当触发我的Arduino MKR1000上的传感器时,我会发送一封电子邮件:
//....
WiFiClient client;
char server[] = "www.myserver.com";
//....
void setup() {
//... Connect to wifi ....
}
void loop() {
// when sensor triggered =>
if (client.connect(server, 80)) {
Serial.println("Sending email");
client.print("GET /WaterOff/sendGridCall.php");
client.print("?valve=");
client.print(valve);
client.print("&position=");
client.print(position);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("User-Agent: Arduino");
client.println("Connection: close");
client.println();
}
delay(6000);
}
但是,它仅在前几次有效(打印“发送电子邮件”),之后不执行请求(不打印“发送电子邮件”)。我是否应该采取一些额外措施使其可靠。
答案 0 :(得分:3)
您永远不会关闭连接。但阻止等待电子邮件确认可能需要永远。您应该考虑使用一个小型状态机来使您的网络连接正常工作。
void loop()
{
// when sensor triggered =>
if (client.connect(server, 80)) { // You connect to client, but it's already
// connected the second time around
// send ...
// client() should wait for response, and client.disconnect()
}
// ...
delay(6000); // tip: avoid blocking the main loop, this blocks your ability to
// read your sensor while sending emails.
}
您的应用的状态机可能如下所示:
enum EmailState {
emIdle, emSendMail, emCheckMailSent, emEmailOK, emEmailError,
};
EmailState email_state;
unsigned long long mail_timer; // can be shared between states.
// small state handlers that do a bit at a time,
// check for an event, wait on some delay (use millis())
// avoid blocking the instruction flow as much as possible.
static void on_emIdle()
{
// read sensor, check timer?
email_state = (triggered) ? emSendMail : emIdle;
}
static void on_sendMail()
{
if (client.connect())
{
// ... prints
email_state = emCheckMailSent;
return;
}
email_state = emEmailError;
}
static void on_emCheckMailSent()
{
// receive HTTP response... can have a long timeout without blocking.
email_state = emCheckMailSent;
// or emEmailOK or emEmailError or retry emSendMail
}
static void on_emEmailOK()
{
if (/*client is connected?*/)
client.disconnect();
if (!mail_timer)
mail_timer = millis();
if (millis() - mail_timer < 6000) // stay in this state for 6 seconds...
{
email_state = emEmailOK;
return;
}
mail_timer = 0; // always reset the timer so it can be used by other states
email_state = emIdle;
}
static void on_emEmailError()
{
if (/*client is connected?*/)
client.disconnect();
// keep a log ?
email_state = emIdle; // or another timer
}
//...
void loop()
{
// update readings, manage other things...
// ...
switch(email_state)
{
default:
case emIdle: on_emIdle(); break;
case emSendMail: on_emSendMail(); break;
case emCheckMailSent: on_emCheckMailSent(); break;
case emEmailOK: on_emEmailOK(); break;
case emEmailError: on_emEmailError(); break;
}
}