Arduino Uno + ESP01模块HTTP请求问题

时间:2017-12-01 02:08:26

标签: arduino httprequest at-command

我一直在使用我的Arduino Uno板和ESP01模块。我的目标是向远程服务器发送HTTP请求并获取远程数据库的最后一个条目。此条目是远程切换按钮的状态,可以通过位于远程服务器上的网页进行修改。我正在使用AT命令。

要检查切换按钮的状态,每秒都会从Arduino Uno发送HTTP请求。

我写的Arduino草图配置了ESP01,将它连接到wifi,并发送HTTP请求。

Arduino sketch:

#include <SoftwareSerial.h>
SoftwareSerial SerialESP8266(2,3); // RX, TX

String server = "someServer";
String cadena=""; //to store HTTP request

void setup() {
  SerialESP8266.begin(9600);
  Serial.begin(9600);
  SerialESP8266.setTimeout(5000);
  //checking the ESP8266 response
  SerialESP8266.println("AT");
  if(SerialESP8266.find("OK"))
    Serial.println("AT OK");
  else
    Serial.println("Error on ESP8266");
  //ESP8266 in STA mode.
  SerialESP8266.println("AT+CWMODE=1");
  if(SerialESP8266.find("OK"))
    Serial.println("ESP8266 on STATION mode...");
  //Connecting to wifi
  SerialESP8266.println("AT+CWJAP=\"mySSID\",\"somePassword\"");
  Serial.println("Connnecting...");
  SerialESP8266.setTimeout(10000); //waiting for connection
  if(SerialESP8266.find("OK"))
    Serial.println("WIFI OK");
  else
    Serial.println("Unable to connect...");
  SerialESP8266.setTimeout(2000);
  //Disable multiple connections
  SerialESP8266.println("AT+CIPMUX=0");
  if(SerialESP8266.find("OK"))
    Serial.println("Multiple connections disabled");
}

void loop() {
  SerialESP8266.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");
  //connecting to server
  if(SerialESP8266.find("OK")) {
    Serial.println();
    Serial.println();
    Serial.println();
    Serial.println("Server connection successful...");
    //Armamos el encabezado de la peticion http
    String peticionHTTP= "GET /readLast.php";
    peticionHTTP=peticionHTTP+" HTTP/1.1\r\n";
    peticionHTTP=peticionHTTP+"Host: someserver\r\n\r\n";
    peticionHTTP=peticionHTTP+"Host: localhost\r\n\r\n";
    //Sending the length of the HTTP request
    SerialESP8266.print("AT+CIPSEND=");
    SerialESP8266.println(peticionHTTP.length());
    //waiting for ">" for sending HTTP request
    if(SerialESP8266.find(">")) {
      //we can send the HTTP request when > is displayed
      Serial.println("Sending HTTP request. . .");
      SerialESP8266.println(peticionHTTP);
      if(SerialESP8266.find("SEND OK")) {
        Serial.println("HTTP request sent...:");
        Serial.println();
        Serial.println("On stand by...");
        boolean fin_respuesta=false;
        long tiempo_inicio=millis();
        cadena="";
        while(fin_respuesta==false) {
          while(SerialESP8266.available()>0) {
            char c=SerialESP8266.read();
            Serial.write(c);
            cadena.concat(c); //store the request string on "cadena"
          }
          //terminate if "cadena" length is greater than  3500
          if(cadena.length()>3500) {
            Serial.println("The request exceeded the maximum length...");
            SerialESP8266.println("AT+CIPCLOSE");
            if( SerialESP8266.find("OK"))
              Serial.println("Connection terminated...");
            fin_respuesta=true;
          }
          if((millis()-tiempo_inicio)>10000) {
            //Terminate if connection time exceeded the maximum
            Serial.println("Connection time exceeded...");
            SerialESP8266.println("AT+CIPCLOSE");
            if( SerialESP8266.find("OK"))
              Serial.println("Connection terminated");
            fin_respuesta=true;
          }
          if(cadena.indexOf("CLOSED")>0) {
            Serial.println();
            Serial.println("String OK, connection terminated");
            fin_respuesta=true;
          }
        }
      } else {
        Serial.println("error on HTTP request.....");
      }
    }
  } else {
    Serial.println("Unable to find the server....");
  }
  delay(1000); //1 second delay before new loop
}

HTTP请求(GET请求)由服务器上的readLast.php处理,该服务器连接到数据库并返回切换按钮的最后状态。两种状态是可能的:encender(TURN ON)或apagar(TURN OFF)。

readLast.php

<?php
 $servername = "host";
 $username = "user"; // username for your database
 $password = "password";
 $dbname = "database"; // Name of database

 $now = new DateTime();
 $CRLF = "\n\r";

 $conn = mysqli_connect("localhost", "user", "password");
 if (!$conn) {
     die('Could not connect: ' . mysqli_error($conn));
 }
 $con_result = mysqli_select_db($conn,"database");
 if(!$con_result) {
    die('Could not connect to specific database: ' . mysqli_error($conn));
 }

 $result = mysqli_query($conn, "SELECT accion from `datatable` where id =  (select MAX(id) from datatable)");
 if (!$result) {
    die('Invalid query: ' . mysqli_error($conn));
 }

 while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
     echo "accion=" . $row["accion"];
 }

 mysqli_close($conn);
 ?>

第一个HTTP请求正确返回切换按钮的状态。但是下一个HTTP请求返回BAD HTTP REQUEST:

IPD,298:HTTP/1.1 200 OK
Date: Fri, 01 Dec 2017 01:40:56 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: awex
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Request-ID: cf44e42dbd53cb7cb5456e4b70e3399d

10
accion: encender

+IPD,5:0

+IPD,428:HTTP/1.1 400 Bad Request
Date: Fri, 01 Dec 2017 01:40:56 GMT
Content-Type: text/html
Content-Length: 170
Connection: close
Server: awex
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Request-ID: d8ffa7b4eece5d1e88c7786fea5ace9f

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>openresty</center>
</body>
</html>
CLOSED

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,但能够解决它:

     while(SerialESP8266.available()>0) {
        char c=SerialESP8266.read();
        Serial.write(c);
        cadena.concat(c); //store the request string on "cadena"
        if (cadena.length() > 50) cadena = "";
      }

问题是由于string.indexof();

的限制

支持的最大字符数为170,任何更大的字符都不起作用。