使用While循环时NodeMCU超时 [英] NodeMCU timeout when using while loop
问题描述
我有一个Lua脚本,可以通过SMTP向自己发送电子邮件.上载到NodeMCU并说dofile("sendemail.lua")
时,一切正常.
I have a Lua script that sends an email to myself via SMTP. Everything works fine when uploading to the NodeMCU and saying dofile("sendemail.lua")
.
-- sendmail.lua
-- The email and password from the account you want to send emails from
MY_EMAIL = "REDACTED"
EMAIL_PASSWORD = "REDACTED"
-- The SMTP server and port of your email provider.
-- If you don't know it google [my email provider] SMTP settings
SMTP_SERVER = "isp.smtp.server"
SMTP_PORT = 25
-- The account you want to send email to
mail_to = "REDACTED"
-- Your access point's SSID and password
SSID = "REDACTED"
SSID_PASSWORD = "REDACTED"
-- configure ESP as a station
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID,SSID_PASSWORD)
wifi.sta.autoconnect(1)
email_subject = ""
email_body = ""
count = 0
local smtp_socket = nil -- will be used as socket to email server
-- The display() function will be used to print the SMTP server's response
function display(sck,response)
print(response)
end
-- The do_next() function is used to send the SMTP commands to the SMTP server in the required sequence.
-- I was going to use socket callbacks but the code would not run callbacks after the first 3.
function do_next()
if(count == 0)then
count = count+1
IP_ADDRESS = wifi.sta.getip()
smtp_socket:send("HELO "..IP_ADDRESS.."\r\n")
elseif(count==1) then
count = count+1
smtp_socket:send("AUTH LOGIN\r\n")
elseif(count == 2) then
count = count + 1
smtp_socket:send("REDACTED".."\r\n")
elseif(count == 3) then
count = count + 1
smtp_socket:send("REDACTED".."\r\n")
elseif(count==4) then
count = count+1
smtp_socket:send("MAIL FROM:<" .. MY_EMAIL .. ">\r\n")
elseif(count==5) then
count = count+1
smtp_socket:send("RCPT TO:<" .. mail_to ..">\r\n")
elseif(count==6) then
count = count+1
smtp_socket:send("DATA\r\n")
elseif(count==7) then
count = count+1
local message = string.gsub(
"From: \"".. MY_EMAIL .."\"<"..MY_EMAIL..">\r\n" ..
"To: \"".. mail_to .. "\"<".. mail_to..">\r\n"..
"Subject: ".. email_subject .. "\r\n\r\n" ..
email_body,"\r\n.\r\n","")
smtp_socket:send(message.."\r\n.\r\n")
elseif(count==8) then
count = count+1
tmr.stop(0)
smtp_socket:send("QUIT\r\n")
print("msg sent")
else
smtp_socket:close()
end
print(count)
end
-- The connectted() function is executed when the SMTP socket is connected to the SMTP server.
-- This function will create a timer to call the do_next function which will send the SMTP commands
-- in sequence, one by one, every 5000 seconds.
-- You can change the time to be smaller if that works for you, I used 5000ms just because.
function connected(sck)
tmr.alarm(0,5000,1,do_next)
end
-- @name send_email
-- @description Will initiated a socket connection to the SMTP server and trigger the connected() function
-- @param subject The email's subject
-- @param body The email's body
function send_email(subject,body)
count = 0
email_subject = subject
email_body = body
smtp_socket = net.createConnection(net.TCP,0)
smtp_socket:on("connection",connected)
smtp_socket:on("receive",display)
smtp_socket:connect(SMTP_PORT, SMTP_SERVER)
end
-- Send an email
send_email("ESP8266", "[[Hi, How are your IoT projects coming along? Best Wishes,ESP8266]]")
但是,我想使用一个循环来监视模拟输入值,并且仅在检测到某些模拟输入值时才发送电子邮件.因此,我在脚本的末尾,sendemail()
函数定义之后和函数sendmail('subject', 'body')
调用之前
However, I want to use a loop to monitor an analog input value and only send the email when certain analog input values are detected. Therefore, I added this code at the end of the script, after the sendemail()
function definition and immediately before the function sendmail('subject', 'body')
is called
vp = 0
gpio.mode(vp, gpio.INPUT)
while true do
local v = adc.read(vp)
if v < 840 or v > 870 then
print(v)
break
end
tmr.wdclr()
end
sendmail('subject', 'body')
while循环运行良好,可以无限期地等待来自模拟引脚的输入.找到该输入后,它将正确中断并调用sendmail函数.但是,一旦调用该函数,NodeMCU最终将重置.有时,它可以达到与服务器成功认证SMTP凭据的程度,有时,它甚至在关闭之前甚至无法生成HELO.可能是什么原因造成的?为什么sendmail.lua
脚本能正常工作,然后突然添加一个似乎完全可以正常工作的小while循环,突然决定不工作?
The while loop works perfectly, waiting indefinitely for input from the analog pin. Once that input is found, it breaks correctly and calls the sendmail function. However, once that function is called, NodeMCU eventually resets. Sometimes it will get as far as successfully authenticating the SMTP credentials with the server, and sometimes it will not even make the HELO before it shuts down. What could possibly be causing this? Why would the sendmail.lua
script work fine then suddenly decide not to work when adding this one small while loop that appears to work perfectly fine on its own?
推荐答案
即使它可能不是确定的答案,但由于注释输入太小,我还是这样张贴它.
Even if it may not be the definite answer I post it as such since the comment input is too small.
首先,建议您使用我为上一个问题发布的脚本.此人未正确处理WiFi设置.您需要等待计时器直到设备获得IP,然后才能继续.请记住, wifi.sta.config
是非阻塞的.并且由于未明确设置使用auto-connect=true
,因此它将尝试立即连接到AP.这也是wifi.sta.autoconnect(1)
多余的原因.
First, I suggest you use the script I posted for your previous question. This one isn't handling WiFi setup correctly. You need to wait in a timer until the device got an IP before you can continue. Remember, wifi.sta.config
is non-blocking. And since it uses auto-connect=true
if not set explicitly it'll try to connect to the AP immediately. That's also the reason why wifi.sta.autoconnect(1)
is superfluous.
我不理解您发布的ADC阅读代码.
I don't understand the ADC reading code you posted.
vp = 0
gpio.mode(vp, gpio.INPUT)
对我来说似乎不必要,因为a)您不使用GPIO 0进行任何操作,并且b) adc.read
仅支持0.
Seems unnecessary to me because a) you don't do anything with GPIO 0 and b) adc.read
only supports 0.
这是一个非常糟糕的信号,我建议您使用基于间隔的计时器.此外,我想您不想在第一次满足条件时就中断循环吗?因此,您需要保持循环并继续触发发送邮件,对吗?可能是这样(未经测试):
Rather than using a busy loop and constantly feeding the watch dog, which is a very bad sign, I suggest you use an interval based timer. Furthermore, I guess you don't wanna break the loop the first time the condition is met and never come back? So, you need to stay in the loop and keep triggering send mail, no? Something like this maybe (untested):
tmr.alarm(0, 200, tmr.ALARM_AUTO, function()
local v = adc.read(0)
if v < 840 or v > 870 then
node.task.post(function()
send_email("ESP8266", "[[Hi, How are your IoT projects coming along? Best Wishes,ESP8266]]")
end)
end
end)
这篇关于使用While循环时NodeMCU超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!