我一直在使用我的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
我做错了什么?
答案 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,任何更大的字符都不起作用。