Post your best Lua script examples here

User avatar
By VasilijHCN
#4994
sancho wrote:Please, take a look into my code for correct procedure to get negative temperatures. http://www.esp8266.com/viewtopic.php?f=19&t=752#p4433

Thanks but when using this code i get something like 4085 C (abnormal temp, but not actual negative temp)

Code: Select allpin = 2
ow.setup(pin)

counter=0
lasttemp=-999

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
                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
                   lasttemp = t
         print("Last temp: " .. lasttemp)
                end                   
                tmr.wdclr()
          end
        end
      end
      addr = ow.search(pin)
      until(addr == nil)
end

    getTemp()
    t1 = lasttemp / 10000
    t2 = (lasttemp >= 0 and lasttemp % 10000) or (10000 - lasttemp % 10000)
print("Temperature= " .. t1 .. "." .. string.format("%04d", t2) .. " Centigrade")
conn=net.createConnection(net.TCP, 0)
conn:on("receive", function(conn, payload) print(payload) end)
conn:connect(80,'184.106.153.149')
conn:send("GET /update?key=Yourey&field1=" .. t1 .. "." .. string.format("%04d", t2) .. " HTTP/1.1\r\n")
conn:send("Host: api.thingspeak.com\r\n")
conn:send("Accept: */*\r\n")
conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
conn:send("\r\n")
 
end)
User avatar
By Buggz
#6969 Thanks for your example code. Also "javeiry's" code inhttp://www.esp8266.com/viewtopic.php?f=19&t=1009&start=20

FYI I have used a DHT-22, the results are on Thingspeak, https://thingspeak.com/channels/20743#publicview

Dave

code for anyone who's interested:
Code: Select all    -- Retrieve data from DHT22 sensor

     -- Network stuff
     -- wifi.sta.config("YOURSSID","yourpw")
     
     
       
    -- Set pin
    pin = 4; 

    -- Initiliase bit data array
    bitCount = 39
    bitData = {}
    --Pre-allocate vars used in loop.
    for i = 0, bitCount, 1 do
         bitData[i] = 0
    end

    -- Set bitlength variable
    bitLength = 0
    retryCount = 0
    ackGoCnt = 0
    ackLoCnt = 0
    ackHiCnt = 0

    --Use Markus Gritsch trick to speed up read/write on GPIO
    gpio_read = gpio.read
    gpio_write = gpio.write

    -- Step 1 - Host send start signal and wait 1ms
    -- Set pin to output data
    gpio.mode(pin, gpio.OUTPUT)
    -- Send out start signal to DHT22, pull low
    gpio.write(pin, gpio.LOW)
    -- Wait specified time '1ms+'
    tmr.delay(20000)
    -- Host pull up output pin voltage and wait for sensors response
    gpio.write(pin, gpio.HIGH)

    -- Set pin to recieve data
    gpio.mode(pin, gpio.INPUT)

    -- Loop and wait for ACK pulse

    -- Tgo, typ 20 us
    --while (gpio_read(pin) == 1 and ackGoCnt < 100) do
    --     ackGoCnt = ackGoCnt + 1
    --end

    -- ACKlow - Trel, typ 80 us
    while (gpio_read(pin) == 0 and ackLoCnt < 100) do
         ackLoCnt = ackLoCnt + 1
    end

    -- ACKhi - Treh, typ 80 us
    while (gpio_read(pin) == 1 and ackHiCnt < 100) do
         ackHiCnt = ackHiCnt + 1
    end

    -- Step 2 - Read data stream
    -- Data recieved as 40 bits of data, 16 bits for humidity, 16 bits for temperature and 6 bits checksum
    -- Need to convert from binary to decimal and divide by 10
    for i = 0, bitCount, 1 do
         bitLength = 0
         --bus will always let up eventually, don't bother with timeout
         while (gpio_read(pin) == 0) do
         end
         -- Wait for DHT22 pin to pull high and set whether 0 or 1 bit value based upon length
         while (gpio_read(pin) == 1 and bitLength < 10) do
              bitLength = bitLength + 1
         end
         bitData[i] = bitLength
    end

    -- Re-initialise DHT22 pin
    gpio.mode(pin, gpio.OUTPUT)
    gpio.write(pin, gpio.HIGH)

    -- Using bit data calculate values for humidity, temperature and checksum
    -- Initialise variables
    humidity = 0
    temperature = 0
    rcheck = 0
    ccheck = 0

    -- First 4 bytes
    for i = 0, 3, 1 do
         dat = 0
         for j = 0, 7, 1 do
              if bitData[i*8 + j] > 2 then
                   dat = dat + 2^(7 - j)
              end
         end;
         if i == 0 then
              -- humidity high
              humidity = humidity + dat * 256
         elseif i == 1 then
              -- humidity low
              humidity = humidity + dat
         elseif i == 2 then
              -- temperature high
              temperature = temperature + dat * 256
         elseif i == 3 then
              -- temperature low
              temperature = temperature + dat
         end
         rcheck = rcheck + dat
    end

    -- When highest bit of temperature is '1' it means that temperature is below '0'
    if bit.isset(temperature, 15) then
       temperature = -bit.clear(temperature , 15)
    end
   

    -- Checksum low byte
    rcheck = rcheck % 256

    -- Last 8 bit - checksum
    for i = 0, 7, 1 do
         if bitData[32 + i] > 2 then
              ccheck = ccheck + 2^(7 - i)
         end
    end

    -- Check
    if rcheck == ccheck then
         print("Checksum: OK")
    else
         print("Checksum: fail [RX:", rcheck, "Calc:", ccheck, "]")
    end

    -- Output
    print("Temperature: "..(temperature/10).."."..(temperature%10))
    print("Humidity   : "..(humidity/10).."."..(humidity%10))

    Temp1="&field1="..(temperature/10).."."..(temperature%10)..""
    Hum1="&field2="..(humidity/10).."."..(humidity%10)..""
   
   
    -- create a WWW client
   
     conn=net.createConnection(net.TCP, 0)
     conn:on("receive", function(conn, payload) print(payload) end )
     conn:connect(80,"184.106.153.149")
     conn:send("GET /update?key="aaaaaaaa"..Temp1.. Hum1.." HTTP/1.1\r\n")
     conn:send("Host: api.thingspeak.com\r\n")
     conn:send("Accept: */*\r\n")
     conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
     conn:send("\r\n")
User avatar
By Tia
#7890 Hi there,

I modified your code a bit - unfortunately my DHT22 gives me some strange readings (almost on ever first try, a second try afterwards is returning valid values most of the time...)
(I used the DHT22 code from Javier Yanez as an additional lua-file)
(If I´m using the code from Buggz it is posting every time i execute the file, but it also is posting the readings if the checksum test failed...)

Code: Select all   -- Receive data from DHT22 and upload it to thingspeak.com
   
    -- Set data pin for DHT22
    pin = 4; 
   local apiKey = "AAAAAAAA"

   -- Retry 5 times
   for i = 1, 5 do
   
      dht22 = require("dht22")
      dht22.read(pin)
      t = dht22.getTemperature()
      h = dht22.getHumidity()

      -- temperature in degrees Celsius  and Farenheit
      print("Temperature: "..(t/10).."."..(t%10).." deg C")
      print("Temperature: "..(9 * t / 50 + 32).."."..(9 * t / 5 % 10).." deg F")

      -- humidity
      print("Humidity: "..(h/10).."."..(h%10).."%")

      -- release module
      dht22 = nil
      package.loaded["dht22"]=nil
            
      -- Check output
      if h ~= -1 then
         Temp1="&field1="..(t/10).."."..(t%10)..""
         Hum1="&field2="..(h/10).."."..(h%10)..""
         
         -- create a WWW client
         -- create a client/socket. TCP, normal link
         conn=net.createConnection(net.TCP, 0)
         
         -- register callback functions
         conn:on("receive", function(conn, payload)
            print("Callback: Receive")
            print("---------------------------------------------------------")
            print(payload)
            print("---------------------------------------------------------")
         end)
         conn:on("sent",function(conn)
            print("---------------------------------------------------------")
            print("Callback: Sent")
            print("---------------------------------------------------------")
         end)
         conn:on("connection",function(conn)
            print("---------------------------------------------------------")
            print("Callback: Connection")
            print("---------------------------------------------------------")
         end)
         conn:on("reconnection",function(conn)
            print("---------------------------------------------------------")
            print("Callback: Reconnection")
            print("---------------------------------------------------------")
         end)
         conn:on("disconnection",function(conn)
            print("---------------------------------------------------------")
            print("disconnection")
            print("---------------------------------------------------------")
         end)
         
         -- connect to remote (port, ip)
         conn:connect(80,"184.106.153.149")
         
         -- send data to remote via connection
         conn:send("GET /update?key="..apiKey..""..Temp1..""..Hum1.." HTTP/1.1\r\n")
         conn:send("Host: api.thingspeak.com\r\n")
         conn:send("Accept: */*\r\n")
         conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
         conn:send("\r\n")
         
         -- close socket
         conn:close()
         
         -- sent successful - break loop
         break
      else
         -- strange reading
          print("---------------------------------------------------------")
          print("Error reading DHT22. Wait 5 seconds.")
          print("---------------------------------------------------------")
          tmr.delay(5000000)
      end   
   
    end


I programmed a for loop to get 5 retries - if the DHT22 is returning a valid value it should post it to thingspeak and break the loop.
I also registered every possible callback function to get a more inside look of what ist going on there. (But none of those callback functions are being called...)

I (almost) always get a invalid reading in the first try and in the second one I get a valid reading, but it isn´t posting anything to the web?! None of my print statements (in the callback functions) is posting anything to the console (and also the payload from the receive-callback isn´t posted).

Heres what I get in my console: First reading - strange readings, waiting 2 seconds, correct readings, but nothing is getting posted to the web?!
Code: Select alldofile("dht22_speak2.lua")
Temperature: -3277.3 deg C
Temperature: -5867.9 deg F
Humidity: -1.9%
---------------------------------------------------------
Error reading DHT22. Wait 5 seconds.
---------------------------------------------------------
Temperature: 22.4 deg C
Temperature: 72.3 deg F
Humidity: 49.0%
>


Could you help me with that? Is there anything I am doing completely wrong with my code?!


Best regards

EDIT:
If rewritten my program and tried a different approach. I simply rescheduled the program when I received strange readings and if the readings are okay, I can upload them... This way it just works fine.