• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

Victor

Administrator
Команда форума
Не совсем корректно сформулировал. Мне нужна связка uart<--> tcp server. Двусторонняя. Проблема в том, что Arduino подключается просто к esp8266, а вот PIC завести с ней через uart и AT команды - целая проблема. Поэтому хочу максмально упростить обмен.
Давайте уж совсем подробно, а то не очень понятно
 

Alex Sedov

New member
Давайте уж совсем подробно, а то не очень понятно
У меня есть PIC24, esp8266, планшет. мне нужно организовать управление PIC'ом через wi-fi. Я на esp поднимаю TCP сервер, на планшете стоит клиент. Идея проста - PIC принимает 32 команды, по 33 команде - должен отправить строку. формат команды - число от 1 до 33.
Если работать через прошивку с AT-командами, то получается большой объем данных, т.к. PIC плохо читает строки по uart и приходиться вычитывать все побайтно. Поэтому, для упрощения, я хочу сделать прошивку для esp, которая :
1) поднимает точку доступа;
2) поднимает сервер;
3) передает от клиента в uart команды PIC'у в формате 1..33.
4) если в порт приходит строка известной длины - отправляет ее клиенту.
Первые два пункта решены. а вот дальше - не получается.
 

Victor

Administrator
Команда форума
хочу сделать прошивку для esp
Если вы хотите написать свою прошивку, то лучше попросить помощи в другой теме - здесь обсуждаются только скрипты на LUA для NodeMCU
Если же вы хотите написать скрипт на lua, тогда ок.
По п.3. В NodeMCU есть команда, которая задает функцию, которая вызывается, когда приходят данные серверу по WiFi (если сервер HTTP, то подразумевается, что приходит GET запрос)
вот пример https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru#Пример-65
в примере print - это как раз отправка в UART, т.е. если к UART подключен PIC, то это то, что вам нужно.
Для 4. В NodeMCU есть команда, которая задает функцию, которая вызывается, когда приходят данные по UART (в вашем случае это PIC)
https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru#uarton
в примере вместо print нужно выставить какой-то флаг (например присвоить переменной какое-то значение, создать файл и т.п.)
Теперь с планшета можем отправить запрос, чтобы узнать состояние этого флага.
Таким образом не нужно будет в ответе от PIC посылать данные клиенту, хотя и это можно реализовать, если в п.3 опрашивать состояние флага
Как то так. Причем я уверен, что это не единственное решение, и далеко не самое лучшее. Можете создать отдельную тему в этом разделе, выложить схему, скрипты и, наверняка, найдутся еще люди, которые смогут вам помочь. Так же вполне возможно, что за выходные и в этой теме появятся еще ответы - вы же наконец-то сформулировали конкретнее, чего вы хотите.
 

xopek

New member
Здравия желаю,
Я в луа особо не силен, но все же. Взял вот это\это для DHT22 и пример прерывания от LuaLoader
Получилось вот такое
И оно не работает. Ошибка вываливается при попытке запросить страничку.
Ошибка:
PANIC: unprotected error in call to Lua API (error loading module 'dht22' from file 'dht22.lua':
not enough memory)

Подскажите, пожалуйста, в чем проблема.
 
Последнее редактирование:

nikolz

Well-known member
копируете это и записываете в ESP
http://esp8266.fancon.cz/common/monDHT22.lua
-----------------------------------
копируете это и записываете в ESP
http://esp8266.fancon.cz/common/dht22.lua
Если в ESP имя файла у вас будет большими буквами т е DHT22.lua
то в файле monDHT22.lua исправьте строку:
dht22 = require("dht22") на dht22 = require("DHT22")
----------------------
после запуска monDHT22.lua у меня выводится (датчик подключен AM2302)
> dofile('monDHT22.lua')
Humidity: -0.1.9%
Temperature: 25.8.8.0000000000002 deg C
Temperature: 78.44.4.4000000000003 deg F
 

nikolz

Well-known member
если заменить "." на ";" здесь
humi=(h/10)..";"..(h%10)
temp=(t/10)..";"..(t%10)
то будет красивее:
-------------------------------------
Humidity: -0.1;9%
Temperature: 26.3;3.0000000000002 deg C
Temperature: 79.34.3.4000000000003 deg F
> Humidity: -0.1;9%
Temperature: 26.1;1.0000000000002 deg C
Temperature: 78.98.9.8000000000003 deg F
Humidity: -0.1;9%
Temperature: 26.1;1.0000000000002 deg C
Temperature: 78.98.9.8000000000003 deg F
 

nikolz

Well-known member
этот драйвер неправильно работает с AM2302.
моя программа дает такие результаты
25.5625; 25.8125 --это температура двух датчиков DS
26; 20.6 -- это температура и влажность с датчика AM2302.
если датчик AM2302 накрыть пальцем то получим
26.4;37
26.7;41.2
26.9;46.8
т е температура и влажность растут
 

nikolz

Well-known member
что-то я не вижу сообщение об ошибке.
--------------------------------------------------
невозможно найти в темной комнате черную кошку, если ее там нет.
 

xopek

New member
Вот же:
PANIC: unprotected error in call to Lua API (error loading module 'dht22' from file 'dht22.lua':
not enough memory)
 

nikolz

Well-known member
разделяйте программу на части,
пишите части в отдельные файлы
и исполняйте части оператором dofile()
 

Victor

Administrator
Команда форума
Совет от разработчиков NodeMCU после старта определять есть ли скомпилированная версия
Код:
if file.open("user.lc") then
   file.close()
   dofile("user.lc")
else
   dofile("user.lua")
end
и более подробная версия
Код:
--init.lua, updated.
countdown = 3
tmr.alarm(0,1000,1,function()
print(countdown)
countdown = countdown-1
if countdown<1 then
tmr.stop(0)
countdown = nil
local s,err
if file.open("user.lc") then
file.close()
s,err = pcall(function() dofile("user.lc") end)
else
s,err = pcall(function() dofile("user.lua") end)
end
if not s then print(err) end
end
end)
 
Последнее редактирование:

nikolz

Well-known member
Разрезал программу на 12 частей.
В результате собрал датчики DS ( 3 шт ),AM2302,BMP180 HC-SR04 и веб сервер.
 

TRO

Member
разделяйте программу на части,
пишите части в отдельные файлы
и исполняйте части оператором dofile()
Дайте пожалуйста примерчик как передавать этим частям данные и получать обратно.
А то планы наполеоновские, а в однойм фале и пятой части функионала реализовать немогу.
 

nikolz

Well-known member
Пример обычно иллюстрация к знаниям На одном примере нельзя научить.
Но могу показать результат.
Выложите свою какую-нибудь программу, для которой не хватает место.
(Весь план ватерлоо просьба не выкладывать).
Покажу результат.
 

Victor

Administrator
Команда форума
как передавать этим частям данные и получать обратно
передать аргументы можно так
arg.lua
Код:
return function (arg)
print("Argument:"..arg)
end
затем
Код:
dofile("arg.lua")(100)
dofile("arg.lua")("ARG")
Файл arg.lua возвращает тип function, а когда мы делаем dofile("arg.lua")(100) происходит как бы макроподстановка.
получаем в итоге
Код:
Argument:100
Argument:ARG
 

Victor

Administrator
Команда форума
ах да, еще вариант в условиях дефицита памяти
Код:
f=dofile("arg.lua")
f(100)
f("test")
f=nil
ну или
Код:
local f=dofile("arg.lua")
f(100)
f("test")
 

nikolz

Well-known member
Данные(переменные массивы) определяете как глобальные.
Т е все фрагменты получают автоматом к ним доступ.
чтобы данные были глобальными не надо перед ними ставит слово local.
 

TRO

Member
Спасибо, не думал что кускам доступны глобальные переменные из основного кода.
Мне в принципе нужно в кусках выбирать внешним мультиплексором аналоговый канал, опрашивать АЦП десяток раз, и суммировать результат в глобальную переменную.
И вывод результатов в HTML тоже хочу в отдельные куски разбить, а то для вывода в тексте вроде укладываюсь, а осцилограммы и шкалы в векторном SVG рисовать уже в один файл никак не лезет.

И еще, когда использую прерывания по внешнему сигналу,
Код:
tt1 = 0
gpio.mode(6, gpio.INT)
gpio.trig(6, "both",function()
tt1 = tt1 + 1
end)
в функци которого только одна строкака добавляющая единицу к счетчику, а потом в односекундном прерывании считываю этот счетчик и обнуляю (типа частотомер)
Код:
tmr.alarm(1, 1000, 1, function()
sp1=tt1
tt1=0
--  еще пользовательский код
end)
, то модуль частенько вешается когда частоту на этот вход подаю. Но частотомер все равно нужен (до 300Гц), подумываю уже добавлять внешний контроллер для этого, а так хотелось обойтись только модулем.
 
Последнее редактирование:
Сверху Снизу