As the title says... Chat on...

User avatar
By sancho
#16402 Hi! I am probably too stupid to solve this by myself.
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...):
Code: Select allpin = 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...