Post your best Lua script examples here

User avatar
By Toshi Bass
#5941 Hi Pigs Fly
I saw this code from you in another post i cannot get it to work, tied it on 0.9.2 (219) & 0.9.4 (222) it just produces :
stdin:1: attempt to compare number with nil

Hi Sancho
I don't think the script is crappy, the getTemp() function is working great it gets both my sensor readings perfectly however, although the automated post part again works exactly how I want it to work (its constantly sending the temperature of my second sensor to my web page) my skill is so low that I cannot figure out how get and send both sensor reading (whether in a single POST or 2 separate POSTS) I don't think your suggestion of a separate web interface will personalty help me as I want to incorporate the sensor reading into my own web page,

Finally sorry for the confusion when I said "web page" what i meant was: when I enter http://192.168.0.179:8080/ into chrome browser address bar and press enter it displays on the screen only the second sensor reading, its clear to me that although getTemp successfully reads both my sensors the srv=net.createServer(net.TCP) part of the code is not designed to POST both sensor readings, currently.
User avatar
By sancho
#5952 Thanks for the explanation - now I understand.
The original script of mine was really meant for a single temp sensor. I updated it with the ability to send multiple results:
Code: Select allpin = 4
ow.setup(pin)

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()
      print("Measurement start")
      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
                print("Have sensor " .. sensor)
                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
                   print("Got temp: " .. t)
                   temps[counter] = t
                end
          end
        end
      end
      addr = ow.search(pin)
      counter = counter + 1
      until(addr == nil)

    srv=net.createConnection(net.TCP, 0)
    srv:connect(8888, "192.168.11.1")
    srv:on("connection", function(conn)
                             print "We have connection"
                         end
                         )
    for i, sensorID in ipairs(sensors) do
        t1 = temps[i] / 10000
        t2 = (temps[i] >= 0 and temps[i] % 10000) or (10000 - temps[i] % 10000)
        srv:send(wifi.sta.getmac())
        print("Sending: \t" .. sensorID .. "\t" .. t1 .. "." .. string.format("%04d", t2) .. "\n")
        srv:send("\t" .. sensorID .. "\t" .. t1 .. "." .. string.format("%04d", t2) .. "\n")
    end
    srv:on("sent",function(conn)
                      print("Data sent")
                      conn:close()
                  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,30*1000, 1, getTemp)
    end
end

tmr.alarm(0, 2 * 1000, 1, checkIP)

The new code includes fixes for the measurement using DS18S20 (9bit resolution + compensation based on the documentation).
However, with the new firmware (0.9.4) the sending part is not working for me - I already filed a bug to this thread.
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)