ESP-8266/ESP32 NodeMCU Lua: азы программирования.

Тема в разделе "ESP8266, ESP32", создана пользователем ИгорьК, 25 июл 2017.

  1. bor1andrey@gmail

    bor1andrey@gmail Нерд

    Все так. Переделал, взлетело, благодарю. Я просто по старинке воспринимаю коллбеки как обработчики прерываний, и соответственно, делаю там лишь необходимый минимум.
     
    ИгорьК нравится это.
  2. obuhanoe

    obuhanoe Гик

    Подскажите, куда данный код нужно встроить? Под esp32 перепишу.
    На данный момент получаю ошибку при работе esp32 модуля http и хочу понять почему появляется плавающая ошибка, да еще и для меня не значащая.
    Код (Text):
    Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

    Core  0 register dump:
    PC      : 0x400e98f0  PS      : 0x00060830  A0      : 0x800e9c44  A1      : 0x3ffbb310
    A2      : 0x3ffc2154  A3      : 0x3ffcccd4  A4      : 0x3ffcccf4  A5      : 0x00000003
    A6      : 0x00000005  A7      : 0x00000040  A8      : 0x800e9900  A9      : 0x3ffbb2f0
    A10     : 0x00000004  A11     : 0xfffffffe  A12     : 0x00000009  A13     : 0x0000ff00
    A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x00000020  EXCCAUSE: 0x0000001c
    EXCVADDR: 0x00000003  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffd

    Backtrace:0x400e98ed:0x3ffbb3100x400e9c41:0x3ffbb340 0x400e9fa7:0x3ffbb370 0x400e6786:0x3ffbb390 0x400ea080:0x3ffbb3c0 0x400ec436:0x3ffbb3e0 0x400ea57a:0x3ffbb410 0x400e7b0e:0x3ffbb470 0x400e7bb5:0x3ffbb500 0x400e8132:0x3ffbb530 0x400e84c5:0x3ffbb570 0x400e592d:0x3ffbb590 0x400e7d19:0x3ffbb5b0 0x400e85d2:0x3ffbb630 0x400e646e:0x3ffbb660 0x400ea1c6:0x3ffbb690 0x400df205:0x3ffbb6b0 0x400f52cd:0x3ffbb6d0 0x400d78b7:0x3ffbb700 0x401895f7:0x3ffbb720

    ELF file SHA256: 6fcaa6c47ac702bc

    Rebooting...
    ets Jun  8 2016 00:22:57
     
  3. ИгорьК

    ИгорьК Гуру

    upload_2023-1-19_15-27-45.png
    Когда ловится такая ошибка, лучший способ борьбы с ней - "обойти" тот участок кода, который ее вызывает, Это не ошибка кода - ошибка разработчиков.
     
  4. obuhanoe

    obuhanoe Гик

    А что в Вашем понимании значит обойти?
    Разработчиков ESP или ошибка моя все таки?
     
  5. ИгорьК

    ИгорьК Гуру

    Это ошибка разработчиков nodeMcu.

    Это зависит от ситуации. Зачастую задачу можно решить другим способом. Я с таким сталкивался очень давно именно с ESP32 и удавалось переписать код чтобы такая ошибка не вылезла. Но пример не приведу.
     
    obuhanoe нравится это.
  6. serg3295

    serg3295 Гуру

    Вызывается как обычная функция. Если нужно время наступления события для записи в файл, то вызывается где-нибудь в начале программы после получения времени от NTP сервера. Например, вот так:
    Код (C++):
    local function getTime()
      sntp.sync(ntp_server, function ()
          catchErr()
        end, function ()
          catchErr()
      end)
    end
     
    Естественно, функция необязательна. Можно просто вставить код в начале программы, но тогда надо будет решать вопрос с подстановкой реального времени. Вот пример файлов с устройства где-то за год его работы.
    Код (C++):
    07:05:17 4,0,0,0,0,0,0
    03:00:00 0,0,0,0,0,0,0
    03:00:00 2,9,1076075591,0,0,1970237061,0
    12:26:00 0,0,0,0,0,0,0
    14:06:28 0,0,0,0,0,0,0
    14:16:24 0,0,0,0,0,0,0
    03:00:00 0,0,0,0,0,0,0
    16:24:47 0,0,0,0,0,0,0
    12:55:23 0,0,0,0,0,0,0
    12:11:23 0,0,0,0,0,0,0
    11:38:23 0,0,0,0,0,0,0
    19:52:15 2,29,1073799012,0,0,0,0
    18:57:43 0,0,0,0,0,0,0
    13:35:46 0,0,0,0,0,0,0
    12:25:25 0,0,0,0,0,0,0
    11:25:06 0,0,0,0,0,0,0
    03:00:00 3,0,0,0,0,0,0
    23:12:14 2,9,1076075591,0,0,1970237061,0
    12:42:50 0,0,0,0,0,0,0
    03:00:00 0,0,0,0,0,0,0
    15:30:04 0,0,0,0,0,0,0
     
    Код (C++):
    ERROR out of memory
    ERROR out of memory
     
    Как видите, какой-то волшебной информации, которая сразу бы решила вашу проблему, вы там не найдёте. Кроме причин рестарта есть еще разнообразные цифры, значение которых можно посмотреть вот здесь (собственно, вы это в красивом виде и получили), но для их интерпретации необходимо иметь код прошивки для отладки. То есть, справочно.
    С функцией node.setonerror возможностей побольше. При аварии в callback в файл будет записано информационное сообщение перед рестартом esp'шки. Для проверки на ESP32 введём в Esplorer'e:
    Код (C++):
    -- Регистрируем функцию
    node.setonerror(function(s)
        fh = io.open("err.txt",  "a+")
        fh:write('\nERROR '..s)
        fh:close()
        node.restart()
      end)

    -- И проверяем
    tmr.create():alarm(1000,0, function() g() end)
     
    На выходе получим файл err.txt с содержимым
    Код (C++):
    ERROR stdin:1: attempt to call a nil value (field 'g')
    stack traceback:
        stdin:1: in function <stdin:1>
     
    Да, и при подключенном COM совсем необязательно писать в файл, можно просто print(s)
    Таким образом, использование функций node.bootreason и node.setonerror удобно если ваше устройство уже где-то стоит и работает. Тогда, если происходят непонятные сбои в работе устройства, то просмотр записанных файлов может помочь при поиске ошибки. По-крайней мере выяснить причину рестарта и, возможно, тип exception'a. Если же устройство подключено к COM'у, то возможностей для отладки имеется гораздо больше.
     
    ИгорьК и obuhanoe нравится это.
  7. obuhanoe

    obuhanoe Гик

    Нашел место где происходит ошибка.
    Код (Text):
    local connect = http.createConnection(curl, http.GET, {headers = {Connection = "close"}})

    connect:on("data", function(code, data)          
                catchErr()      
    end)

    connect:request()
    Падает в connect: on, ошибка - attempt to call a nil value
    Если закомментировать connect: on - ошибку не получаю сколько бы я не тестировал код.
    Если это ошибка разработчиков Nodemcu - как обойти пока не смог придумать.
     
    ИгорьК нравится это.
  8. ИгорьК

    ИгорьК Гуру

    Модуль http, полагаю, надстройка над модулем net. Не там ли решение?
     
  9. ИгорьК

    ИгорьК Гуру


    upload_2023-1-23_14-10-41.png
     
  10. serg3295

    serg3295 Гуру

    1. Проверьте, что у вас получено корректное время от ntp сервера.
    2. Введите проверочный код в Esplorer
    Код (C++):
    dat = {}
    dat.bot = ''цифро буквы"
    dat.id  = ''цифры"

    dat.text = 'It_Works'

    ask = 'https://api.telegram.org/bot'..dat.bot..'/sendMessage?chat_id='..dat.id..'&text='..dat.text

    connection = http.createConnection(ask, http.POST)
    connection:on("complete", function(status, connected)
      print("Request completed with status code =", status, connected)
    end)

    cb_on = function(code, txt) print("dsfsdfsdfsdfsd") end
    connection:on("data", cb_on)

    connection:request()

    dat, ask, connection = nil, nil, nil
    collectgarbage()
     
    У меня как-то так выходит.
    23-01-23_14-14.png
    Да, и функцию лучше написать такую
    cb_on = function(code, txt) print(code, txt) end
    сразу вывод поинтереснее станет.
     
    Последнее редактирование: 23 янв 2023
  11. obuhanoe

    obuhanoe Гик

    вот что на сайте:
    Код (Text):
    connection:on(event[, callback])
    -- event One of
    "data" Can be called multiple times, each time more (non-headers) data is received. Callback is called as callback(status_code, data)
    То есть все верно у меня
    Проверить на net модуле вместо http ?
    Вот как раз с таким вызовом, я использую в другом месте - проблем не было, где используется http.createConnection(ask, http.POST)

    А вот использование функции как Вы показали попробую использовать.
     
  12. obuhanoe

    obuhanoe Гик

    А это для каких целей нужно?
     
  13. serg3295

    serg3295 Гуру

    Без корректного времени не установится TLS соединение и будет ошибка
    esp-tls: couldn't get hostname for :api.telegram.org: getaddrinfo() returns 202, addrinfo=0x0
    E (19391) esp-tls: Failed to open new connection
     
    obuhanoe нравится это.
  14. obuhanoe

    obuhanoe Гик

    Понял. спасибо проверяю дальше.
     
  15. obuhanoe

    obuhanoe Гик

    Переписал вот так:
    Код (Text):
    cb_on = function(code, txt) catchErr() print(code, txt) end
    connect:on("data", cb_on)

    То есть я каждые 5 секунд вызываю метод telegram - getUpdates
    Он может поработать 10 секунд, а может и 5 минут.
    И потом падение с ошибкой - attempt to call a nil value

    Со свободной памятью все в порядке - 200К свободных.
     
  16. serg3295

    serg3295 Гуру

    Из вашего первого сообщения я понял так, что регистрация callback'a приводит к падению. Теперь выясняется, что эта неисправность зависит от времени наработки.
    Я не знаю что у вас в функции catchErr, но предлагаю убрать её оттуда.
    Я повызывал вручную раз десять вот этот код, а потом устал. Ничего пока не отвалилось.
    Код (C++):
     connection = http.createConnection(ask, http.GET, {headers = {Connection = "close"}})

    connection:on("data", function(code, data)        
                print(code, data)    
    end)

    connection:request()
    Переделал запрос на getUpdates и выполнил раз тридцать. Всё работает.
     
    Последнее редактирование: 23 янв 2023
  17. obuhanoe

    obuhanoe Гик

    Я чуть ранее писал о том, что не зависит от времени и происходит спонтанно, нужно было еще раз мне акцентировать на это внимание.
    Ваш пример по отлову ошибки - node.setonerror
    если таймер повесить - наверное и у Вас должен сломаться )
     
  18. serg3295

    serg3295 Гуру

    Переделал запрос на getUpdates и выполнил раз тридцать. Всё работает.
    А зачем вы в каждом callback'e регистрируете функцию node.setonerror!? Её один раз надо зарегистрировать и всё.
     
  19. obuhanoe

    obuhanoe Гик

    я саму функцию описал в начале файла вызываемого:
    Код (Text):
    do

       local function catchErr()
           .....код
       end

    end
    А вставил в место предположительного падения - если не callback, то вызов можно вставить любое место файла?
     
  20. serg3295

    serg3295 Гуру

    Функция node.setonerror сама перехватит исключение, если оно произошло в callback'e. Поэтому достаточно просто зарегистрировать её в начале программы.
    Как я писал в примере чуть выше.
     
    Последнее редактирование: 23 янв 2023
    obuhanoe нравится это.