2016-05-13 5 views
1

У меня есть приложение NodeMCU Lua, которое использует два таймера. Каждый таймер вызывает функцию, которая вызывает HTTP-запрос на локальный сервер.Таймер NodeMCU неожиданно останавливается

После нескольких итераций один из таймеров останавливается, а другой таймер продолжается. Количество итераций до остановки таймера кажется случайным. Я много раз запускал тестовый скрипт, и точка, с которой останавливается таймер, никогда не меняется. Примечание. Не всегда один и тот же таймер останавливается.

Вот некоторый тестовый код, который надежно демонстрирует эту проблему:

ctr1=0 
ctr2=0 

local function doCmdChk() 
    ctr1 = ctr1 + 1 
    http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
    function(rspCode, payload) 
     tmr.start(1) 
    end) 
end 

local function sendData() 
    ctr2 = ctr2 + 1 
    local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

    http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
    function(rspCode, payload) 
     tmr.start(2) 
    end) 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, doCmdChk) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, sendData) 

Моего приложение не выпалить по HTTP запросов так быстро, как тестовый код, но когда приложение запускается в течение нескольких часов и тот же результат (т.е. один из таймеров перестает работать). Сокращение времени между HTTP-запросами делает ошибку раньше.

Неужели кто-нибудь столкнулся с этой проблемой? Кто-нибудь есть идеи по устранению этой проблемы? (неспособность надежно отправлять непрерывные HTTP-запросы - это шоу-стоп для этого приложения).

ответ

1

Решение состоит в том, чтобы установить флаги, чтобы в любой момент времени выдавался только один запрос HTTP. Вот предыдущий скрипт тест, который включает в себя флаги:

ctr1=0 
ctr2=0 
sendFlag=true 

local function doCmdChk() 
    if sendFlag then 
     sendFlag=false   
     ctr1 = ctr1 + 1 
     http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(1) 
     end) 
    else 
     tmr.alarm(3, 1000, tmr.ALARM_SINGLE, doCmdChk) 
    end 
end 

local function sendData() 
    if sendFlag then 
     sendFlag=false   
     ctr2 = ctr2 + 1 
     local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

     http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(2) 
     end) 
    else 
     tmr.alarm(3, 1000, tmr.ALARM_SINGLE, sendData) 
    end 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, doCmdChk) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, sendData) 

Я побежал этот сценарий в течение нескольких часов, и оба HTTP отправить функции продолжали работать, как ожидалось.

Я попробовал node.task.post() вариант, тестовый скрипт следующим образом:

ctr1=0 
ctr2=0 

local function doCmdChk() 
     ctr1 = ctr1 + 1 
     http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(1) 
     end) 
end 

local function sendData() 
     ctr2 = ctr2 + 1 
     local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

     http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(2) 
     end) 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, function() node.task.post(node.task.MEDIUM_PRIORITY, doCmdChk) end) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, function() node.task.post(node.task.HIGH_PRIORITY, sendData) end) 

Но через пару часов работы одного из HTTP обратных вызовов не был вызван, так что должно быть столкновение.

0

Я мало знаю о NodeMCU, но в соответствии с справочным руководством вызывающие функции http.post и http.get вызываются при получении ответа. Следовательно, таймеры перезапускаются только при получении ответа. Есть ли вероятность задержки или, может быть, вы никогда не получите ответ?

Перезапуск таймера после того, как какой-либо сторонний материал ответил, добавит переменную задержку и поэтому не должен быть очень точным. Я бы не ожидал, что он будет таким же точным, как и некоторый тестовый код.

Для отладки я предлагаю вам распечатать фактические задержки между вызванными обратными вызовами или задержкой между post/get и response.

+0

Ваш комментарий к функции обратного вызова интересен. У меня был случай в Nodemcu, где там, где два HTTP-запроса делались один за другим, а ответ на второй запрос никогда не вызывал функцию обратного вызова. Вставка 1-секундной задержки между http-вызовами решила эту проблему. Мне интересно, создают ли две таймеры, действующие независимо, аналогичную ситуацию (в которой два HTTP-запроса делаются близко друг к другу). Я сделаю некоторое тестирование, чтобы увидеть, произошло ли такое столкновение. – Jonathan

+0

@ Джонатан см. Https://github.com/nodemcu/nodemcu-firmware/issues/1258 –

Смежные вопросы