Post your best Lua script examples here

User avatar
By sancho
#5959 OK, I found a workaround to address the problem, now it works. However, I do not know why the old version did not :(
Code: Select allpin = 4
ow.setup(pin)

output = nil

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()
      sensors={}
      temps={}
      counter=0
      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,7 do sensor = sensor .. string.format("%02x", addr:byte(j)) end
                sensors[counter] = sensor
                ow.reset(pin)
                ow.select(pin, addr)
                ow.write(pin, 0x44, 1)
                tmr.delay(1000 * 1000)
                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[counter] = t
                end
          end
        end
      end
      addr = ow.search(pin)
      counter = counter + 1
      until(addr == nil)

    output = ""
    for i, sensorID in ipairs(sensors) do
        t1 = temps[i] / 10000
        t2 = (temps[i] >= 0 and temps[i] % 10000) or (10000 - temps[i] % 10000)
        output = output .. wifi.sta.getmac()
        output = output .."\t" .. sensorID .. "\t"
        output = output .. t1 .. "." .. string.format("%04d", t2) .. "\n"
    end
    output = output .. "#"
end

function sendData()
    if(output ~= nil) then
        if(string.byte(output, -1) == string.byte("#")) then
            print("About to send:\n" .. output)
            sk=net.createConnection(net.TCP, 0)
            sk:on("receive", function(sck, c) print(c) end )
            sk:connect(8888, "192.168.11.1")
            sk:send(output)
            sk:on("sent", function(conn) print "Closing connection" conn:close() end)
            output = nil
        end
    end
end

function checkIP()
    if wifi.sta.getip() ~= nil then
        tmr.stop(0)
        tmr.wdclr()
        print("Got IP")
        print(wifi.sta.getip())
        print("Starting Temp measurement")
        getTemp()
        tmr.alarm(0,5*1000, 1, sendData)
        tmr.alarm(1,30*1000, 1, getTemp)
    end
end

tmr.alarm(0, 2 * 1000, 1, checkIP)
User avatar
By sancho
#5992 So, I looked at the script and fixed it - now it displays the output in following format:
Code: Select allMAC address
sensor address <tab> sensor temperature
sensor address 2 <tab> sensor temperature 2
...

So in real life:
Code: Select all18-FE-34-9E-E1-42
100e295101080069   24.1250
28abb595010000ec   23.4375


Here is the code:
Code: Select allpin = 4
ow.setup(pin)

counter=0
temps={}

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

srv=net.createServer(net.TCP)
srv:listen(8080,function(conn)
    getTemp()
    output = wifi.sta.getmac() .. "\n"
    for sensorID, temperature in pairs(temps) do
        t1 = temperature / 10000
        t2 = (temperature >= 0 and temperature % 10000) or (10000 - temperature % 10000)
        output = output .. sensorID .. "\t"
        output = output .. t1 .. "." .. string.format("%04d", t2) .. "\n"
    end

    conn:send(output)
  conn:on("sent",function(conn) conn:close() end)
end)

User avatar
By baracudaz
#6266 Thanks for sharing! I took another approach. While I noticed Lua module for ds18b20 is already part of nodemcu source code available at Github: https://github.com/nodemcu/nodemcu-firm ... es/ds18b20

So all I had to do is to fetch the module, upload "ds18b20.lua" from Github to my nodemcu/ESP-01 and my resulting code is basically simple as:
Code: Select allrequire('ds18b20')

gpio0, gpio2 = 3, 4

ds18b20.setup(gpio0)

srv=net.createServer(net.TCP)
srv:listen(80,
     function(conn)
          conn:send("HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" ..
              "<!DOCTYPE HTML>" ..
              "<html><body>" ..
              "<b>ESP8266</b></br>" ..
              "Temperature : " .. ds18b20.read() .. "<br>" ..
              "Node ChipID : " .. node.chipid() .. "<br>" ..
              "Node MAC : " .. wifi.sta.getmac() .. "<br>" ..
              "Node Heap : " .. node.heap() .. "<br>" ..
              "Timer Ticks : " .. tmr.now() .. "<br>" ..
              "</html></body>")         
          conn:on("sent",function(conn) conn:close() end)
     end
)

Producing following results:
Code: Select allESP8266
Temperature : 23.4375
Node ChipID : ...
Node MAC : 18-FE-34-...
Node Heap : 7080
Timer Ticks : 1866967595