• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Lua скрипты и модули

skylocker

Member
У меня модуль ds18b20.lua имеет размер 560 байт,
вместо указанного Вами из примера: ds18b20.lua size: 3437 байт.
------------------------------------------------
Кроме того, программа в примере задерживает работу процессора на 750 ms для готовности датчика
У меня задержки нет, а на опрос датчиков dS тратится 40 ms (сейчас датчиков три).
Чем хвастаться, лучше поделитесь своей виртуозностью со страждущими :)
 
boka17,
Уменьшить размер можно удалив все строки комментарии и убрав куски, связанные с расчетом температуры в фаренгейтах и кельвинах (надеюсь вам не надо). Еще можно убрать пробелы, табуляции и переводы строк. Это никак не повлияет на функциональность.
nikolz,
И это при ПОЛНОМ сохранении функционала и ВСЕХ проверок, как в оригинале? Если съежить функционал и убрать все проверки которые есть в оригинале - то оно конечно...
ВСЕМ, кто может ответить.
Задавал этот вопрос, но ответа нет. Размер .lc файла может быть больше размера .lua файла. Это как???
 

nikolz

Well-known member
вот пример из примеров разработчиков web сервера :
----------------------
collectgarbage()
srv=net.createServer(net.TCP) srv:listen(80,function(conn)
conn:eek:n("receive",function(conn,payload)
--print(payload) -- for debugging only
--generates HTML web site
conn:send('HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nCache-Control: private, no-store\r\n\r\n\
<!DOCTYPE HTML>\
<html><head><meta content="text/html;charset=utf-8"><title>ESP8266</title></head>\
<body bgcolor="[HASHTAG]#ffe4c4[/HASHTAG]"><h2>Hygrometer with<br>DHT22 sensor</h2>\
<h3><font color="green">\
<IMG SRC="http://esp8266.fancon.cz/common/hyg.gif"WIDTH="64"HEIGHT="64"><br>\
<input style="text-align: center"type="text"size=4 name="j"value="'..TEMP[2]..'"> Temperature grade<br><br>\
<IMG SRC="http://esp8266.fancon.cz/common/tmp.gif"WIDTH="64"HEIGHT="64"><br>\
<input style="text-align: center"type="text"size=4 name="p"value="'..TEMP[1]..'"> Temperature grade C<br>\
<input style="text-align: center"type="text"size=4 name="p"value="'..TT..'"> время</font></h3>\
<IMG SRC="http://esp8266.fancon.cz/common/dht22.gif"WIDTH="200"HEIGHT="230"BORDER="2"></body></html>')
conn:eek:n("sent",function(conn) conn:close() end)
end)
end)
------------------
я его тестил под именем "srv_1.lua" вот в такой программе:
----------------------------
dofile("nk_start.lc")
print("1="..collectgarbage("count")..">"..node.heap());
collectgarbage()
function cb()
collectgarbage()
if ip==nil then dofile("wifi_1.lua") end
print("2="..collectgarbage("count")..">"..node.heap());
if ip~=nil and is==nil then
dofile("srv_1.lua");
is=1;
end
print("3="..collectgarbage("count")..">"..node.heap());
dofile("cbAM2302.lc");
print("4="..collectgarbage("count")..">"..node.heap());
dofile("cb18b20.lua");
print("5="..collectgarbage("count")..">"..node.heap());
dofile("get_tp.lc"); dofile("norm.lc");
print("6="..collectgarbage("count")..">"..node.heap());
end
tmr.alarm(3,5000,1,cb)
 

CatFromSummer

New member
Доброго времени суток!
Имеется ESP-01 + AM2302(DHT22) подключенные на мекетной плате с модулем питания YwRobot. С компьютером их связывает USB2TTL CH340G.
ESP-01 прошито NodeMCU 0.9.6 build 20150704 Lua 5.1.4.
Для опроса сенсора использую библиотеку из репозитория NodeMCU:
Код:
-- ***************************************************************************
-- DHTxx(11,21,22) module for ESP8266 with nodeMCU
--
-- Written by Javier Yanez mod by Martin
-- but based on a script of Pigs Fly from ESP8266.com forum
--
-- MIT license, http://opensource.org/licenses/MIT
-- ***************************************************************************

--Support list:

--DHT11 Tested
--DHT21 Not Test yet
--DHT22(AM2302) Tested
--AM2320 Not Test yet

--Output format-> Real temperature times 10(or DHT22 will miss it float part in Int Version)
--==========================Module Part======================
local moduleName = ...
local M = {}
_G[moduleName] = M
--==========================Local the UMI and TEMP===========
local humidity
local temperature
--==========================Local the bitStream==============
local bitStream = {}

---------------------------Read bitStream from DHTXX--------------------------
local function read(pin)

  local bitlength = 0
  humidity = 0
  temperature = 0

  -- Use Markus Gritsch trick to speed up read/write on GPIO
  local gpio_read = gpio.read
 
 
  for j = 1, 40, 1 do
    bitStream[j] = 0
  end

  -- Step 1:  send out start signal to DHT22
  gpio.mode(pin, gpio.OUTPUT)
  gpio.write(pin, gpio.HIGH)
  tmr.delay(100)
  gpio.write(pin, gpio.LOW)
  tmr.delay(20000)
  gpio.write(pin, gpio.HIGH)
  gpio.mode(pin, gpio.INPUT)

  -- Step 2:  Receive bitStream from DHT11/22
  -- bus will always let up eventually, don't bother with timeout
  while (gpio_read(pin) == 0 ) do end
  local c=0
  while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
  -- bus will always let up eventually, don't bother with timeout
  while (gpio_read(pin) == 0 ) do end
  c=0
  while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end

  -- Step 3: DHT22 send data
  for j = 1, 40, 1 do
    while (gpio_read(pin) == 1 and bitlength < 10 ) do
      bitlength = bitlength + 1
    end
    bitStream[j] = bitlength
    bitlength = 0
    -- bus will always let up eventually, don't bother with timeout
    while (gpio_read(pin) == 0) do end
  end
end

---------------------------Check out the data--------------------------
----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3] -------
---------------Which is empty when using DHT11-------------------------
function M.read(pin)
  read(pin)

  local byte_0 = 0
  local byte_1 = 0
  local byte_2 = 0
  local byte_3 = 0
  local byte_4 = 0

  for i = 1, 8, 1 do -- Byte[0]
    if (bitStream[i] > 3) then
      byte_0 = byte_0 + 2 ^ (8 - i)
    end
  end

  for i = 1, 8, 1 do -- Byte[1]
    if (bitStream[i+8] > 3) then
      byte_1 = byte_1 + 2 ^ (8 - i)
    end
  end

  for i = 1, 8, 1 do -- Byte[2]
    if (bitStream[i+16] > 3) then
      byte_2 = byte_2 + 2 ^ (8 - i)
    end
  end

  for i = 1, 8, 1 do -- Byte[3]
    if (bitStream[i+24] > 3) then
      byte_2 = byte_2 + 2 ^ (8 - i)
    end
  end

  for i = 1, 8, 1 do -- Byte[4]
    if (bitStream[i+32] > 3) then
      byte_4 = byte_4 + 2 ^ (8 - i)
    end
  end


  if byte_1==0 and byte_3 == 0 then
  ---------------------------Convert the bitStream into Number through DHT11's Way--------------------------
  --As for DHT11 40Bit is consisit of 5Bytes
  --First byte->Humidity Data's Int part
  --Sencond byte->Humidity Data's Float Part(Which should be empty)
  --Third byte->Temp Data;s Intpart
  --Forth byte->Temp Data's Float Part(Which should be empty)
  --Fifth byte->SUM Byte, Humi+Temp

    if(byte_4 ~= byte_0+byte_2) then
     humidity = nil
     temperature = nil
    else
     humidity = byte_0 *10 -- In order to universe with the DHT22
     temperature = byte_2 *10
    end

  else ---------------------------Convert the bitStream into Number through DHT22's Way--------------------------
  --As for DHT22 40Bit is consisit of 5Bytes
  --First byte->Humidity Data's High Bit
  --Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement)
  --Third byte->Temp Data's High Bit
  --Forth byte->Temp Data's Low Bit
  --Fifth byte->SUM Byte

  humidity = byte_0 * 256 + byte_1
  temperature = byte_2 * 256 + byte_3
  checksum = byte_4

  checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8))
  checksumTest = bit.band(checksumTest, 0xFF)

  if temperature > 0x8000 then
    -- convert to negative format
    temperature = -(temperature - 0x8000)
  end

  -- conditions compatible con float point and integer
  if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then
    humidity = nil
  end

  end

   byte_0 = nil
   byte_1 = nil
   byte_2 = nil
   byte_3 = nil
   byte_4 = nil

end
--------------API for geting the data out------------------

function M.getTemperature()
  return temperature
end

function M.getHumidity()
  return humidity
end
-------------Return Index------------------------------------
return M
Там же взят и тестовый код:
Код:
PIN = 4 --  data pin, GPIO2

DHT= require("dht_lib")

DHT.read(PIN)

t = DHT.getTemperature()
h = DHT.getHumidity()

if h == nil then
  print("Error reading from DHT11/22")
else
  -- temperature in degrees Celsius  and Farenheit
  -- floating point and integer version:

  print("Temperature: "..(t/10).." deg C")
  print("Temperature: "..(9 * t / 50 + 32).." deg F")

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

-- release module
DHT = nil
package.loaded["dht_lib"]=nil
Проблема - либо выдается ошибка что неверное чтение с сенсора, либо очень редко нереальные данные. :eek:
Датчик проверял в том же положении на том же питании с Arduino - ошиок нет и показания вполне в пределах нормы. Порт ESP так же проверял - читает и пишет нормально.
Где может быть косяк в коде, железе или там и там? Есть у кого 100% рабочий код для AM2302?
 

nikolz

Well-known member
Могу предложить один из своих вариантов программы для работы с этим датчиком (байт код)
помещаете файл на ESP
-------------------------------------------
вот так выглядит главная программа main:
выкидываете то,что вам не надо
--------------------------
pds=1;pam=2; scl=4; oss=0;T0=0;TM=0; adT={}
gpio.mode(pam, gpio_OUTPUT); gpio.write(pam, gpio.HIGH)
--DS18B20--AM2302--BMP180(SCL,SDA=SCL+1)
local ae={{96,209,111,6,0,0,149},{199,186,111,6,0,0,45}} -- это таблица адресов DS
------1--2--3--4-5--6-7--8-9-10-11-12-13-14-
TD={3,0,0,0,2,0,0,4,0,0, 0,0,1, 0};
--------------------
function cb()
m=1
dofile('nkDS.lc');
m=6 -- номер позиции в таблице TD результатов для данного датчика
dofile('cb2302.lc'); - в результате TD[7] -t TD[8] -h
m=9 -- номер позиции в таблице TD результатов для данного датчика
dofile('get_tp.lc');
m=14 -- номер позиции в таблице TD результатов для данного датчика
TD[m]=adc.read(0);
print(table.concat(TD,";"));
end
tmr.alarm(1,2000,1,cb)
----------------------------------
делал давно, как есть.
 

Вложения

  • 716 байт Просмотры: 39

VelAndr

New member
Здравствуйте!
А как правильно использовать в nodemcu дату и время?
В свежей сборке появился модуль sntp.sync(), который возвращает timestamp. А что потом с ним делать? Ведь в njdemcu отсутствуют модули os.date и os.time...
 

nikolz

Well-known member
А как правильно использовать в nodemcu дату и время?
В свежей сборке появился модуль sntp.sync(), который возвращает timestamp. А что потом с ним делать? Ведь в njdemcu отсутствуют модули os.date и os.time...
----------------------
Посмотрите это :
http://www.esp8266.com/viewtopic.php?f=19&t=938
https://github.com/annejan/nodemcu-lua-watch
http://richard.burtons.org/2015/04/23/real-time-clock-ds1307ds3231-for-the-esp8266/
http://geektimes.ru/post/267718/
 
Последнее редактирование:

Cadil

New member
Здравствуйте!
Собрал термометр на DS18B20+ESP8266. Залитые в ESP8266 скрипты Lua читают и отправляют информацию с термодатчика на удаленный сайт. Хотелось бы исключить из этой цепочки удаленный сервер и выводить температуру на локальный веб сервер.
Пытаюсь это сделать по такому скрипту:
Код:
-- чтение температуры
gpio = 4
require('ds18b20')
ds18b20.setup(gpio)
function sendData()
t=ds18b20.read()
print("Temp:"..t.." C\n")
-- connection to SERVER
wifi.setmode(wifi.STATION)
wifi.sta.config("VB","EG4P5BMHTQ")
print(wifi.sta.getip())
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on("receive",function(conn,payload)
    print(payload)
  --  conn:send("<h1> test_2 </h1>")
   conn:send("<h1> "..t.." </h1>")
    conn:close()
    end)
end)
-- send data every 60000 ms to thing speak
tmr.alarm(0, 6000, 1, function() sendData() end )
Код сервера сам по себе компилируется, а с добавлением кода чтения температуры ESPlorer выдает ошибку -
init.lua:24: 'end' expected (to close 'function' at line 5) near '<eof>'

Помогите найти ошибки в скрипте. Заранее благодарю за помощь.
 

nikolz

Well-known member
gpio = 4
require('ds18b20')
ds18b20.setup(gpio)
function sendData()
t=ds18b20.read()
print("Temp:"..t.." C\n")
-- connection to SERVER
wifi.setmode(wifi.STATION)
wifi.sta.config("VB","EG4P5BMHTQ")
print(wifi.sta.getip())
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:eek:n("receive",function(conn,payload)
print(payload)
-- conn:send("<h1> test_2 </h1>")
conn:send("<h1> "..t.." </h1>")
conn:close()
end)
end)
end
-- send data every 60000 ms to thing speak
tmr.alarm(0, 6000, 1, function() sendData() end )
 

Cadil

New member
gpio = 4
....
-- send data every 60000 ms to thing speak
tmr.alarm(0, 6000, 1, function() sendData() end )
Вы даже не представляете, как я благодарен за оказанную помощь. Не могу подобрать слов. Код успешно компилируется - IP-адрес, температура отображаются в окне ESPlorer'a.
А вот с веб браузером - проблемы. При подключении к IP-адресу - "Попытка соединения не удалась" или - "Время ожидания истекло". Ели нажимать кнопку браузера ОБНОВИТЬ, то температура иногда выводится.
Как программно решить эту проблему?
 

nikolz

Well-known member
Добрый день,
я давно делал сбор данных с датчиков на ESP.
При сборе по TCP возникала утечка памяти.
Все реализовал на UDP.
----------------------
Могу лишь дать совет посмотреть в сторону UDP.
Это более простой и более быстрый способ сбора данных при хороших каналах.
 

Cadil

New member
Добрый день,
я давно делал сбор данных с датчиков на ESP.
При сборе по TCP возникала утечка памяти.
Все реализовал на UDP.
Спасибо за совет.
Но не хочется бросать начатое на полпути. В скрипте, составленном чайником, вы без труда нашли ошибки (я о [HASHTAG]#211[/HASHTAG]). Поэтому, думаю, подправить скрипт, чтобы сервер работал корректно, вам не составит большого труда.
Подскажите, хотя бы - где копать?
 

Cadil

New member
Не могу найти скрипты на LUA для схем с ADC (АЦП). Кому такие встречались - сбросьте линк!
 
Последнее редактирование:

Lioplay

New member
Добрый день.
Пытаюсь подключить датчик BH1750 (GY-302) к WeMos D1 R2. Прошит прошивкой nodemcu_integer_0.9.6-dev_20150704.bin
Для получения данных использую стандартный код с github - nodemcu-firmware/lua_modules/bh1750 at master · nodemcu/nodemcu-firmware · GitHub
При запуске скрипта выдает "PANIC: unprotected error in call to Lua API (bad argument #2 to 'write' (string expected, got nil))" и перезагружается. При сохранении модуля dh1750 выдает такое сообщение "bh1750.lua:11: table index is nil" (11 строка это _G[moduleName] = M)
Подскажите что может быть и как это исправить, так как никаких других скриптов для съема показаний с этого датчика так и не нашел.
P.S. кто нибудь пробовал подключать к esp8266 с прошивкой NodeMCU такой экранчик 2.4 " 240 x 320 SPI TFT LCD серийный порта модуля 3.3 В кпб адаптер SD ILI9341 купить на AliExpress
 
Последнее редактирование:

Vid152

New member
Добры вечер,
Прошу прощения, если задам не корректный вопрос. Нужна помощь асов Lua. Бьюсь который день со стандартной библиотекой ds18b20 с примеров. Прочитал форумы и похожие примеры, но ответа не нашел.
Проблема:
1. Нужно мерять порядка 5 термометров и по определенной логике переключать gpo.
2. Паралельно хотел выдавать на thinkspeak данные для мониторинга.
3. При выводе одгоно значения на сайт проблем нет, как только в программе появляеться несколько измеряемых подряд значений температуры значения не выдаються.
4. Пробовал советы знатоков с уменьшением программы, обнуление переменных без результатно.
При этом в сети масса примеров с несколькими значениями Т и вроде работает. TCP сервер работает нормально. Не понимаю в чем дело.
Поможет кто?
 

nikolz

Well-known member
Добры вечер,
Прошу прощения, если задам не корректный вопрос. Нужна помощь асов Lua. Бьюсь который день со стандартной библиотекой ds18b20 с примеров. Прочитал форумы и похожие примеры, но ответа не нашел.
Проблема:
1. Нужно мерять порядка 5 термометров и по определенной логике переключать gpo.
2. Паралельно хотел выдавать на thinkspeak данные для мониторинга.
3. При выводе одгоно значения на сайт проблем нет, как только в программе появляеться несколько измеряемых подряд значений температуры значения не выдаються.
4. Пробовал советы знатоков с уменьшением программы, обнуление переменных без результатно.
При этом в сети масса примеров с несколькими значениями Т и вроде работает. TCP сервер работает нормально. Не понимаю в чем дело.
Поможет кто?
Что конкретно ?
Если ошибка в проге, то выкладывайте текст, если не знаете, как написать алгоритм, то напишите задачу.
год назад на LUA подключал 3 датчика температуры и выдавал по UDP на свой серевер.
 

Vid152

New member
nikolz Спасибо за ответ. Похоже сам разобрался с этим удивительным ресурсом thingspeak! Там особенность в передаче данных, нужна задержка в 20 секунд. Все работает.
 

Vid152

New member
nikolz Спасибо за ответ. Похоже сам разобрался с этим удивительным ресурсом thingspeak! Там особенность в передаче данных, нужна задержка в 20 секунд. Все работает.
Что конкретно ?
Если ошибка в проге, то выкладывайте текст, если не знаете, как написать алгоритм, то напишите задачу.
год назад на LUA подключал 3 датчика температуры и выдавал по UDP на свой серевер.
nikolz
Нужна помощь.
Написал простой сервер TCP srv=net.createServer(net.TCP) srv:listen(80, function(conn) и далее как обычно. Сервер должен работать постоянно под tmr.alarm c опросом раз в 5 сек. Но возникла проблема с heap. С каждым обращением к listen память уменьшается на 152 байта, доходит до 6000 и перезагрузка. Что с этим можно сделать? Вроде в постах встречал, что это кривая прошивка, но не ужели никто не сталкивался с этой проблемой и не решал?
 
Сверху Снизу