• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 и перезагрузка. Что с этим можно сделать? Вроде в постах встречал, что это кривая прошивка, но не ужели никто не сталкивался с этой проблемой и не решал?
 
Сверху Снизу