Post your best Lua script examples here

User avatar
By Pigs Fly
#6857 Very cool, thanks javiery. Alas I think the captain of the boat bringing my DHT22's must have been smoking some of our Colorado State Flower and forgotten where he was going. I'm ordering more of them and anxiously await a chance to try your revisions.

Not sure what to think about the checksum calc. In the data sheet for the '11 it said to sum the parts and take the LSB as the checksum, and while I'm no programming expert, that seems to imply a mask of 0xff to get the LSB of the sum. Maybe the '22 is different. I have to respect anything that works, so thanks for that.
User avatar
By alko
#6895 Highest bit of temperature is '1' it means that temperature is below '0'.

Code: Select allif bit.isset(temperature, 15) then
     temperature = -bit.clear(temperature , 15)
end
User avatar
By alko
#6898 Its my variant for DHT22, based on Pigs Fly code. On my ESP-01 work more stability when by javiery. Main differences - read init pulse and data bits as datasheet specified.

Code: Select all-- Retrieve data from DHT22 sensor

-- 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))

User avatar
By javiery
#6903
Pigs Fly wrote:Very cool, thanks javiery. Alas I think the captain of the boat bringing my DHT22's must have been smoking some of our Colorado State Flower and forgotten where he was going. I'm ordering more of them and anxiously await a chance to try your revisions.

:D The captains who bring things to Spain should also have started smoking, everything takes a lot lately

Pigs Fly wrote:Not sure what to think about the checksum calc. In the data sheet for the '11 it said to sum the parts and take the LSB as the checksum, and while I'm no programming expert, that seems to imply a mask of 0xff to get the LSB of the sum. Maybe the '22 is different. I have to respect anything that works, so thanks for that.

Note that the % operator refers to the modulo operation (http://en.wikipedia.org/wiki/Modulo_operation). To get the LSB with a mask of 0XFF you need a "and" operator.

A trivial example:

256 in binary is 0000000100000000
then MSB = 00000001 and LSB = 00000000

Using NodeMCU Lua Interpreter:
Code: Select all> print(bit.band(256,0xFF))
0
> print(256%256)
0
> print(256%0xFF)
1


The expected result is 0. The first two methods give a correct result the third is incorrect. 0xFF is almost as 256, the result may be the same in many cases, but not all.