From ef7ed47ac3ca6cbd201b1b1f35d588ffdaed636c Mon Sep 17 00:00:00 2001 From: devsaurus Date: Sat, 21 Mar 2015 22:58:58 +0100 Subject: [PATCH 01/22] document XBM conversion --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 90ec76e3..299841c6 100644 --- a/README.md +++ b/README.md @@ -402,7 +402,8 @@ u8glib comes with a wide range of fonts for small displays. Since they need to b They'll be available as `u8g.` in Lua. #####Bitmaps -Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See `lua_examples/u8glib/u8g_bitmaps.lua`. Binary files can be uploaded with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader). +Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See `lua_examples/u8glib/u8g_bitmaps.lua`. +In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader). #####Unimplemented functions - [ ] Cursor handling From 1c267dfac7c5fc406929df63799280646095e93c Mon Sep 17 00:00:00 2001 From: AllAboutEE Date: Mon, 23 Mar 2015 21:57:54 -0500 Subject: [PATCH 02/22] Added phone calls and sms example. --- lua_examples/make_phone_call.lua | 98 ++++++++++++++++++++++++++++++ lua_examples/send_text_message.lua | 98 ++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 lua_examples/make_phone_call.lua create mode 100644 lua_examples/send_text_message.lua diff --git a/lua_examples/make_phone_call.lua b/lua_examples/make_phone_call.lua new file mode 100644 index 00000000..16295fdf --- /dev/null +++ b/lua_examples/make_phone_call.lua @@ -0,0 +1,98 @@ +--[[ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]]-- + +-- Your access point's SSID and password +local SSID = "xxxxxx" +local SSID_PASSWORD = "xxxxxx" + +-- configure ESP as a station +wifi.setmode(wifi.STATION) +wifi.sta.config(SSID,SSID_PASSWORD) +wifi.sta.autoconnect(1) + +local TWILIO_ACCOUNT_SID = "xxxxxx" +local TWILIO_TOKEN = "xxxxxx" + +local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service + -- Please be sure to understand the security issues of using this relay app and use at your own risk. +local URI = "/twilio/Calls.json" + +function build_post_request(host, uri, data_table) + + local data = "" + + for param,value in pairs(data_table) do + data = data .. param.."="..value.."&" + end + + request = "POST "..uri.." HTTP/1.1\r\n".. + "Host: "..host.."\r\n".. + "Connection: close\r\n".. + "Content-Type: application/x-www-form-urlencoded\r\n".. + "Content-Length: "..string.len(data).."\r\n".. + "\r\n".. + data + + print(request) + + return request +end + +local function display(sck,response) + print(response) +end + +-- When using send_sms: the "from" number HAS to be your twilio number. +-- If you have a free twilio account the "to" number HAS to be your twilio verified number. +local function make_call(from,to,body) + + local data = { + sid = TWILIO_ACCOUNT_SID, + token = TWILIO_TOKEN, + Body = string.gsub(body," ","+"), + From = from, + To = to + } + + socket = net.createConnection(net.TCP,0) + socket:on("receive",display) + socket:connect(80,HOST) + + socket:on("connection",function(sck) + + local post_request = build_post_request(HOST,URI,data) + sck:send(post_request) + end) +end + +function check_wifi() + local ip = wifi.sta.getip() + + if(ip==nil) then + print("Connecting...") + else + tmr.stop(0) + print("Connected to AP!") + print(ip) + -- make a call with a voice message "your house is on fire" + make_call("15558976687","1334856679","Your house is on fire!") + end + +end + +tmr.alarm(0,2000,1,check_wifi) diff --git a/lua_examples/send_text_message.lua b/lua_examples/send_text_message.lua new file mode 100644 index 00000000..abd1908f --- /dev/null +++ b/lua_examples/send_text_message.lua @@ -0,0 +1,98 @@ +--[[ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]]-- + +-- Your access point's SSID and password +local SSID = "xxxxxx" +local SSID_PASSWORD = "xxxxxx" + +-- configure ESP as a station +wifi.setmode(wifi.STATION) +wifi.sta.config(SSID,SSID_PASSWORD) +wifi.sta.autoconnect(1) + +local TWILIO_ACCOUNT_SID = "xxxxxx" +local TWILIO_TOKEN = "xxxxxx" + +local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service + -- Please be sure to understand the security issues of using this relay app and use at your own risk. +local URI = "/twilio/Messages.json" + +function build_post_request(host, uri, data_table) + + local data = "" + + for param,value in pairs(data_table) do + data = data .. param.."="..value.."&" + end + + request = "POST "..uri.." HTTP/1.1\r\n".. + "Host: "..host.."\r\n".. + "Connection: close\r\n".. + "Content-Type: application/x-www-form-urlencoded\r\n".. + "Content-Length: "..string.len(data).."\r\n".. + "\r\n".. + data + + print(request) + + return request +end + +local function display(sck,response) + print(response) +end + +-- When using send_sms: the "from" number HAS to be your twilio number. +-- If you have a free twilio account the "to" number HAS to be your twilio verified number. +local function send_sms(from,to,body) + + local data = { + sid = TWILIO_ACCOUNT_SID, + token = TWILIO_TOKEN, + Body = string.gsub(body," ","+"), + From = from, + To = to + } + + socket = net.createConnection(net.TCP,0) + socket:on("receive",display) + socket:connect(80,HOST) + + socket:on("connection",function(sck) + + local post_request = build_post_request(HOST,URI,data) + sck:send(post_request) + end) +end + +function check_wifi() + local ip = wifi.sta.getip() + + if(ip==nil) then + print("Connecting...") + else + tmr.stop(0) + print("Connected to AP!") + print(ip) + -- send a text message with the text "Hello from your esp8266" + send_sms("15558889944","15559998845","Hello from your ESP8266") + end + +end + +tmr.alarm(0,7000,1,check_wifi) From 855864119074eaf2804ace5ce63faa61b3bc9a63 Mon Sep 17 00:00:00 2001 From: funshine Date: Fri, 3 Apr 2015 16:05:14 +0800 Subject: [PATCH 03/22] add gpio.serout() api to help serialize bit out --- app/modules/gpio.c | 77 +++++++++++++++++++++++++++++++++++++++++++ examples/fragment.lua | 12 +++++++ 2 files changed, 89 insertions(+) diff --git a/app/modules/gpio.c b/app/modules/gpio.c index 551dca8a..79e4e850 100644 --- a/app/modules/gpio.c +++ b/app/modules/gpio.c @@ -146,6 +146,82 @@ static int lgpio_write( lua_State* L ) return 0; } +#define DELAY_TABLE_MAX_LEN 256 +#define noInterrupts os_intr_lock +#define interrupts os_intr_unlock +#define delayMicroseconds os_delay_us +#define DIRECT_WRITE(pin, level) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), level)) +// Lua: serout( pin, firstLevel, delay_table, [repeatNum] ) +// -- serout( pin, firstLevel, delay_table, [repeatNum] ) +// gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) +// gpio.serout(1,1,{30,30,60,60,30,30}) -- serial one byte, b10110010 +// gpio.serout(1,1,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles +// gpio.serout(1,1,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles +// gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles +// gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) +// gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps +// gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles +static int lgpio_serout( lua_State* L ) +{ + unsigned level; + unsigned pin; + unsigned table_len = 0; + unsigned repeat = 0; + int delay_table[DELAY_TABLE_MAX_LEN]; + + pin = luaL_checkinteger( L, 1 ); + MOD_CHECK_ID( gpio, pin ); + level = luaL_checkinteger( L, 2 ); + if ( level!=HIGH && level!=LOW ) + return luaL_error( L, "wrong arg type" ); + if( lua_istable( L, 3 ) ) + { + table_len = lua_objlen( L, 3 ); + if (table_len <= 0 || table_len>DELAY_TABLE_MAX_LEN) + return luaL_error( L, "wrong arg range" ); + int i; + for( i = 0; i < table_len; i ++ ) + { + lua_rawgeti( L, 3, i + 1 ); + delay_table[i] = ( int )luaL_checkinteger( L, -1 ); + lua_pop( L, 1 ); + if( delay_table[i] < 0 || delay_table[i] > 1000000 ) // can not delay more than 1000000 us + return luaL_error( L, "delay must < 1000000 us" ); + } + } else { + return luaL_error( L, "wrong arg range" ); + } + + if(lua_isnumber(L, 4)) + repeat = lua_tointeger( L, 4 ); + if( repeat < 0 || repeat > DELAY_TABLE_MAX_LEN ) + return luaL_error( L, "delay must < 256" ); + + if(repeat==0) + repeat = 1; + int j; + bool skip_loop = true; + do + { + if(skip_loop){ // skip the first loop. + skip_loop = false; + continue; + } + for(j=0;j0); + + return 0; +} +#undef DELAY_TABLE_MAX_LEN + // Module function map #define MIN_OPT_LEVEL 2 #include "lrodefs.h" @@ -154,6 +230,7 @@ const LUA_REG_TYPE gpio_map[] = { LSTRKEY( "mode" ), LFUNCVAL( lgpio_mode ) }, { LSTRKEY( "read" ), LFUNCVAL( lgpio_read ) }, { LSTRKEY( "write" ), LFUNCVAL( lgpio_write ) }, + { LSTRKEY( "serout" ), LFUNCVAL( lgpio_serout ) }, #ifdef GPIO_INTERRUPT_ENABLE { LSTRKEY( "trig" ), LFUNCVAL( lgpio_trig ) }, #endif diff --git a/examples/fragment.lua b/examples/fragment.lua index 9206be8c..157d8c41 100644 --- a/examples/fragment.lua +++ b/examples/fragment.lua @@ -472,3 +472,15 @@ m:on("offline", function(conn) print(node.heap()) end) m:connect("192.168.18.88",1883,0,1) + +-- serout( pin, firstLevel, delay_table, [repeatNum] ) +gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) +gpio.serout(1,1,{30,30,60,60,30,30}) -- serial one byte, b10110010 +gpio.serout(1,1,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles +gpio.serout(1,1,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles +gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles + +gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) +gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps + +gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles From 4ca371f473f5780fb6c3280b51b9190e19e4b18d Mon Sep 17 00:00:00 2001 From: Martin Han Date: Fri, 3 Apr 2015 23:34:12 +0800 Subject: [PATCH 04/22] Add support to DHT11 and add some comments. Change function names. read->-read11() support DHT11 ->read22() support DHT21 DHT22 --- lua_modules/dht22/{dht22.lua => dht_lib.lua} | 77 +++++++++++++++++--- 1 file changed, 66 insertions(+), 11 deletions(-) rename lua_modules/dht22/{dht22.lua => dht_lib.lua} (54%) diff --git a/lua_modules/dht22/dht22.lua b/lua_modules/dht22/dht_lib.lua similarity index 54% rename from lua_modules/dht22/dht22.lua rename to lua_modules/dht22/dht_lib.lua index a80a1bd6..641f2e17 100644 --- a/lua_modules/dht22/dht22.lua +++ b/lua_modules/dht22/dht_lib.lua @@ -1,34 +1,43 @@ -- *************************************************************************** --- DHT22 module for ESP8266 with nodeMCU +-- DHTxx(11,21,22) module for ESP8266 with nodeMCU -- --- Written by Javier Yanez +-- Written by Javier Yanez mod by Martin -- but based on a script of Pigs Fly from ESP8266.com forum -- -- MIT license, http://opensource.org/licenses/MIT -- *************************************************************************** +--Support list: +--DHT11 Tested ->read11 +--DHT21 Not Tested->read22 +--DHT22 Tested->read22 + +--==========================Module Part====================== local moduleName = ... local M = {} _G[moduleName] = M - +--==========================Local the UMI and TEMP=========== local humidity local temperature +--==========================Local the bitStream============== +local bitStream = {} -function M.read(pin) - local checksum - local checksumTest +---------------------------Read bitStream from DHTXX-------------------------- +local function read(pin) + + local bitlength = 0 humidity = 0 temperature = 0 - checksum = 0 -- Use Markus Gritsch trick to speed up read/write on GPIO local gpio_read = gpio.read - local bitStream = {} + for j = 1, 40, 1 do bitStream[j] = 0 end - local bitlength = 0 + + -- Step 1: send out start signal to DHT22 gpio.mode(pin, gpio.OUTPUT) @@ -39,7 +48,7 @@ function M.read(pin) gpio.write(pin, gpio.HIGH) gpio.mode(pin, gpio.INPUT) - -- Step 2: DHT22 send response signal + -- Step 2: Receive bitStream from DHT11/22 -- bus will always let up eventually, don't bother with timeout while (gpio_read(pin) == 0 ) do end local c=0 @@ -59,8 +68,53 @@ function M.read(pin) -- bus will always let up eventually, don't bother with timeout while (gpio_read(pin) == 0) do end end - +end +---------------------------Convert the bitStream into Number through DHT11 Ways-------------------------- +function M.read11(pin) +--As for DHT11 40Bit is consisit of 5Bytes +--First byte->Humidity Data's Int part +--Sencond byte->Humidity Data's Float Part(Which should be empty) +--Third byte->Temp Data;s Intpart +--Forth byte->Temp Data's Float Part(Which should be empty) +--Fifth byte->SUM Byte, Humi+Temp + read(pin) + local checksum = 0 + local checksumTest --DHT data acquired, process. + for i = 1, 8, 1 do -- Byte[0] + if (bitStream[i] > 3) then + humidity = humidity + 2 ^ (8 - i) + end + end + for i = 1, 8, 1 do -- Byte[2] + if (bitStream[i + 16] > 3) then + temperature = temperature + 2 ^ (8 - i) + end + end + for i = 1, 8, 1 do --Byte[4] + if (bitStream[i + 32] > 3) then + checksum = checksum + 2 ^ (8 - i) + end + end + + if(checksum ~= humidity+temperature) then + humidity = nil + temperature = nil + end + +end +---------------------------Convert the bitStream into Number through DHT22 Ways-------------------------- +function M.read22( pin ) +--As for DHT22 40Bit is consisit of 5Bytes +--First byte->Humidity Data's High Bit +--Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement) +--Third byte->Temp Data's High Bit +--Forth byte->Temp Data's Low Bit +--Fifth byte->SUM Byte + read(pin) + local checksum = 0 + local checksumTest + --DHT data acquired, process. for i = 1, 16, 1 do if (bitStream[i] > 3) then humidity = humidity + 2 ^ (16 - i) @@ -91,6 +145,7 @@ function M.read(pin) end end +---------------------------Check out the data-------------------------- function M.getTemperature() return temperature end From 1bc81f4c3e30b5bcb77fb06d69f512d1e4286261 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Fri, 3 Apr 2015 23:44:26 +0800 Subject: [PATCH 05/22] Add support to DHT11 and add some comments. --- lua_modules/dht22/README.md | 77 ++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/lua_modules/dht22/README.md b/lua_modules/dht22/README.md index b68a3278..ab7b30f9 100644 --- a/lua_modules/dht22/README.md +++ b/lua_modules/dht22/README.md @@ -1,46 +1,78 @@ -# DHT22 module +# DHTxx module -This module is compatible with DHT22 and DHT21. -Supports nodemcu with or without floating point. +This module is compatible with DHT11, DHT21 and DHT22. No need to use a resistor to connect the pin data of DHT22 to ESP8266. -## Example +##Integer Verison[When using DHT11, Float version is useless...] +### Example ```lua PIN = 4 -- data pin, GPIO2 -dht22 = require("dht22") -dht22.read(PIN) -t = dht22.getTemperature() -h = dht22.getHumidity() +DHT= require("dht_lib") + +--dht.read11(PIN) +DHT.read22(PIN) + +t = DHT.getTemperature() +h = DHT.getHumidity() if h == nil then - print("Error reading from DHT22") + print("Error reading from DHT11/22") else -- temperature in degrees Celsius and Farenheit - -- floating point and integer version: + print("Temperature: "..((t-(t % 10)) / 10).."."..(t % 10).." deg C") - -- only integer version: + print("Temperature: "..(9 * t / 50 + 32).."."..(9 * t / 5 % 10).." deg F") - -- only float point version: - print("Temperature: "..(9 * t / 50 + 32).." deg F") -- humidity - -- floating point and integer version + print("Humidity: "..((h - (h % 10)) / 10).."."..(h % 10).."%") end -- release module -dht22 = nil -package.loaded["dht22"]=nil +DHT = nil +package.loaded["dht_lib"]=nil +``` +##Float Verison +###Example +```lua +PIN = 4 -- data pin, GPIO2 + +DHT= require("dht_lib") + +--dht.read11(PIN) +DHT.read22(PIN) + +t = DHT.getTemperature() +h = DHT.getHumidity() + +if h == nil then + print("Error reading from DHT11/22") +else + -- temperature in degrees Celsius and Farenheit + -- floating point and integer version: + print("Temperature: "..t.." deg C") + print("Temperature: "..(9 * t / 50 + 32).." deg F") + + -- humidity + print("Humidity: "..h.."%") +end + +-- release module +DHT = nil +package.loaded["dht_lib"]=nil ``` ## Functions -### read -read(pin) -Read humidity and temperature from DHT22. - +### read11 +read11(pin) +Read humidity and temperature from DHT11. +###read22 +read22(pin) +Read humidity and temperature from DHT22/21. **Parameters:** -* pin - ESP8266 pin connect to data pin in DHT22 +* pin - ESP8266 pin connect to data pin ### getHumidity getHumidity() @@ -54,5 +86,6 @@ getTemperature() Returns the temperature of the last reading. **Returns:** -* last temperature reading in 0.1ºC +* last temperature reading in(dht22) 0.1ºC (dht11)1ºC +* From bcbde08bf70b703e32aa43bdc6a76102a50944d1 Mon Sep 17 00:00:00 2001 From: funshine Date: Sun, 5 Apr 2015 02:22:51 +0800 Subject: [PATCH 06/22] fix mqtt keepalive ping, add a example for mqtt in lua_examples. --- app/include/user_version.h | 2 +- app/modules/mqtt.c | 62 ++++++++++++++++++-------------------- examples/fragment.lua | 31 +++++++++++++++++++ lua_examples/mqtt_test.lua | 30 ++++++++++++++++++ 4 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 lua_examples/mqtt_test.lua diff --git a/app/include/user_version.h b/app/include/user_version.h index 06bce33b..e9357259 100644 --- a/app/include/user_version.h +++ b/app/include/user_version.h @@ -7,6 +7,6 @@ #define NODE_VERSION_INTERNAL 0U #define NODE_VERSION "NodeMCU 0.9.5" -#define BUILD_DATE "build 20150403" +#define BUILD_DATE "build 20150405" #endif /* __USER_VERSION_H__ */ diff --git a/app/modules/mqtt.c b/app/modules/mqtt.c index ce303af2..c7afd0ff 100644 --- a/app/modules/mqtt.c +++ b/app/modules/mqtt.c @@ -47,8 +47,6 @@ typedef struct mqtt_state_t uint16_t port; int auto_reconnect; mqtt_connect_info_t* connect_info; - uint8_t* in_buffer; - int in_buffer_length; uint16_t message_length; uint16_t message_length_read; mqtt_connection_t mqtt_connection; @@ -166,7 +164,6 @@ static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length) NODE_DBG("enter deliver_publish.\n"); if(mud == NULL) return; - const char comma[] = ","; mqtt_event_data_t event_data; event_data.topic_length = length; @@ -181,11 +178,15 @@ static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length) return; if(mud->L == NULL) return; - lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_message_ref); - lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua - - lua_pushlstring(mud->L, event_data.topic, event_data.topic_length); - if(event_data.data_length > 0){ + if(event_data.topic && (event_data.topic_length > 0)){ + lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_message_ref); + lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua + lua_pushlstring(mud->L, event_data.topic, event_data.topic_length); + } else { + NODE_DBG("get wrong packet.\n"); + return; + } + if(event_data.data && (event_data.data_length > 0)){ lua_pushlstring(mud->L, event_data.data, event_data.data_length); lua_call(mud->L, 3, 0); } else { @@ -202,6 +203,9 @@ static void mqtt_socket_received(void *arg, char *pdata, unsigned short len) uint8_t msg_qos; uint16_t msg_id; msg_queue_t *node = NULL; + int length = (int)len; + // uint8_t in_buffer[MQTT_BUF_SIZE]; + uint8_t *in_buffer = (uint8_t *)pdata; struct espconn *pesp_conn = arg; if(pesp_conn == NULL) @@ -211,17 +215,17 @@ static void mqtt_socket_received(void *arg, char *pdata, unsigned short len) return; READPACKET: - if(len > MQTT_BUF_SIZE && len <= 0) + if(length > MQTT_BUF_SIZE || length <= 0) return; - c_memcpy(mud->mqtt_state.in_buffer, pdata, len); + // c_memcpy(in_buffer, pdata, length); uint8_t temp_buffer[MQTT_BUF_SIZE]; mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); mqtt_message_t *temp_msg = NULL; switch(mud->connState){ case MQTT_CONNECT_SENDING: case MQTT_CONNECT_SENT: - if(mqtt_get_type(mud->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK){ + if(mqtt_get_type(in_buffer) != MQTT_MSG_TYPE_CONNACK){ NODE_DBG("MQTT: Invalid packet\r\n"); mud->connState = MQTT_INIT; if(mud->secure) @@ -245,11 +249,11 @@ READPACKET: break; case MQTT_DATA: - mud->mqtt_state.message_length_read = len; - mud->mqtt_state.message_length = mqtt_get_total_length(mud->mqtt_state.in_buffer, mud->mqtt_state.message_length_read); - msg_type = mqtt_get_type(mud->mqtt_state.in_buffer); - msg_qos = mqtt_get_qos(mud->mqtt_state.in_buffer); - msg_id = mqtt_get_id(mud->mqtt_state.in_buffer, mud->mqtt_state.in_buffer_length); + mud->mqtt_state.message_length_read = length; + mud->mqtt_state.message_length = mqtt_get_total_length(in_buffer, mud->mqtt_state.message_length_read); + msg_type = mqtt_get_type(in_buffer); + msg_qos = mqtt_get_qos(in_buffer); + msg_id = mqtt_get_id(in_buffer, mud->mqtt_state.message_length); msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q)); @@ -295,7 +299,7 @@ READPACKET: if(msg_qos == 1 || msg_qos == 2){ NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos); } - deliver_publish(mud, mud->mqtt_state.in_buffer, mud->mqtt_state.message_length_read); + deliver_publish(mud, in_buffer, mud->mqtt_state.message_length); break; case MQTT_MSG_TYPE_PUBACK: if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){ @@ -365,11 +369,11 @@ READPACKET: if(msg_type == MQTT_MSG_TYPE_PUBLISH) { - len = mud->mqtt_state.message_length_read; + length = mud->mqtt_state.message_length_read; if(mud->mqtt_state.message_length < mud->mqtt_state.message_length_read) { - len -= mud->mqtt_state.message_length; + length -= mud->mqtt_state.message_length; pdata += mud->mqtt_state.message_length; NODE_DBG("Get another published message\r\n"); @@ -386,8 +390,8 @@ READPACKET: espconn_secure_sent( pesp_conn, node->msg.data, node->msg.length ); else espconn_sent( pesp_conn, node->msg.data, node->msg.length ); - mud->keep_alive_tick = 0; } + mud->keep_alive_tick = 0; NODE_DBG("receive, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_received.\n"); return; @@ -406,6 +410,7 @@ static void mqtt_socket_sent(void *arg) return; // call mqtt_sent() mud->event_timeout = 0; + mud->keep_alive_tick = 0; if(mud->connState == MQTT_CONNECT_SENDING){ mud->connState = MQTT_CONNECT_SENT; @@ -430,7 +435,7 @@ static void mqtt_socket_sent(void *arg) msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); } else if(node && node->msg_type == MQTT_MSG_TYPE_PUBCOMP) { msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); - } else if(node && node->msg_type == MQTT_MSG_TYPE_PINGRESP) { + } else if(node && node->msg_type == MQTT_MSG_TYPE_PINGREQ) { msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q))); } NODE_DBG("sent2, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); @@ -462,6 +467,7 @@ static void mqtt_socket_connected(void *arg) espconn_secure_sent(pesp_conn, temp_msg->data, temp_msg->length); else espconn_sent(pesp_conn, temp_msg->data, temp_msg->length); + mud->keep_alive_tick = 0; mud->connState = MQTT_CONNECT_SENDING; NODE_DBG("leave mqtt_socket_connected.\n"); @@ -625,8 +631,7 @@ static int mqtt_socket_client( lua_State* L ) mud->connect_info.client_id = (uint8_t *)c_zalloc(idl+1); mud->connect_info.username = (uint8_t *)c_zalloc(unl + 1); mud->connect_info.password = (uint8_t *)c_zalloc(pwl + 1); - mud->mqtt_state.in_buffer = (uint8_t *)c_zalloc(MQTT_BUF_SIZE); - if(!mud->connect_info.client_id || !mud->connect_info.username || !mud->connect_info.password || !mud->mqtt_state.in_buffer){ + if(!mud->connect_info.client_id || !mud->connect_info.username || !mud->connect_info.password){ if(mud->connect_info.client_id) { c_free(mud->connect_info.client_id); mud->connect_info.client_id = NULL; @@ -638,10 +643,6 @@ static int mqtt_socket_client( lua_State* L ) if(mud->connect_info.password) { c_free(mud->connect_info.password); mud->connect_info.password = NULL; - } - if(mud->mqtt_state.in_buffer) { - c_free(mud->mqtt_state.in_buffer); - mud->mqtt_state.in_buffer = NULL; } return luaL_error(L, "not enough memory"); } @@ -660,9 +661,8 @@ static int mqtt_socket_client( lua_State* L ) mud->connect_info.will_retain = 0; mud->connect_info.keepalive = keepalive; - mud->mqtt_state.in_buffer_length = MQTT_BUF_SIZE; mud->mqtt_state.pending_msg_q = NULL; - mud->mqtt_state.auto_reconnect = 1; + mud->mqtt_state.auto_reconnect = 0; mud->mqtt_state.port = 1883; mud->mqtt_state.connect_info = &mud->connect_info; @@ -722,10 +722,6 @@ static int mqtt_delete( lua_State* L ) c_free(mud->connect_info.password); mud->connect_info.password = NULL; } - if(mud->mqtt_state.in_buffer){ - c_free(mud->mqtt_state.in_buffer); - mud->mqtt_state.in_buffer = NULL; - } // ------- // free (unref) callback ref diff --git a/examples/fragment.lua b/examples/fragment.lua index 157d8c41..3f4ee2d0 100644 --- a/examples/fragment.lua +++ b/examples/fragment.lua @@ -484,3 +484,34 @@ gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles + +-- Lua: mqtt.Client(clientid, keepalive, user, pass) +-- test with cloudmqtt.com +m_dis={} +function dispatch(m,t,pl) + if pl~=nil and m_dis[t] then + m_dis[t](pl) + end +end +function topic1func(pl) + print("get1: "..pl) +end +function topic2func(pl) + print("get2: "..pl) +end +m_dis["/topic1"]=topic1func +m_dis["/topic2"]=topic2func +m=mqtt.Client("nodemcu1",60,"test","test123") +m:on("connect",function(m) + print("connection "..node.heap()) + m:subscribe("/topic1",0,function(m) print("sub done") end) + m:subscribe("/topic2",0,function(m) print("sub done") end) + m:publish("/topic1","hello",0,0) m:publish("/topic2","world",0,0) + end ) +m:on("offline", function(conn) + print("disconnect to broker...") + print(node.heap()) +end) +m:on("message",dispatch ) +m:connect("m11.cloudmqtt.com",11214,0,1) +-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) diff --git a/lua_examples/mqtt_test.lua b/lua_examples/mqtt_test.lua new file mode 100644 index 00000000..d27c6a93 --- /dev/null +++ b/lua_examples/mqtt_test.lua @@ -0,0 +1,30 @@ +-- Lua: mqtt.Client(clientid, keepalive, user, pass) +-- test with cloudmqtt.com +m_dis={} +function dispatch(m,t,pl) + if pl~=nil and m_dis[t] then + m_dis[t](pl) + end +end +function topic1func(pl) + print("get1: "..pl) +end +function topic2func(pl) + print("get2: "..pl) +end +m_dis["/topic1"]=topic1func +m_dis["/topic2"]=topic2func +m=mqtt.Client("nodemcu1",60,"test","test123") +m:on("connect",function(m) + print("connection "..node.heap()) + m:subscribe("/topic1",0,function(m) print("sub done") end) + m:subscribe("/topic2",0,function(m) print("sub done") end) + m:publish("/topic1","hello",0,0) m:publish("/topic2","world",0,0) + end ) +m:on("offline", function(conn) + print("disconnect to broker...") + print(node.heap()) +end) +m:on("message",dispatch ) +m:connect("m11.cloudmqtt.com",11214,0,1) +-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) From f13c5c61e6113473949bfbc8dab9a4e3353b921a Mon Sep 17 00:00:00 2001 From: Wayne Bartnick Date: Sun, 5 Apr 2015 09:21:16 -0400 Subject: [PATCH 07/22] wifi.sta.config (wifi_station_config): - range checking password length (8~64) wifi.ap.config (wifi_ap_config): - range checking ssid length (1~32) - range checking pwd length (8~64) - new params: - auth: wifi.OPEN, wifi.WPA_PSK, wifi.WPA2_PSK, wifi.WPA_WPA2_PSK - default WITH pwd: wifi.WPA_WPA2_PSK - default WITHOUT pwd: wifi.OPEN - channel: 1~13 (default: 6) - hidden: 0/1 (default: 0) - max: 1~4 (default: 4) - beacon: 100~60000ms (default: 100) wifi.ap.getclient (wifi_ap_listclient): - returns table(mac,ip) of all connected clients wifi.ap.dhcp: - new submodule - config (wifi_ap_dhcp_config), returns start/end ips - params: - start (e.g., "192.168.1.100") - end ip calculated from wifi.ap.config.max - start (wifi_ap_dhcp_start), returns boolean - stop (wifi_ap_dhcp_stop), returns boolean --- app/modules/wifi.c | 216 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 201 insertions(+), 15 deletions(-) diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 635625c6..d2b2d2e5 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -8,6 +8,7 @@ #include "lrotable.h" #include "c_string.h" +#include "c_stdlib.h" #include "c_types.h" #include "user_interface.h" @@ -327,8 +328,8 @@ static int wifi_station_config( lua_State* L ) if (sl>32 || ssid == NULL) return luaL_error( L, "ssid:<32" ); const char *password = luaL_checklstring( L, 2, &pl ); - if (pl>64 || password == NULL) - return luaL_error( L, "pwd:<64" ); + if (pl<8 || pl>64 || password == NULL) + return luaL_error( L, "pwd:8~64" ); c_memset(sta_conf.ssid, 0, 32); c_memset(sta_conf.password, 0, 64); @@ -380,6 +381,7 @@ static int wifi_station_setauto( lua_State* L ) return 0; } +// Lua: table = wifi.sta.getap() static int wifi_station_listap( lua_State* L ) { if(wifi_get_opmode() == SOFTAP_MODE) @@ -437,44 +439,46 @@ static int wifi_ap_getbroadcast( lua_State* L ){ // Lua: wifi.ap.config(table) static int wifi_ap_config( lua_State* L ) { - struct softap_config config; - size_t len; - wifi_softap_get_config(&config); if (!lua_istable(L, 1)) return luaL_error( L, "wrong arg type" ); + struct softap_config config; + wifi_softap_get_config(&config); + + size_t len; + lua_getfield(L, 1, "ssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *ssid = luaL_checklstring( L, -1, &len ); - if(len>32) - return luaL_error( L, "ssid:<32" ); + if(len<1 || len>32 || ssid == NULL) + return luaL_error( L, "ssid:1~32" ); c_memset(config.ssid, 0, 32); c_memcpy(config.ssid, ssid, len); - config.ssid_len = len; - config.ssid_hidden = 0; NODE_DBG(config.ssid); NODE_DBG("\n"); + config.ssid_len = len; + config.ssid_hidden = 0; } else return luaL_error( L, "wrong arg type" ); } else - return luaL_error( L, "wrong arg type" ); + return luaL_error( L, "ssid required" ); lua_getfield(L, 1, "pwd"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the password string { const char *pwd = luaL_checklstring( L, -1, &len ); - if(len>64) - return luaL_error( L, "pwd:<64" ); + if(len<8 || len>64 || pwd == NULL) + return luaL_error( L, "pwd:8~64" ); c_memset(config.password, 0, 64); c_memcpy(config.password, pwd, len); - config.authmode = AUTH_WPA_WPA2_PSK; NODE_DBG(config.password); NODE_DBG("\n"); + config.authmode = AUTH_WPA_WPA2_PSK; } else return luaL_error( L, "wrong arg type" ); @@ -483,11 +487,162 @@ static int wifi_ap_config( lua_State* L ) config.authmode = AUTH_OPEN; } - config.max_connection = 4; + lua_getfield(L, 1, "auth"); + if (!lua_isnil(L, -1)) + { + config.authmode = (uint8_t)luaL_checkinteger(L, -1); + NODE_DBG(config.authmode); + NODE_DBG("\n"); + } + else + { + // keep whatever value resulted from "pwd" logic above + } + + lua_getfield(L, 1, "channel"); + if (!lua_isnil(L, -1)) + { + unsigned channel = luaL_checkinteger(L, -1); + if (channel < 1 || channel > 13) + return luaL_error( L, "channel:1~13" ); + + config.channel = (uint8_t)channel; + NODE_DBG(config.channel); + NODE_DBG("\n"); + } + else + { + config.channel = 6; + } + + lua_getfield(L, 1, "hidden"); + if (!lua_isnil(L, -1)) + { + config.ssid_hidden = (uint8_t)luaL_checkinteger(L, -1); + NODE_DBG(config.ssid_hidden); + NODE_DBG("\n"); + } + else + { + config.ssid_hidden = 0; + } + + lua_getfield(L, 1, "max"); + if (!lua_isnil(L, -1)) + { + unsigned max = luaL_checkinteger(L, -1); + if (max < 1 || max > 4) + return luaL_error( L, "max:1~4" ); + + config.max_connection = (uint8_t)max; + NODE_DBG(config.max_connection); + NODE_DBG("\n"); + } + else + { + config.max_connection = 4; + } + + lua_getfield(L, 1, "beacon"); + if (!lua_isnil(L, -1)) + { + unsigned beacon = luaL_checkinteger(L, -1); + if (beacon < 100 || beacon > 60000) + return luaL_error( L, "beacon:100~60000" ); + + config.beacon_interval = (uint16_t)beacon; + NODE_DBG(config.beacon_interval); + NODE_DBG("\n"); + } + else + { + config.beacon_interval = 100; + } wifi_softap_set_config(&config); // system_restart(); - return 0; + return 0; +} + +// Lua: table = wifi.ap.getclient() +static int wifi_ap_listclient( lua_State* L ) +{ + if (wifi_get_opmode() == STATION_MODE) + { + return luaL_error( L, "Can't list client in STATION_MODE mode" ); + } + + char temp[64]; + + lua_newtable(L); + + struct station_info * station = wifi_softap_get_station_info(); + struct station_info * next_station; + while (station != NULL) + { + c_sprintf(temp, IPSTR, IP2STR(&station->ip)); + lua_pushstring(L, temp); + + c_sprintf(temp, MACSTR, MAC2STR(station->bssid)); + lua_setfield(L, -2, temp); + + next_station = STAILQ_NEXT(station, next); + c_free(station); + station = next_station; + } + + return 1; +} + +// Lua: ip = wifi.ap.dhcp.config() +static int wifi_ap_dhcp_config( lua_State* L ) +{ + if (!lua_istable(L, 1)) + return luaL_error( L, "wrong arg type" ); + + struct dhcps_lease lease; + uint32_t ip; + + ip = parse_key(L, "start"); + if (ip == 0) + return luaL_error( L, "wrong arg type" ); + + lease.start_ip = ip; + NODE_DBG(IPSTR, IP2STR(&lease.start_ip)); + NODE_DBG("\n"); + + // use configured max_connection to determine end + struct softap_config config; + wifi_softap_get_config(&config); + lease.end_ip = lease.start_ip; + ip4_addr4(&lease.end_ip) += config.max_connection - 1; + + char temp[64]; + c_sprintf(temp, IPSTR, IP2STR(&lease.start_ip)); + lua_pushstring(L, temp); + c_sprintf(temp, IPSTR, IP2STR(&lease.end_ip)); + lua_pushstring(L, temp); + + // note: DHCP max range = 101 from start_ip to end_ip + wifi_softap_dhcps_stop(); + wifi_softap_set_dhcps_lease(&lease); + wifi_softap_dhcps_start(); + + return 2; +} + +// Lua: wifi.ap.dhcp.start() +static int wifi_ap_dhcp_start( lua_State* L ) +{ + lua_pushboolean(L, wifi_softap_dhcps_start()); + return 1; +} + +// Lua: wifi.ap.dhcp.stop() +static int wifi_ap_dhcp_stop( lua_State* L ) +{ + lua_pushboolean(L, wifi_softap_dhcps_stop()); + return 1; } // Module function map @@ -509,6 +664,14 @@ static const LUA_REG_TYPE wifi_station_map[] = { LNILKEY, LNILVAL } }; +static const LUA_REG_TYPE wifi_ap_dhcp_map[] = +{ + { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_dhcp_config ) }, + { LSTRKEY( "start" ), LFUNCVAL( wifi_ap_dhcp_start ) }, + { LSTRKEY( "stop" ), LFUNCVAL( wifi_ap_dhcp_stop ) }, + { LNILKEY, LNILVAL } +}; + static const LUA_REG_TYPE wifi_ap_map[] = { { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) }, @@ -517,6 +680,12 @@ static const LUA_REG_TYPE wifi_ap_map[] = { LSTRKEY( "getbroadcast" ), LFUNCVAL ( wifi_ap_getbroadcast) }, { LSTRKEY( "getmac" ), LFUNCVAL ( wifi_ap_getmac ) }, { LSTRKEY( "setmac" ), LFUNCVAL ( wifi_ap_setmac ) }, + { LSTRKEY( "getclient" ), LFUNCVAL ( wifi_ap_listclient ) }, +#if LUA_OPTIMIZE_MEMORY > 0 + { LSTRKEY( "dhcp" ), LROVAL( wifi_ap_dhcp_map ) }, + +// { LSTRKEY( "__metatable" ), LROVAL( wifi_ap_map ) }, +#endif { LNILKEY, LNILVAL } }; @@ -540,6 +709,12 @@ const LUA_REG_TYPE wifi_map[] = { LSTRKEY( "LIGHT_SLEEP" ), LNUMVAL( LIGHT_SLEEP_T ) }, { LSTRKEY( "MODEM_SLEEP" ), LNUMVAL( MODEM_SLEEP_T ) }, + { LSTRKEY( "OPEN" ), LNUMVAL( AUTH_OPEN ) }, + // { LSTRKEY( "WEP" ), LNUMVAL( AUTH_WEP ) }, + { LSTRKEY( "WPA_PSK" ), LNUMVAL( AUTH_WPA_PSK ) }, + { LSTRKEY( "WPA2_PSK" ), LNUMVAL( AUTH_WPA2_PSK ) }, + { LSTRKEY( "WPA_WPA2_PSK" ), LNUMVAL( AUTH_WPA_WPA2_PSK ) }, + // { LSTRKEY( "STA_IDLE" ), LNUMVAL( STATION_IDLE ) }, // { LSTRKEY( "STA_CONNECTING" ), LNUMVAL( STATION_CONNECTING ) }, // { LSTRKEY( "STA_WRONGPWD" ), LNUMVAL( STATION_WRONG_PASSWORD ) }, @@ -573,6 +748,12 @@ LUALIB_API int luaopen_wifi( lua_State *L ) MOD_REG_NUMBER( L, "LIGHT_SLEEP", LIGHT_SLEEP_T ); MOD_REG_NUMBER( L, "MODEM_SLEEP", MODEM_SLEEP_T ); + MOD_REG_NUMBER( L, "OPEN", AUTH_OPEN ); + // MOD_REG_NUMBER( L, "WEP", AUTH_WEP ); + MOD_REG_NUMBER( L, "WPA_PSK", AUTH_WPA_PSK ); + MOD_REG_NUMBER( L, "WPA2_PSK", AUTH_WPA2_PSK ); + MOD_REG_NUMBER( L, "WPA_WPA2_PSK", AUTH_WPA_WPA2_PSK ); + // MOD_REG_NUMBER( L, "STA_IDLE", STATION_IDLE ); // MOD_REG_NUMBER( L, "STA_CONNECTING", STATION_CONNECTING ); // MOD_REG_NUMBER( L, "STA_WRONGPWD", STATION_WRONG_PASSWORD ); @@ -589,6 +770,11 @@ LUALIB_API int luaopen_wifi( lua_State *L ) luaL_register( L, NULL, wifi_ap_map ); lua_setfield( L, -2, "ap" ); + // Setup the new table (dhcp) inside ap + lua_newtable( L ); + luaL_register( L, NULL, wifi_ap_dhcp_map ); + lua_setfield( L, -1, "dhcp" ); + return 1; #endif // #if LUA_OPTIMIZE_MEMORY > 0 } From ff85cf43716814a1959cf7299290584393804596 Mon Sep 17 00:00:00 2001 From: Wolfram Ladurner Date: Sun, 5 Apr 2015 14:19:14 +0200 Subject: [PATCH 08/22] fixes issue #321 "ws2812.writergb scrambles buffer" reported by makefu. Don't modify Lua-internal lstring - use a copy instead. --- app/modules/ws2812.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/modules/ws2812.c b/app/modules/ws2812.c index b9419181..b0975201 100644 --- a/app/modules/ws2812.c +++ b/app/modules/ws2812.c @@ -3,6 +3,8 @@ #include "platform.h" #include "auxmods.h" #include "lrotable.h" +#include "c_stdlib.h" +#include "c_string.h" /** * All this code is mostly from http://www.esp8266.com/viewtopic.php?f=21&t=1143&sid=a620a377672cfe9f666d672398415fcb * from user Markus Gritsch. @@ -35,7 +37,10 @@ static int ICACHE_FLASH_ATTR ws2812_writergb(lua_State* L) { const uint8_t pin = luaL_checkinteger(L, 1); size_t length; - char *buffer = (char *)luaL_checklstring(L, 2, &length); // Cast away the constness. + const char *rgb = luaL_checklstring(L, 2, &length); + // dont modify lua-internal lstring - make a copy instead + char *buffer = (char *)c_malloc(length); + c_memcpy(buffer, rgb, length); // Initialize the output pin: platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT); @@ -59,17 +64,17 @@ static int ICACHE_FLASH_ATTR ws2812_writergb(lua_State* L) // Send the buffer: os_intr_lock(); - const char * const end = buffer + length; - while (buffer != end) { + for (i = 0; i < length; i++) { uint8_t mask = 0x80; while (mask) { - (*buffer & mask) ? send_ws_1(pin_num[pin]) : send_ws_0(pin_num[pin]); + (buffer[i] & mask) ? send_ws_1(pin_num[pin]) : send_ws_0(pin_num[pin]); mask >>= 1; } - ++buffer; } os_intr_unlock(); + c_free(buffer); + return 0; } From 06193090e6c51956d4fa439b573b5e4928da3f9b Mon Sep 17 00:00:00 2001 From: cal Date: Sun, 5 Apr 2015 15:52:10 +0200 Subject: [PATCH 09/22] LUAL_BUFFERSIZE back to 1K and warning notice added --- app/lua/luaconf.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/lua/luaconf.h b/app/lua/luaconf.h index 1a1760c7..7e0b182c 100644 --- a/app/lua/luaconf.h +++ b/app/lua/luaconf.h @@ -541,8 +541,12 @@ extern int readline4lua(const char *prompt, char *buffer, int length); /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** Attention: This value should probably not be set higher than 1K. +** The size has direct impact on the C stack size needed be auxlib functions. +** For example: If set to 4K a call to string.gsub will need more than +** 5k C stack space. */ -#define LUAL_BUFFERSIZE ((BUFSIZ)*4) +#define LUAL_BUFFERSIZE BUFSIZ /* }================================================================== */ From b1287756bca71055caf57345ab22e039a7a034d7 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Sun, 5 Apr 2015 23:22:25 +0800 Subject: [PATCH 10/22] Adjust the detail, fix program bug --- lua_modules/dht_lib/README.md | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 lua_modules/dht_lib/README.md diff --git a/lua_modules/dht_lib/README.md b/lua_modules/dht_lib/README.md new file mode 100644 index 00000000..7b36f76c --- /dev/null +++ b/lua_modules/dht_lib/README.md @@ -0,0 +1,89 @@ +# DHTxx module + +This module is compatible with DHT11, DHT21 and DHT22. +And is able to auto-select wheather you are using DHT11 or DHT2x + +No need to use a resistor to connect the pin data of DHT22 to ESP8266. + +##Integer Verison[When using DHT11, Float version is useless...] +### Example +```lua +PIN = 4 -- data pin, GPIO2 + +DHT= require("dht_lib") + +DHT.read(PIN) + +t = DHT.getTemperature() +h = DHT.getHumidity() + +if h == nil then + print("Error reading from DHTxx") +else + -- temperature in degrees Celsius and Farenheit + + print("Temperature: "..((t-(t % 10)) / 10).."."..(t % 10).." deg C") + + print("Temperature: "..(9 * t / 50 + 32).."."..(9 * t / 5 % 10).." deg F") + + -- humidity + + print("Humidity: "..((h - (h % 10)) / 10).."."..(h % 10).."%") +end + +-- release module +DHT = nil +package.loaded["dht_lib"]=nil +``` +##Float Verison +###Example +```lua +PIN = 4 -- data pin, GPIO2 + +DHT= require("dht_lib") + +DHT.read(PIN) + +t = DHT.getTemperature() +h = DHT.getHumidity() + +if h == nil then + print("Error reading from DHT11/22") +else + -- temperature in degrees Celsius and Farenheit + -- floating point and integer version: + + print("Temperature: "..(t/10).." deg C") + print("Temperature: "..(9 * t / 50 + 32).." deg F") + + -- humidity + print("Humidity: "..(h/10).."%") +end + +-- release module +DHT = nil +package.loaded["dht_lib"]=nil +``` +## Functions + +###read +read(pin) +Read humidity and temperature from DHTxx(11,21,22...). +**Parameters:** + +* pin - ESP8266 pin connect to data pin + +### getHumidity +getHumidity() +Returns the humidity of the last reading. + +**Returns:** +* last humidity reading in per thousand + +### getTemperature +getTemperature() +Returns the temperature of the last reading. + +**Returns:** +* last temperature reading in(dht22) 0.1ºC (dht11)1ºC +* From c21dea9d8eca30d444449c9af1b6c6edce042ca1 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Sun, 5 Apr 2015 23:23:18 +0800 Subject: [PATCH 11/22] Fix DHT11 10times BUG, add auto-select feature --- lua_modules/dht_lib/dht_lib.lua | 185 ++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 lua_modules/dht_lib/dht_lib.lua diff --git a/lua_modules/dht_lib/dht_lib.lua b/lua_modules/dht_lib/dht_lib.lua new file mode 100644 index 00000000..e1edf13a --- /dev/null +++ b/lua_modules/dht_lib/dht_lib.lua @@ -0,0 +1,185 @@ +-- *************************************************************************** +-- DHTxx(11,21,22) module for ESP8266 with nodeMCU +-- +-- Written by Javier Yanez mod by Martin +-- but based on a script of Pigs Fly from ESP8266.com forum +-- +-- MIT license, http://opensource.org/licenses/MIT +-- *************************************************************************** + +--Support list: +--DHT11 Tested ->read11 +--DHT21 Not Tested->read22 +--DHT22 Tested->read22 + +--==========================Module Part====================== +local moduleName = ... +local M = {} +_G[moduleName] = M +--==========================Local the UMI and TEMP=========== +local humidity +local temperature +--==========================Local the bitStream============== +local bitStream = {} + +---------------------------Read bitStream from DHTXX-------------------------- +local function read(pin) + + local bitlength = 0 + humidity = 0 + temperature = 0 + + -- Use Markus Gritsch trick to speed up read/write on GPIO + local gpio_read = gpio.read + + + for j = 1, 40, 1 do + bitStream[j] = 0 + end + + + + -- Step 1: send out start signal to DHT22 + gpio.mode(pin, gpio.OUTPUT) + gpio.write(pin, gpio.HIGH) + tmr.delay(100) + gpio.write(pin, gpio.LOW) + tmr.delay(20000) + gpio.write(pin, gpio.HIGH) + gpio.mode(pin, gpio.INPUT) + + -- Step 2: Receive bitStream from DHT11/22 + -- bus will always let up eventually, don't bother with timeout + while (gpio_read(pin) == 0 ) do end + local c=0 + while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end + -- bus will always let up eventually, don't bother with timeout + while (gpio_read(pin) == 0 ) do end + c=0 + while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end + + -- Step 3: DHT22 send data + for j = 1, 40, 1 do + while (gpio_read(pin) == 1 and bitlength < 10 ) do + bitlength = bitlength + 1 + end + bitStream[j] = bitlength + bitlength = 0 + -- bus will always let up eventually, don't bother with timeout + while (gpio_read(pin) == 0) do end + end +end +---------------------------Convert the bitStream into Number through DHT11 Ways-------------------------- +local function bit2DHT11() +--As for DHT11 40Bit is consisit of 5Bytes +--First byte->Humidity Data's Int part +--Sencond byte->Humidity Data's Float Part(Which should be empty) +--Third byte->Temp Data;s Intpart +--Forth byte->Temp Data's Float Part(Which should be empty) +--Fifth byte->SUM Byte, Humi+Temp + local checksum = 0 + local checksumTest + --DHT data acquired, process. + for i = 1, 8, 1 do -- Byte[0] + if (bitStream[i] > 3) then + humidity = humidity + 2 ^ (8 - i) + end + end + for i = 1, 8, 1 do -- Byte[2] + if (bitStream[i + 16] > 3) then + temperature = temperature + 2 ^ (8 - i) + end + end + for i = 1, 8, 1 do --Byte[4] + if (bitStream[i + 32] > 3) then + checksum = checksum + 2 ^ (8 - i) + end + end + + if(checksum ~= humidity+temperature) then + humidity = nil + temperature = nil + end + +end +---------------------------Convert the bitStream into Number through DHT22 Ways-------------------------- +local function bit2DHT22() +--As for DHT22 40Bit is consisit of 5Bytes +--First byte->Humidity Data's High Bit +--Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement) +--Third byte->Temp Data's High Bit +--Forth byte->Temp Data's Low Bit +--Fifth byte->SUM Byte + local checksum = 0 + local checksumTest + --DHT data acquired, process. + for i = 1, 16, 1 do + if (bitStream[i] > 3) then + humidity = humidity + 2 ^ (16 - i) + end + end + for i = 1, 16, 1 do + if (bitStream[i + 16] > 3) then + temperature = temperature + 2 ^ (16 - i) + end + end + for i = 1, 8, 1 do + if (bitStream[i + 32] > 3) then + checksum = checksum + 2 ^ (8 - i) + end + end + + checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8)) + checksumTest = bit.band(checksumTest, 0xFF) + + if temperature > 0x8000 then + -- convert to negative format + temperature = -(temperature - 0x8000) + end + + -- conditions compatible con float point and integer + if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then + humidity = nil + end +end + +---------------------------Check out the data-------------------------- +----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3]AND --- +---------------Which is empty when using DHT11------------------------- +function M.read(pin) + + read(pin) + + local byte_1 = 0 + local byte_2 = 0 + + for i = 1, 8, 1 do -- Byte[1] + if (bitStream[i+8] > 3) then + byte_1 = byte_1 + 2 ^ (8 - i) + end + end + + for i = 1, 8, 1 do -- Byte[1] + if (bitStream[i+24] > 3) then + byte_2 = byte_2 + 2 ^ (8 - i) + end + end + + if byte_1==0 and byte_2 == 0 then + bit2DHT11() + else + bit2DHT22() + end + +end + + +function M.getTemperature() + return temperature +end + +function M.getHumidity() + return humidity +end + +return M From 450b79dbde5c924ea59166c2d668cd5de40755aa Mon Sep 17 00:00:00 2001 From: funshine Date: Mon, 6 Apr 2015 00:05:08 +0800 Subject: [PATCH 12/22] add more mqtt example, add a mqtt subfolder --- examples/fragment.lua | 4 ++ .../{mqtt_test.lua => mqtt/mqtt2cloud.lua} | 13 +++-- lua_examples/mqtt/mqtt_file.lua | 56 +++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) rename lua_examples/{mqtt_test.lua => mqtt/mqtt2cloud.lua} (82%) create mode 100644 lua_examples/mqtt/mqtt_file.lua diff --git a/examples/fragment.lua b/examples/fragment.lua index 3f4ee2d0..6536024c 100644 --- a/examples/fragment.lua +++ b/examples/fragment.lua @@ -515,3 +515,7 @@ end) m:on("message",dispatch ) m:connect("m11.cloudmqtt.com",11214,0,1) -- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) + +tmr.alarm(0,10000,1,function() local pl = "time: "..tmr.time() + m:publish("/topic1",pl,0,0) + end) diff --git a/lua_examples/mqtt_test.lua b/lua_examples/mqtt/mqtt2cloud.lua similarity index 82% rename from lua_examples/mqtt_test.lua rename to lua_examples/mqtt/mqtt2cloud.lua index d27c6a93..b6b2893a 100644 --- a/lua_examples/mqtt_test.lua +++ b/lua_examples/mqtt/mqtt2cloud.lua @@ -1,19 +1,19 @@ --- Lua: mqtt.Client(clientid, keepalive, user, pass) -- test with cloudmqtt.com m_dis={} function dispatch(m,t,pl) if pl~=nil and m_dis[t] then - m_dis[t](pl) + m_dis[t](m,pl) end end -function topic1func(pl) +function topic1func(m,pl) print("get1: "..pl) end -function topic2func(pl) +function topic2func(m,pl) print("get2: "..pl) end m_dis["/topic1"]=topic1func m_dis["/topic2"]=topic2func +-- Lua: mqtt.Client(clientid, keepalive, user, pass) m=mqtt.Client("nodemcu1",60,"test","test123") m:on("connect",function(m) print("connection "..node.heap()) @@ -26,5 +26,8 @@ m:on("offline", function(conn) print(node.heap()) end) m:on("message",dispatch ) -m:connect("m11.cloudmqtt.com",11214,0,1) -- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) +m:connect("m11.cloudmqtt.com",11214,0,1) +tmr.alarm(0,10000,1,function() local pl = "time: "..tmr.time() + m:publish("/topic1",pl,0,0) + end) diff --git a/lua_examples/mqtt/mqtt_file.lua b/lua_examples/mqtt/mqtt_file.lua new file mode 100644 index 00000000..b491177c --- /dev/null +++ b/lua_examples/mqtt/mqtt_file.lua @@ -0,0 +1,56 @@ +-- test transfer files over mqtt. +m_dis={} +function dispatch(m,t,pl) + if pl~=nil and m_dis[t] then + m_dis[t](m,pl) + end +end + +function pubfile(m,filename) + file.close() + file.open(filename) + repeat + local pl=file.read(1024) + if pl then m:publish("/topic2",pl,0,0) end + until not pl + file.close() +end +-- payload(json): {"cmd":xxx,"content":xxx} +function topic1func(m,pl) + print("get1: "..pl) + local pack = cjson.decode(pl) + if pack.content then + if pack.cmd == "open" then file.open(pack.content,"w+") + elseif pack.cmd == "write" then file.write(pack.content) + elseif pack.cmd == "close" then file.close() + elseif pack.cmd == "remove" then file.remove(pack.content) + elseif pack.cmd == "run" then dofile(pack.content) + elseif pack.cmd == "read" then pubfile(m, pack.content) + end + end +end + +m_dis["/topic1"]=topic1func +-- Lua: mqtt.Client(clientid, keepalive, user, pass) +m=mqtt.Client() +m:on("connect",function(m) + print("connection "..node.heap()) + m:subscribe("/topic1",0,function(m) print("sub done") end) + end ) +m:on("offline", function(conn) + print("disconnect to broker...") + print(node.heap()) +end) +m:on("message",dispatch ) +-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) +m:connect(192.168.18.88,1883,0,1) + +-- usage: +-- another client(pc) subscribe to /topic2, will receive the test.lua content. +-- and publish below message to /topic1 +-- {"cmd":"open","content":"test.lua"} +-- {"cmd":"write","content":"print([[hello world]])\n"} +-- {"cmd":"write","content":"print(\"hello2 world2\")\n"} +-- {"cmd":"write","content":"test.lua"} +-- {"cmd":"run","content":"test.lua"} +-- {"cmd":"read","content":"test.lua"} From 560ad8e029238c9a3da28a0e91bd282427bb157a Mon Sep 17 00:00:00 2001 From: funshine Date: Mon, 6 Apr 2015 00:11:12 +0800 Subject: [PATCH 13/22] remove dht22 lib, use dht_lib instead --- lua_modules/dht22/README.md | 91 -------------------- lua_modules/dht22/dht_lib.lua | 157 ---------------------------------- 2 files changed, 248 deletions(-) delete mode 100644 lua_modules/dht22/README.md delete mode 100644 lua_modules/dht22/dht_lib.lua diff --git a/lua_modules/dht22/README.md b/lua_modules/dht22/README.md deleted file mode 100644 index ab7b30f9..00000000 --- a/lua_modules/dht22/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# DHTxx module - -This module is compatible with DHT11, DHT21 and DHT22. -No need to use a resistor to connect the pin data of DHT22 to ESP8266. - -##Integer Verison[When using DHT11, Float version is useless...] -### Example -```lua -PIN = 4 -- data pin, GPIO2 - -DHT= require("dht_lib") - ---dht.read11(PIN) -DHT.read22(PIN) - -t = DHT.getTemperature() -h = DHT.getHumidity() - -if h == nil then - print("Error reading from DHT11/22") -else - -- temperature in degrees Celsius and Farenheit - - print("Temperature: "..((t-(t % 10)) / 10).."."..(t % 10).." deg C") - - print("Temperature: "..(9 * t / 50 + 32).."."..(9 * t / 5 % 10).." deg F") - - -- humidity - - print("Humidity: "..((h - (h % 10)) / 10).."."..(h % 10).."%") -end - --- release module -DHT = nil -package.loaded["dht_lib"]=nil -``` -##Float Verison -###Example -```lua -PIN = 4 -- data pin, GPIO2 - -DHT= require("dht_lib") - ---dht.read11(PIN) -DHT.read22(PIN) - -t = DHT.getTemperature() -h = DHT.getHumidity() - -if h == nil then - print("Error reading from DHT11/22") -else - -- temperature in degrees Celsius and Farenheit - -- floating point and integer version: - print("Temperature: "..t.." deg C") - print("Temperature: "..(9 * t / 50 + 32).." deg F") - - -- humidity - print("Humidity: "..h.."%") -end - --- release module -DHT = nil -package.loaded["dht_lib"]=nil -``` -## Functions -### read11 -read11(pin) -Read humidity and temperature from DHT11. -###read22 -read22(pin) -Read humidity and temperature from DHT22/21. -**Parameters:** - -* pin - ESP8266 pin connect to data pin - -### getHumidity -getHumidity() -Returns the humidity of the last reading. - -**Returns:** -* last humidity reading in per thousand - -### getTemperature -getTemperature() -Returns the temperature of the last reading. - -**Returns:** -* last temperature reading in(dht22) 0.1ºC (dht11)1ºC -* - diff --git a/lua_modules/dht22/dht_lib.lua b/lua_modules/dht22/dht_lib.lua deleted file mode 100644 index 641f2e17..00000000 --- a/lua_modules/dht22/dht_lib.lua +++ /dev/null @@ -1,157 +0,0 @@ --- *************************************************************************** --- DHTxx(11,21,22) module for ESP8266 with nodeMCU --- --- Written by Javier Yanez mod by Martin --- but based on a script of Pigs Fly from ESP8266.com forum --- --- MIT license, http://opensource.org/licenses/MIT --- *************************************************************************** - ---Support list: ---DHT11 Tested ->read11 ---DHT21 Not Tested->read22 ---DHT22 Tested->read22 - ---==========================Module Part====================== -local moduleName = ... -local M = {} -_G[moduleName] = M ---==========================Local the UMI and TEMP=========== -local humidity -local temperature ---==========================Local the bitStream============== -local bitStream = {} - ----------------------------Read bitStream from DHTXX-------------------------- -local function read(pin) - - local bitlength = 0 - humidity = 0 - temperature = 0 - - -- Use Markus Gritsch trick to speed up read/write on GPIO - local gpio_read = gpio.read - - - for j = 1, 40, 1 do - bitStream[j] = 0 - end - - - - -- Step 1: send out start signal to DHT22 - gpio.mode(pin, gpio.OUTPUT) - gpio.write(pin, gpio.HIGH) - tmr.delay(100) - gpio.write(pin, gpio.LOW) - tmr.delay(20000) - gpio.write(pin, gpio.HIGH) - gpio.mode(pin, gpio.INPUT) - - -- Step 2: Receive bitStream from DHT11/22 - -- bus will always let up eventually, don't bother with timeout - while (gpio_read(pin) == 0 ) do end - local c=0 - while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end - -- bus will always let up eventually, don't bother with timeout - while (gpio_read(pin) == 0 ) do end - c=0 - while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end - - -- Step 3: DHT22 send data - for j = 1, 40, 1 do - while (gpio_read(pin) == 1 and bitlength < 10 ) do - bitlength = bitlength + 1 - end - bitStream[j] = bitlength - bitlength = 0 - -- bus will always let up eventually, don't bother with timeout - while (gpio_read(pin) == 0) do end - end -end ----------------------------Convert the bitStream into Number through DHT11 Ways-------------------------- -function M.read11(pin) ---As for DHT11 40Bit is consisit of 5Bytes ---First byte->Humidity Data's Int part ---Sencond byte->Humidity Data's Float Part(Which should be empty) ---Third byte->Temp Data;s Intpart ---Forth byte->Temp Data's Float Part(Which should be empty) ---Fifth byte->SUM Byte, Humi+Temp - read(pin) - local checksum = 0 - local checksumTest - --DHT data acquired, process. - for i = 1, 8, 1 do -- Byte[0] - if (bitStream[i] > 3) then - humidity = humidity + 2 ^ (8 - i) - end - end - for i = 1, 8, 1 do -- Byte[2] - if (bitStream[i + 16] > 3) then - temperature = temperature + 2 ^ (8 - i) - end - end - for i = 1, 8, 1 do --Byte[4] - if (bitStream[i + 32] > 3) then - checksum = checksum + 2 ^ (8 - i) - end - end - - if(checksum ~= humidity+temperature) then - humidity = nil - temperature = nil - end - -end ----------------------------Convert the bitStream into Number through DHT22 Ways-------------------------- -function M.read22( pin ) ---As for DHT22 40Bit is consisit of 5Bytes ---First byte->Humidity Data's High Bit ---Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement) ---Third byte->Temp Data's High Bit ---Forth byte->Temp Data's Low Bit ---Fifth byte->SUM Byte - read(pin) - local checksum = 0 - local checksumTest - --DHT data acquired, process. - for i = 1, 16, 1 do - if (bitStream[i] > 3) then - humidity = humidity + 2 ^ (16 - i) - end - end - for i = 1, 16, 1 do - if (bitStream[i + 16] > 3) then - temperature = temperature + 2 ^ (16 - i) - end - end - for i = 1, 8, 1 do - if (bitStream[i + 32] > 3) then - checksum = checksum + 2 ^ (8 - i) - end - end - - checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8)) - checksumTest = bit.band(checksumTest, 0xFF) - - if temperature > 0x8000 then - -- convert to negative format - temperature = -(temperature - 0x8000) - end - - -- conditions compatible con float point and integer - if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then - humidity = nil - end -end - ----------------------------Check out the data-------------------------- -function M.getTemperature() - return temperature -end - -function M.getHumidity() - return humidity -end - -return M From 9df94c7ee64f34ff9621316b5ef25d94200c6e32 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Mon, 6 Apr 2015 14:38:35 +0800 Subject: [PATCH 14/22] Really Fix the BUGs, add come comment Sorry for the mistake, I forgot to save the file when gitting... --- lua_modules/dht_lib/dht_lib.lua | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lua_modules/dht_lib/dht_lib.lua b/lua_modules/dht_lib/dht_lib.lua index e1edf13a..4fb60ae3 100644 --- a/lua_modules/dht_lib/dht_lib.lua +++ b/lua_modules/dht_lib/dht_lib.lua @@ -8,10 +8,15 @@ -- *************************************************************************** --Support list: ---DHT11 Tested ->read11 ---DHT21 Not Tested->read22 ---DHT22 Tested->read22 +--DHT11 Tested +--DHT21 Not Test yet +--DHT22(AM2302) Tested +--AM2320 Not Test yet + +--Output format-> Real temperature times 10(or DHT22 will miss it float part in Int Version) +--For example, the data read form DHT2x is 24.3 degree C, and the output will be 243 +---------------the data read form DHT1x is 27 degree C, and the output will be 270 --==========================Module Part====================== local moduleName = ... local M = {} @@ -99,7 +104,12 @@ local function bit2DHT11() if(checksum ~= humidity+temperature) then humidity = nil temperature = nil + else + humidity = humidity *10 -- In order to universe the DHT22 + temperature = temperature *10 end + + end ---------------------------Convert the bitStream into Number through DHT22 Ways-------------------------- @@ -144,7 +154,7 @@ local function bit2DHT22() end ---------------------------Check out the data-------------------------- -----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3]AND --- +----Auto Select the DHT11/DHT22 by checking the byte[1]==0 && byte[3]==0 --- ---------------Which is empty when using DHT11------------------------- function M.read(pin) @@ -172,7 +182,7 @@ function M.read(pin) end end - +--------------API for geting the data out------------------ function M.getTemperature() return temperature @@ -181,5 +191,5 @@ end function M.getHumidity() return humidity end - +-------------Return Index------------------------------------ return M From 81d9f8893a17a93e25566ddbc2d3cf45af4cd298 Mon Sep 17 00:00:00 2001 From: zeroday Date: Sun, 12 Apr 2015 23:34:11 +0800 Subject: [PATCH 15/22] fix #353 --- app/modules/auxmods.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/auxmods.h b/app/modules/auxmods.h index 149b1af3..ece3ff56 100644 --- a/app/modules/auxmods.h +++ b/app/modules/auxmods.h @@ -80,7 +80,7 @@ LUALIB_API int ( luaopen_file )( lua_State *L ); LUALIB_API int ( luaopen_ow )( lua_State *L ); #define AUXLIB_CJSON "cjson" -LUALIB_API int ( luaopen_ow )( lua_State *L ); +LUALIB_API int ( luaopen_cjson )( lua_State *L ); // Helper macros #define MOD_CHECK_ID( mod, id )\ From a3b72906d587ca10c3d93ddc52632909a3b77b0d Mon Sep 17 00:00:00 2001 From: Martin Han Date: Tue, 14 Apr 2015 20:42:16 +0800 Subject: [PATCH 16/22] Yeelink Modules --- lua_modules/yeelink/yeelink_lib.lua | 105 ++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 lua_modules/yeelink/yeelink_lib.lua diff --git a/lua_modules/yeelink/yeelink_lib.lua b/lua_modules/yeelink/yeelink_lib.lua new file mode 100644 index 00000000..39f2b129 --- /dev/null +++ b/lua_modules/yeelink/yeelink_lib.lua @@ -0,0 +1,105 @@ + +-- *************************************************************************** +-- Yeelink Updata Libiary +-- +-- Written by Martin +-- but based on a script of zhouxu_o from bbs.nodemcu.com +-- +-- MIT license, http://opensource.org/licenses/MIT +-- *************************************************************************** + +if wifi.sta.getip() == nil then + print("Please Connect WIFI First") + return nil +end +--==========================Module Part====================== + +local moduleName = ... +local M = {} +_G[moduleName] = M +--=========================Local Args======================= +local dns = "0.0.0.0" + +local device = "" +local sensor = "" +local apikey = "" + +--================================ +local debug = true --<<<<<<<<<<<<< Don't forget to "false" it before using +--================================ +local sk=net.createConnection(net.TCP, 0) + +local datapoint = 0 +--====DNS the yeelink ip advance(in order to save RAM)===== +sk:dns("api.yeelink.net",function(conn,ip) + +dns=ip + +print("DNS YEELINK OK... IP: "..dns) + +end) + +--========Set the init function=========== +--device->number +--sensor->number +-- apikey must be -> string <- +-- e.g. xxx.init(00000,00000,"123j12b3jkb12k4b23bv54i2b5b3o4") +--======================================== +function M.init(_device, _sensor, _apikey) + device = tostring(_device) + sensor = tostring(_sensor) + apikey = _apikey + if dns == "0.0.0.0" then + return false + else + return dns + end + +end + + +--=====Update to Yeelink Sever(At least 10s per sencods))===== +-- datapoint->number +-- +--e.g. xxx.update(233.333) +--============================================================ +function M.update(_datapoint) + + datapoint = tostring(_datapoint) + + sk:on("connection", function(conn) + + print("connect OK...") + + + local a=[[{"value":]] + local b=[[}]] + + local st=a..datapoint..b + + sk:send("POST /v1.0/device/"..device.."/sensor/"..sensor.."/datapoints HTTP/1.1\r\n" +.."Host: www.yeelink.net\r\n" +.."Content-Length: "..string.len(st).."\r\n"--the length of json is important +.."Content-Type: application/x-www-form-urlencoded\r\n" +.."U-ApiKey:"..apikey.."\r\n" +.."Cache-Control: no-cache\r\n\r\n" +..st.."\r\n" ) + + end) + + sk:on("receive", function(sck, content) + + if debug then + print("\r\n"..content.."\r\n") + else + print("Date Receive") + end + + end) + + sk:connect(80,dns) + + +end +--================end========================== +return M From 0f203f32c35c2ff7bcc16178555bd4b8007016cf Mon Sep 17 00:00:00 2001 From: Martin Han Date: Mon, 20 Apr 2015 19:43:24 +0800 Subject: [PATCH 17/22] Resuce RAM Usage --- lua_modules/dht_lib/dht_lib.lua | 149 ++++++++++++++------------------ 1 file changed, 66 insertions(+), 83 deletions(-) diff --git a/lua_modules/dht_lib/dht_lib.lua b/lua_modules/dht_lib/dht_lib.lua index 4fb60ae3..97823455 100644 --- a/lua_modules/dht_lib/dht_lib.lua +++ b/lua_modules/dht_lib/dht_lib.lua @@ -15,8 +15,6 @@ --AM2320 Not Test yet --Output format-> Real temperature times 10(or DHT22 will miss it float part in Int Version) ---For example, the data read form DHT2x is 24.3 degree C, and the output will be 243 ----------------the data read form DHT1x is 27 degree C, and the output will be 270 --==========================Module Part====================== local moduleName = ... local M = {} @@ -42,8 +40,6 @@ local function read(pin) bitStream[j] = 0 end - - -- Step 1: send out start signal to DHT22 gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) @@ -62,7 +58,7 @@ local function read(pin) while (gpio_read(pin) == 0 ) do end c=0 while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end - + -- Step 3: DHT22 send data for j = 1, 40, 1 do while (gpio_read(pin) == 1 and bitlength < 10 ) do @@ -74,70 +70,78 @@ local function read(pin) while (gpio_read(pin) == 0) do end end end ----------------------------Convert the bitStream into Number through DHT11 Ways-------------------------- -local function bit2DHT11() ---As for DHT11 40Bit is consisit of 5Bytes ---First byte->Humidity Data's Int part ---Sencond byte->Humidity Data's Float Part(Which should be empty) ---Third byte->Temp Data;s Intpart ---Forth byte->Temp Data's Float Part(Which should be empty) ---Fifth byte->SUM Byte, Humi+Temp - local checksum = 0 - local checksumTest - --DHT data acquired, process. + +---------------------------Check out the data-------------------------- +----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3] ------- +---------------Which is empty when using DHT11------------------------- +function M.read(pin) + read(pin) + + local byte_0 = 0 + local byte_1 = 0 + local byte_2 = 0 + local byte_3 = 0 + local byte_4 = 0 + for i = 1, 8, 1 do -- Byte[0] if (bitStream[i] > 3) then - humidity = humidity + 2 ^ (8 - i) + byte_0 = byte_0 + 2 ^ (8 - i) end end + + for i = 1, 8, 1 do -- Byte[1] + if (bitStream[i+8] > 3) then + byte_1 = byte_1 + 2 ^ (8 - i) + end + end + for i = 1, 8, 1 do -- Byte[2] - if (bitStream[i + 16] > 3) then - temperature = temperature + 2 ^ (8 - i) - end - end - for i = 1, 8, 1 do --Byte[4] - if (bitStream[i + 32] > 3) then - checksum = checksum + 2 ^ (8 - i) + if (bitStream[i+16] > 3) then + byte_2 = byte_2 + 2 ^ (8 - i) end end - if(checksum ~= humidity+temperature) then - humidity = nil - temperature = nil - else - humidity = humidity *10 -- In order to universe the DHT22 - temperature = temperature *10 + for i = 1, 8, 1 do -- Byte[3] + if (bitStream[i+24] > 3) then + byte_2 = byte_2 + 2 ^ (8 - i) + end + end + + for i = 1, 8, 1 do -- Byte[4] + if (bitStream[i+32] > 3) then + byte_4 = byte_4 + 2 ^ (8 - i) + end end - -end ----------------------------Convert the bitStream into Number through DHT22 Ways-------------------------- -local function bit2DHT22() ---As for DHT22 40Bit is consisit of 5Bytes ---First byte->Humidity Data's High Bit ---Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement) ---Third byte->Temp Data's High Bit ---Forth byte->Temp Data's Low Bit ---Fifth byte->SUM Byte - local checksum = 0 - local checksumTest - --DHT data acquired, process. - for i = 1, 16, 1 do - if (bitStream[i] > 3) then - humidity = humidity + 2 ^ (16 - i) + if byte_1==0 and byte_3 == 0 then + ---------------------------Convert the bitStream into Number through DHT11's Way-------------------------- + --As for DHT11 40Bit is consisit of 5Bytes + --First byte->Humidity Data's Int part + --Sencond byte->Humidity Data's Float Part(Which should be empty) + --Third byte->Temp Data;s Intpart + --Forth byte->Temp Data's Float Part(Which should be empty) + --Fifth byte->SUM Byte, Humi+Temp + + if(byte_4 ~= byte_0+byte_2) then + humidity = nil + temperature = nil + else + humidity = byte_0 *10 -- In order to universe with the DHT22 + temperature = byte_2 *10 end - end - for i = 1, 16, 1 do - if (bitStream[i + 16] > 3) then - temperature = temperature + 2 ^ (16 - i) - end - end - for i = 1, 8, 1 do - if (bitStream[i + 32] > 3) then - checksum = checksum + 2 ^ (8 - i) - end - end + + else ---------------------------Convert the bitStream into Number through DHT22's Way-------------------------- + --As for DHT22 40Bit is consisit of 5Bytes + --First byte->Humidity Data's High Bit + --Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement) + --Third byte->Temp Data's High Bit + --Forth byte->Temp Data's Low Bit + --Fifth byte->SUM Byte + + humidity = byte_0 * 256 + byte_1 + temperature = byte_2 * 256 + byte_3 + checksum = byte_4 checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8)) checksumTest = bit.band(checksumTest, 0xFF) @@ -151,35 +155,14 @@ local function bit2DHT22() if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then humidity = nil end -end ----------------------------Check out the data-------------------------- -----Auto Select the DHT11/DHT22 by checking the byte[1]==0 && byte[3]==0 --- ----------------Which is empty when using DHT11------------------------- -function M.read(pin) - - read(pin) - - local byte_1 = 0 - local byte_2 = 0 - - for i = 1, 8, 1 do -- Byte[1] - if (bitStream[i+8] > 3) then - byte_1 = byte_1 + 2 ^ (8 - i) - end end - for i = 1, 8, 1 do -- Byte[1] - if (bitStream[i+24] > 3) then - byte_2 = byte_2 + 2 ^ (8 - i) - end - end - - if byte_1==0 and byte_2 == 0 then - bit2DHT11() - else - bit2DHT22() - end + byte_0 = nil + byte_1 = nil + byte_2 = nil + byte_3 = nil + byte_4 = nil end --------------API for geting the data out------------------ From fc19725fef5494ba6bc8eb44f370c6f2434a5707 Mon Sep 17 00:00:00 2001 From: devsaurus Date: Tue, 21 Apr 2015 21:48:12 +0200 Subject: [PATCH 18/22] make variables local to save heap --- lua_examples/u8glib/u8g_bitmaps.lua | 12 ++++++------ lua_examples/u8glib/u8g_graphics_test.lua | 12 ++++++------ lua_examples/u8glib/u8g_rotation.lua | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lua_examples/u8glib/u8g_bitmaps.lua b/lua_examples/u8glib/u8g_bitmaps.lua index 1b388e41..4ac8a60f 100644 --- a/lua_examples/u8glib/u8g_bitmaps.lua +++ b/lua_examples/u8glib/u8g_bitmaps.lua @@ -2,9 +2,9 @@ -- setup I2c and connect display function init_i2c_display() -- SDA and SCL can be assigned freely to available GPIOs - sda = 5 -- GPIO14 - scl = 6 -- GPIO12 - sla = 0x3c + local sda = 5 -- GPIO14 + local scl = 6 -- GPIO12 + local sla = 0x3c i2c.setup(0, sda, scl, i2c.SLOW) disp = u8g.ssd1306_128x64_i2c(sla) end @@ -15,9 +15,9 @@ function init_spi_display() -- Hardware SPI MOSI = GPIO13 -- Hardware SPI MISO = GPIO12 (not used) -- CS, D/C, and RES can be assigned freely to available GPIOs - cs = 8 -- GPIO15, pull-down 10k to GND - dc = 4 -- GPIO2 - res = 0 -- GPIO16 + local cs = 8 -- GPIO15, pull-down 10k to GND + local dc = 4 -- GPIO2 + local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) disp = u8g.ssd1306_128x64_spi(cs, dc, res) diff --git a/lua_examples/u8glib/u8g_graphics_test.lua b/lua_examples/u8glib/u8g_graphics_test.lua index 27c7a346..d1049ffc 100644 --- a/lua_examples/u8glib/u8g_graphics_test.lua +++ b/lua_examples/u8glib/u8g_graphics_test.lua @@ -2,9 +2,9 @@ -- setup I2c and connect display function init_i2c_display() -- SDA and SCL can be assigned freely to available GPIOs - sda = 5 -- GPIO14 - scl = 6 -- GPIO12 - sla = 0x3c + local sda = 5 -- GPIO14 + local scl = 6 -- GPIO12 + local sla = 0x3c i2c.setup(0, sda, scl, i2c.SLOW) disp = u8g.ssd1306_128x64_i2c(sla) end @@ -15,9 +15,9 @@ function init_spi_display() -- Hardware SPI MOSI = GPIO13 -- Hardware SPI MISO = GPIO12 (not used) -- CS, D/C, and RES can be assigned freely to available GPIOs - cs = 8 -- GPIO15, pull-down 10k to GND - dc = 4 -- GPIO2 - res = 0 -- GPIO16 + local cs = 8 -- GPIO15, pull-down 10k to GND + local dc = 4 -- GPIO2 + local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) disp = u8g.ssd1306_128x64_spi(cs, dc, res) diff --git a/lua_examples/u8glib/u8g_rotation.lua b/lua_examples/u8glib/u8g_rotation.lua index 6d81c779..81d81e6f 100644 --- a/lua_examples/u8glib/u8g_rotation.lua +++ b/lua_examples/u8glib/u8g_rotation.lua @@ -2,9 +2,9 @@ -- setup I2c and connect display function init_i2c_display() -- SDA and SCL can be assigned freely to available GPIOs - sda = 5 -- GPIO14 - scl = 6 -- GPIO12 - sla = 0x3c + local sda = 5 -- GPIO14 + local scl = 6 -- GPIO12 + local sla = 0x3c i2c.setup(0, sda, scl, i2c.SLOW) disp = u8g.ssd1306_128x64_i2c(sla) end @@ -15,9 +15,9 @@ function init_spi_display() -- Hardware SPI MOSI = GPIO13 -- Hardware SPI MISO = GPIO12 (not used) -- CS, D/C, and RES can be assigned freely to available GPIOs - cs = 8 -- GPIO15, pull-down 10k to GND - dc = 4 -- GPIO2 - res = 0 -- GPIO16 + local cs = 8 -- GPIO15, pull-down 10k to GND + local dc = 4 -- GPIO2 + local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) disp = u8g.ssd1306_128x64_spi(cs, dc, res) From 5bda87845ff706cc16a54d4aa8a559ac48b069f8 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Wed, 22 Apr 2015 12:50:02 +0800 Subject: [PATCH 19/22] Update to Ver0.1.2, fix logic bug Detail: When require lib before connect to ap, program will return nil but the table. --- lua_modules/yeelink/yeelink_lib.lua | 43 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/lua_modules/yeelink/yeelink_lib.lua b/lua_modules/yeelink/yeelink_lib.lua index 39f2b129..8702cbf6 100644 --- a/lua_modules/yeelink/yeelink_lib.lua +++ b/lua_modules/yeelink/yeelink_lib.lua @@ -1,17 +1,12 @@ -- *************************************************************************** --- Yeelink Updata Libiary +-- Yeelink Updata Libiary Version 0.1.2 -- -- Written by Martin -- but based on a script of zhouxu_o from bbs.nodemcu.com -- -- MIT license, http://opensource.org/licenses/MIT -- *************************************************************************** - -if wifi.sta.getip() == nil then - print("Please Connect WIFI First") - return nil -end --==========================Module Part====================== local moduleName = ... @@ -30,7 +25,23 @@ local debug = true --<<<<<<<<<<<<< Don't forget to "false" it before using local sk=net.createConnection(net.TCP, 0) local datapoint = 0 + + --====DNS the yeelink ip advance(in order to save RAM)===== + +if wifi.sta.getip() == nil then + print("Please Connect WIFI First") + tmr.alarm(1,1000,1,function () + if wifi.sta.getip() ~= nil then + tmr.stop(1) + sk:dns("api.yeelink.net",function(conn,ip) + dns=ip + print("DNS YEELINK OK... IP: "..dns) + end) + end + end) +end + sk:dns("api.yeelink.net",function(conn,ip) dns=ip @@ -50,14 +61,32 @@ function M.init(_device, _sensor, _apikey) sensor = tostring(_sensor) apikey = _apikey if dns == "0.0.0.0" then + tmr.alarm(2,5000,1,function () + if dns == "0.0.0.0" then + print("Waiting for DNS...") + end + end) return false else return dns end +end +--========Check the DNS Status=========== +--if DNS success, return the address(string) +--if DNS fail(or processing), return nil +-- +-- +--======================================== +function M.getDNS() + + if dns == "0.0.0.0" then + return nil + else + return dns + end end - --=====Update to Yeelink Sever(At least 10s per sencods))===== -- datapoint->number -- From a60f28cf9ccc875c193986f712a0f765b58fffc3 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Wed, 22 Apr 2015 13:10:06 +0800 Subject: [PATCH 20/22] Ver 0.1.2 r1 Add init ok callback function --- lua_modules/yeelink/yeelink_lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua_modules/yeelink/yeelink_lib.lua b/lua_modules/yeelink/yeelink_lib.lua index 8702cbf6..226e33ce 100644 --- a/lua_modules/yeelink/yeelink_lib.lua +++ b/lua_modules/yeelink/yeelink_lib.lua @@ -1,6 +1,6 @@ -- *************************************************************************** --- Yeelink Updata Libiary Version 0.1.2 +-- Yeelink Updata Libiary Version 0.1.2 r1 -- -- Written by Martin -- but based on a script of zhouxu_o from bbs.nodemcu.com From effb57247caefa89476b64824fa57bf08052aa42 Mon Sep 17 00:00:00 2001 From: Martin Han Date: Wed, 22 Apr 2015 13:16:37 +0800 Subject: [PATCH 21/22] Add Example to yeelink lib --- .../yeelink/Example_for_Yeelink_Lib.lua | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 lua_modules/yeelink/Example_for_Yeelink_Lib.lua diff --git a/lua_modules/yeelink/Example_for_Yeelink_Lib.lua b/lua_modules/yeelink/Example_for_Yeelink_Lib.lua new file mode 100644 index 00000000..d5cae98c --- /dev/null +++ b/lua_modules/yeelink/Example_for_Yeelink_Lib.lua @@ -0,0 +1,25 @@ +-- *************************************************************************** +-- Example for Yeelink Lib +-- +-- Written by Martin +-- +-- +-- MIT license, http://opensource.org/licenses/MIT +-- *************************************************************************** + +wifi.setmode(wifi.STATION) --Step1: Connect to Wifi +wifi.sta.config("SSID","Password") + +dht = require("dht_lib") --Step2: "Require" the libs +yeelink = require("yeelink_lib") + +yeelink.init(23333,23333,"You api-key",function() --Step3: Register the callback function + + print("Yeelink Init OK...") + tmr.alarm(1,60000,1,function() --Step4: Have fun~ (Update your data) + + dht.read(4) + yeelink.update(dht.getTemperature()) + + end) +end) From 897c8cd16904682467c55a4b63b21fc191c23a86 Mon Sep 17 00:00:00 2001 From: devsaurus Date: Fri, 24 Apr 2015 21:57:27 +0200 Subject: [PATCH 22/22] further reduce memory for u8g graphics test --- lua_examples/u8glib/u8g_graphics_test.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lua_examples/u8glib/u8g_graphics_test.lua b/lua_examples/u8glib/u8g_graphics_test.lua index d1049ffc..1985b461 100644 --- a/lua_examples/u8glib/u8g_graphics_test.lua +++ b/lua_examples/u8glib/u8g_graphics_test.lua @@ -91,17 +91,6 @@ function ascii_1() end end -function ascii_2() - local x, y, s - disp:drawStr(0, 0, "ASCII page 2") - for y = 0, 5, 1 do - for x = 0, 15, 1 do - s = y*16 + x + 160 - disp:drawStr(x*7, y*10+10, string.char(s)) - end - end -end - function extra_page(a) disp:drawStr(0, 12, "setScale2x2") disp:setScale2x2() @@ -131,8 +120,6 @@ function draw(draw_state) elseif (component == 6) then ascii_1() elseif (component == 7) then - ascii_2() - elseif (component == 8) then extra_page(bit.band(draw_state, 7)) end end