From fb0938db2ecfb2e4578a46abcd502981a84080be Mon Sep 17 00:00:00 2001 From: Tuan PM Date: Sat, 31 Jan 2015 11:49:24 +0700 Subject: [PATCH 1/3] fixes nodemcu/nodemcu-firmware#155 lwt qos, retain, change header support MQTT 3.1.1 --- app/modules/mqtt.c | 9 ++++++--- app/mqtt/mqtt_msg.c | 10 +++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/modules/mqtt.c b/app/modules/mqtt.c index 332a9e87..3c970feb 100644 --- a/app/modules/mqtt.c +++ b/app/modules/mqtt.c @@ -472,7 +472,8 @@ static int mqtt_socket_client( lua_State* L ) stack++; } if(username == NULL) - return 1; + il = 0; + NODE_DBG("lengh username: %d\r\n", il); mud->connect_info.username = (uint8_t *)c_zalloc(il + 1); if(!mud->connect_info.username){ return luaL_error(L, "not enough memory"); @@ -486,7 +487,9 @@ static int mqtt_socket_client( lua_State* L ) stack++; } if(password == NULL) - return 1; + il = 0; + NODE_DBG("lengh password: %d\r\n", il); + mud->connect_info.password = (uint8_t *)c_zalloc(il + 1); if(!mud->connect_info.password){ return luaL_error(L, "not enough memory"); @@ -659,7 +662,7 @@ static int mqtt_socket_lwt( lua_State* L ) lwtMsg = luaL_checklstring( L, stack, &il ); if (lwtMsg == NULL) { - return luaL_error( L, "need lwt topic"); + return luaL_error( L, "need lwt message"); } mud->connect_info.will_topic = (uint8_t*) c_zalloc( topicSize + 1 ); diff --git a/app/mqtt/mqtt_msg.c b/app/mqtt/mqtt_msg.c index 5e49bfb1..a58f6057 100644 --- a/app/mqtt/mqtt_msg.c +++ b/app/mqtt/mqtt_msg.c @@ -47,7 +47,7 @@ struct __attribute((__packed__)) mqtt_connect_variable_header { uint8_t lengthMsb; uint8_t lengthLsb; - uint8_t magic[6]; + uint8_t magic[4]; uint8_t version; uint8_t flags; uint8_t keepaliveMsb; @@ -293,9 +293,9 @@ mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_inf connection->message.length += sizeof(*variable_header); variable_header->lengthMsb = 0; - variable_header->lengthLsb = 6; - memcpy(variable_header->magic, "MQIsdp", 6); - variable_header->version = 3; + variable_header->lengthLsb = 4; + memcpy(variable_header->magic, "MQTT", 4); + variable_header->version = 4; variable_header->flags = 0; variable_header->keepaliveMsb = info->keepalive >> 8; variable_header->keepaliveLsb = info->keepalive & 0xff; @@ -322,7 +322,7 @@ mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_inf variable_header->flags |= MQTT_CONNECT_FLAG_WILL; if(info->will_retain) variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN; - variable_header->flags |= (info->will_qos & 3) << 4; + variable_header->flags |= (info->will_qos & 3) << 3; } if(info->username != NULL && info->username[0] != '\0') From 169699b93acf37ac2f486dd3acadc3fb85b6c881 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Sat, 31 Jan 2015 11:27:24 +0300 Subject: [PATCH 2/3] ds18b20: negatives handled --- lua_examples/yet-another-ds18b20.lua | 46 ++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/lua_examples/yet-another-ds18b20.lua b/lua_examples/yet-another-ds18b20.lua index edcbe2d1..e02a2fe9 100644 --- a/lua_examples/yet-another-ds18b20.lua +++ b/lua_examples/yet-another-ds18b20.lua @@ -5,10 +5,11 @@ -- Vladimir Dronnikov -- -- Example: --- for k, v in pairs(require("ds18b20").read(4)) do print(k, v) end +-- require("ds18b20").read(4, function(r) for k, v in pairs(r) do print(k, v) end end) ------------------------------------------------------------------------------ local M do + local bit = bit local format_addr = function(a) return ("%02x-%02x%02x%02x%02x%02x%02x"):format( a:byte(1), @@ -16,7 +17,7 @@ do a:byte(4), a:byte(3), a:byte(2) ) end - local read = function(pin, delay) + local read = function(pin, cb, delay) local ow = require("ow") -- get list of relevant devices local d = { } @@ -37,25 +38,32 @@ do ow.skip(pin) ow.write(pin, 0x44, 1) -- wait a bit - tmr.delay(delay or 100000) + tmr.alarm(0, delay or 100, 0, function() -- iterate over devices - local r = { } - for i = 1, #d do - tmr.wdclr() - -- read rom command - ow.reset(pin) - ow.select(pin, d[i]) - ow.write(pin, 0xBE, 1) - -- read data - local x = ow.read_bytes(pin, 9) - if ow.crc8(x) == 0 then - local t = (x:byte(1) + x:byte(2) * 256) * 625 - -- NB: temperature in Celcius * 10^4 - r[format_addr(d[i])] = t - d[i] = nil + local r = { } + for i = 1, #d do + tmr.wdclr() + -- read rom command + ow.reset(pin) + ow.select(pin, d[i]) + ow.write(pin, 0xBE, 1) + -- read data + local x = ow.read_bytes(pin, 9) + if ow.crc8(x) == 0 then + local t = (x:byte(1) + x:byte(2) * 256) + -- negatives? + if bit.isset(t, 15) then t = 1 - bit.bxor(t, 0xffff) end + -- NB: temperature in Celsius * 10^4 + t = t * 625 + -- NB: due 850000 means bad pullup. ignore + if t ~= 850000 then + r[format_addr(d[i])] = t + end + d[i] = nil + end end - end - return r + cb(r) + end) end -- expose M = { From a00044980c942c6ccb45445f7963016ec7db9da0 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Sat, 31 Jan 2015 12:55:51 +0300 Subject: [PATCH 3/3] yet another bmp085 module added --- lua_examples/yet-another-bmp085.lua | 108 ++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 lua_examples/yet-another-bmp085.lua diff --git a/lua_examples/yet-another-bmp085.lua b/lua_examples/yet-another-bmp085.lua new file mode 100644 index 00000000..5de2de09 --- /dev/null +++ b/lua_examples/yet-another-bmp085.lua @@ -0,0 +1,108 @@ +------------------------------------------------------------------------------ +-- BMP085 query module +-- +-- LICENCE: http://opensource.org/licenses/MIT +-- Vladimir Dronnikov +-- Heavily based on work of Christee +-- +-- Example: +-- require("bmp085").read(sda, scl) +------------------------------------------------------------------------------ +local M +do + -- cache + local i2c, tmr = i2c, tmr + -- helpers + local r8 = function(reg) + i2c.start(0) + i2c.address(0, 0x77, i2c.TRANSMITTER) + i2c.write(0, reg) + i2c.stop(0) + i2c.start(0) + i2c.address(0, 0x77, i2c.RECEIVER) + local r = i2c.read(0, 1) + i2c.stop(0) + return r:byte(1) + end + local w8 = function(reg, val) + i2c.start(0) + i2c.address(0, 0x77, i2c.TRANSMITTER) + i2c.write(0, reg) + i2c.write(0, val) + i2c.stop(0) + end + local r16u = function(reg) + return r8(reg) * 256 + r8(reg + 1) + end + local r16 = function(reg) + local r = r16u(reg) + if r > 32767 then r = r - 65536 end + return r + end + -- calibration data + local AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD + -- read + local read = function(sda, scl, oss) + i2c.setup(0, sda, scl, i2c.SLOW) + -- cache calibration data + if not AC1 then + AC1 = r16(0xAA) + AC2 = r16(0xAC) + AC3 = r16(0xAE) + AC4 = r16u(0xB0) + AC5 = r16u(0xB2) + AC6 = r16u(0xB4) + B1 = r16(0xB6) + B2 = r16(0xB8) + MB = r16(0xBA) + MC = r16(0xBC) + MD = r16(0xBE) + end + -- get raw P + local p + -- NB: optimize for oss = 0 + if not oss then oss = 0 end + if oss == 0 then + oss = 0 + w8(0xF4, 0x34) + tmr.delay(5000) + p = r8(0xF6) * 256 + r8(0xF7) + else + w8(0xF4, 0x34 + 64 * oss) + tmr.delay(30000) + p = r8(0xF6) * 65536 + r8(0xF7) * 256 + r8(0xF8) + p = p / 2^(8 - oss) + end + -- get T + w8(0xF4, 0x2E) + tmr.delay(5000) + local t = r16(0xF6) + local X1 = (t - AC6) * AC5 / 32768 + local X2 = MC * 2048 / (X1 + MD) + t = (X2 + X1 + 8) / 16 + -- normalize P + local B5 = t * 16 - 8; + local B6 = B5 - 4000 + local X1 = B2 * (B6 * B6 / 4096) / 2048 + local X2 = AC2 * B6 / 2048 + local X3 = X1 + X2 + local B3 = ((AC1 * 4 + X3) * 2^oss + 2) / 4 + X1 = AC3 * B6 / 8192 + X2 = (B1 * (B6 * B6 / 4096)) / 65536 + X3 = (X1 + X2 + 2) / 4 + local B4 = AC4 * (X3 + 32768) / 32768 + local B7 = (p - B3) * (50000 / 2^oss) + p = B7 / B4 * 2 + X1 = (p / 256)^2 + X1 = (X1 * 3038) / 65536 + X2 = (-7357 * p) / 65536 + p = p + (X1 + X2 + 3791) / 16 + -- Celsius * 10, Hg mm * 10 + return t, p * 3 / 40 + end + -- expose + M = { + read = read, + } +end +return M