I'm trying to do a script, that will measure the temperature on multiple DS18B20 sensors and report them to thingspeak.com.
This is the code (I'll change the API key later...):
pin = 3
ow.setup(pin)
counter=0
temps={}
fields={}
apiKey = "B98OP5LG0GPH9RYV"
fields["100e295101080069"] = "field1"
fields["10a850de020800be"] = "field2"
fields["28abb595010000ec"] = "field3"
function bxor(a,b)
local r = 0
for i = 0, 31 do
if ( a % 2 + b % 2 == 1 ) then
r = r + 2^i
end
a = a / 2
b = b / 2
end
return r
end
function getTemp()
addr = ow.reset_search(pin)
repeat
tmr.wdclr()
if (addr ~= nil) then
crc = ow.crc8(string.sub(addr,1,7))
if (crc == addr:byte(8)) then
if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
sensor = ""
for j = 1,8 do sensor = sensor .. string.format("%02x", addr:byte(j)) end
ow.reset(pin)
ow.select(pin, addr)
ow.write(pin, 0x44, 1)
tmr.delay(1000000)
present = ow.reset(pin)
ow.select(pin, addr)
ow.write(pin,0xBE, 1)
data = nil
data = string.char(ow.read(pin))
for i = 1, 8 do
data = data .. string.char(ow.read(pin))
end
crc = ow.crc8(string.sub(data,1,8))
if (crc == data:byte(9)) then
t = (data:byte(1) + data:byte(2) * 256)
if (t > 32768) then
t = (bxor(t, 0xffff)) + 1
t = (-1) * t
end
t = t * 625
if(addr:byte(1) == 0x10) then
-- we have DS18S20, the measurement must change
t = t * 8; -- compensating for the 9-bit resolution only
t = t - 2500 + ((10000 * (data:byte(8) - data:byte(7))) / data:byte(8))
end
temps[sensor] = t
print(sensor .. ": " .. t)
end
tmr.wdclr()
end
end
end
addr = ow.search(pin)
until(addr == nil)
end
function sendData()
dataToSend="GET /update?key=" .. apiKey
for sensorID, temperature in pairs(temps) do
if not (fields[sensorID] == nil) then
dataToSend = dataToSend .. "&" .. fields[sensorID] .. "=" .. temperature/10000
end
end
tmr.wdclr()
dataToSend = dataToSend .. " HTTP/1.1\r\n"
dataToSend = dataToSend .. "Host: api.thingspeak.com\r\n"
dataToSend = dataToSend .. "Accept: */*\r\n"
dataToSend = dataToSend .. "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n"
dataToSend = dataToSend .. "\r\n"
print("Sending data to thingspeak.com")
conn=net.createConnection(net.TCP, 0)
conn:on("receive", function(conn, payload)
print("Response: " .. payload)
end)
-- api.thingspeak.com 184.106.153.149
conn:connect(80,'184.106.153.149')
conn:on("sent",function(conn)
print("Closing connection")
conn:close()
payloadSent = 1
end)
conn:on("disconnection", function(conn)
print("Got disconnection...")
end)
conn:send(dataToSend)
end
getTemp()
sendData() Now the problem:
- running on 0.9.6 nodeMCU version, the file throws "not enough memory" when first executed. When I execute it again, it works. After reset it always works...
- when running the code, the data never got sent, I get "Got disconnection..." every time without the payload being sent
- when I directly type command "sendData()" right after the code is executed, the data is always sent
- when I call the function to get the temperature "getTemp()" and then run "sendData()", the data is sent correctly
I have no idea what am I doing wrong. I suspect this is a heap or some kind of memory allocation problem.
How can I clear memory of some objects - e.g. the table with measurements?
Thanks for any advices...