2016-07-06 5 views
0

SMTP를 통해 나에게 이메일을 보내는 Lua 스크립트가 있습니다. NodeMCU에 업로드하고 dofile("sendemail.lua")라고 할 때 모든 것이 잘 작동합니다.while 루프를 사용할 때 NodeMCU 시간 초과

-- 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]]") 

그러나, I는 아날로그 입력 값을 모니터링하고 소정의 아날로그 입력 값이 검출되는 경우 만 전자 메일을 보낼 루프 사용할. 따라서, I는 sendemail() 함수 정의 후 즉시 기능 sendmail('subject', 'body')

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 스크립트가 정상적으로 작동하고 갑자기이 작은 하나의 작은 루프를 추가 할 때 갑자기 작동하지 않기로 결정하면 루프 자체가 완벽하게 작동합니다. NodeMCU 기준에서

답변

1

작은 따옴표 :

tmr.wdclr() 시스템 감시를 공급. 혹시이 기능을 사용해야하는 경우 일반적으로

, 당신은 잘못하고있다.

NodeMCU의 이벤트 기반 모델은 이 발생하기를 기다리는 하드 루프에있을 필요가 없음을 의미합니다. 오히려 어떤 일이 발생하면 콜백을 으로 보내서 알림을받습니다. 이 접근 방식을 사용하면 시스템 워치 독에 수동으로 피드 할 필요가 없습니다.

두 번째 줄을 유의하시기 바랍니다. :)

확실하지 당신의 문제가 무엇인지,하지만 당신은 처음에 while 루프를 사용합니까 이유는 무엇입니까? 정기적으로 타이머 이벤트를 사용하여 ADC를 폴링하지 않는 이유는 무엇입니까? 피드에 늦게 어떤 이유로 오기 때문에

어쩌면 감시가 시작됩니다. 만약 당신이 루프를 빠져 나올 때마다 당신은 그것을 먹이지 않습니다.

1

는 코멘트 입력이 너무 작기 때문에 나는 등을 게시 명확한 대답을하지 않을 경우에도 마찬가지입니다.

첫째, 난 당신이 내가 당신의 이전 질문에 대한 게시 된 스크립트를 사용하는 것이 좋습니다. 이것은 WiFi 설정을 올바르게 처리하지 못합니다. 계속하기 전에 장치가 IP를 얻을 때까지 타이머를 기다려야합니다. wifi.sta.config이 (가) 비 블로킹임을 기억하십시오. 그리고 명시 적으로 설정하지 않으면 auto-connect=true을 사용하므로 AP에 즉시 연결을 시도합니다. 이것은 또한 wifi.sta.autoconnect(1)이 불필요한 이유이기도합니다.

게시 한 ADC 읽기 코드를 이해하지 못합니다. a) 귀하가 GPIO 0 아무것도하지 않고 B) adc.read는 0을 지원하기 때문에

vp = 0 
gpio.mode(vp, gpio.INPUT) 

나에게 불필요한 보인다.

바쁜 루프를 사용하고 감시견에게 지속적으로 먹이를 보내는 것보다는 which is a very bad sign 간격 타이머를 사용하는 것이 좋습니다. 또한, 처음으로 조건이 충족되면 루프를 중단하고 싶지 않을 것입니다. 으로 돌아 오지 않으십니까? 그래서, 당신은 루프에 머물러 있어야하고, 메일을 보내는 것을 계속해야합니까? 이와 같은 것 (테 스트되지 않은 것) :

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) 
+0

이렇게하면 타이머 알람이 약 10 초 동안 재설정됩니다. 그게 왜 일어날 지 모르는 어떤 아이디어? – user1173922

+0

실제로 NodeMCU에서 스크립트를 실행하려고하면이 작업이 임의로 발생하는 것 같습니다. 개별 부품이 잘 작동하는 것 같아서, 나는 나쁜 하드웨어가 있거나 펌웨어가 엉망이되었다고 생각하고 있습니다. – user1173922