使用Arduino Wifi客户端发送可靠的HTTP请求

使用Arduino Wifi客户端发送可靠的HTTP请求,arduino,client,Arduino,Client,当我的Arduino MKR1000上的传感器被触发时,我会发送一封电子邮件: //.... WiFiClient client; char server[] = "www.myserver.com"; //.... void setup() { //... Connect to wifi .... } void loop() { // when sensor triggered => if (client.connect(server, 80)) {

当我的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);
}

但是,它只在前几次工作(“发送电子邮件”被打印),之后它不会执行请求(“发送电子邮件”被打印)。我是否应该采取一些额外的措施使其可靠。

您从未关闭连接。但阻止等待电子邮件确认可能会花费很长时间。您应该考虑一个小型的状态机来进行网络连接工作。
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;
   }
}
enum电子邮件状态{
emIdle、emSendMail、emCheckMailSent、emEmailOK、emEmailError、,
};
EmailState email_state;
未签名的长邮件\u计时器;//可以在各州之间共享。
//一次执行一点操作的小型状态处理程序,
//检查事件,等待一些延迟(使用millis())
//尽可能避免阻塞指令流。
_emIdle()上的静态空隙
{
//读取传感器,检查定时器?
电子邮件状态=(已触发)?emSendMail:emIdle;
}
_sendMail()上的静态无效
{
if(client.connect())
{
//…印刷品
email_state=emCheckMailSent;
返回;
}
email_state=emEmailError;
}
emCheckMailSent()上的静态无效
{
//接收HTTP响应…可以有很长的超时而不阻塞。
email_state=emCheckMailSent;
//或emEmailOK或emEmailError或重试emSendMail
}
_emEmailOK()上的静态无效
{
如果(/*客户端已连接?*/)
client.disconnect();
如果(!邮件计时器)
邮件计时器=毫秒();
如果(millis()-mail_timer<6000)//保持此状态6秒。。。
{
email_state=emEmailOK;
返回;
}
mail_timer=0;//始终重置计时器,以便其他状态可以使用它
email_state=emIdle;
}
_emEmailError()上的静态无效
{
如果(/*客户端已连接?*/)
client.disconnect();
//记日志?
email_state=emIdle;//或其他计时器
}
//...
void循环()
{
//更新阅读资料,管理其他事情。。。
// ...
开关(电子邮件状态)
{
违约:
案例emIdle:on_emIdle();中断;
案例emSendMail:on_emSendMail();中断;
案例emcheckmailssent:on_emcheckmailssent();中断;
案例emEmailOK:on_emEmailOK();中断;
案例emEmailError:on_emEmailError();中断;
}
}

可能您需要关闭与
客户端的连接。stop()
?似乎没有帮助。您是否尝试创建另一个func()并从loop()调用此func?它是否工作多次,还是仅工作一次?它主要工作两次,然后停止工作