ESP8266 - Ответ от сервера обрезается
Я использую ESP8266, подключенный к Arduino через SoftwareSerial, для отправки запроса на веб-сервер узла. ESP8266 отправляет некоторые данные на сервер, и он должен возвращать другие данные. Данные поступают на сервер правильно, но ответ от сервера является неполным (он обрезается каждый раз по-разному), и я не могу получить доступ к телу ответа из своего эскиза Arduino. Сервер отправляет ответ правильно, как я проверил с Hurl.
Это мой код:
#include "SoftwareSerial.h"
String ssid ="ssid";
String password="pwd";
SoftwareSerial esp(3, 2);// RX, TX
ESP8266_Simple wifi(3,2);
String data;
String server = "server";
String uri = "uri";
String token = "token";
float temp_set = 15; //standard values
float temp_rec = 15;
String temp_set_s;
String temp_rec_s;
int activate = LED_BUILTIN; //pin for relay
int button_up = 4;
int button_down = 5;
unsigned long time;
//LCD
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// DHT11
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 6
#define DHTTYPE DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);
void setup() {
esp.begin(9600);
Serial.begin(9600);
delay(10);
reset();
connectWifi();
pinMode(activate, OUTPUT);
pinMode(button_up, INPUT);
pinMode(button_down, INPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
//DHT setup
dht.begin();
sensor_t sensor;
delay(500);
}
//reset the esp8266 module
void reset() {
esp.println("AT+RST");
delay(1000);
if(esp.find("OK") ) Serial.println("Module Reset");
}
//connect to your wifi network
void connectWifi() {
String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
esp.println(cmd);
delay(4000);
if(esp.find("OK")) {
Serial.println("Connected!");
time = millis();
} else {
connectWifi();
Serial.println("Cannot connect to wifi");
}
}
void loop () {
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s;
//httppost();
// dht data
sensors_event_t event;
dht.temperature().getEvent(&event);
temp_rec = event.temperature;
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet" + temp_set_s;
// to activate
if(temp_set < temp_rec){
digitalWrite(activate, LOW);
} else{
digitalWrite(activate, HIGH);
}
//function for physical buttons
if((digitalRead(button_up)) == HIGH){
temp_set = temp_set + 0.5;
delay(100);
}
if((digitalRead(button_down)) == HIGH){
temp_set = temp_set - 0.5;
delay(100);
}
//shows temperature on display
lcd.setCursor(0, 0);
lcd.print("T rec " + String(temp_rec));
//shows temperature on display
lcd.setCursor(0, 1);
lcd.print("T set " + String(temp_set));
temp_rec_s = String(temp_rec);
temp_set_s = String(temp_set);
data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s + "&token=" + token;
//Serial.println(data);
if((millis() - time) >= 10000){
httppost();
}
delay(200);
}
void httppost () {
esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.
if(esp.find("OK")) {
Serial.println("TCP connection ready");
}
delay(1000);
String postRequest =
"POST " + uri + " HTTP/1.0\r\n" +
"Host: " + server + "\r\n" +
"Accept: *" + "/" + "*\r\n" +
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"\r\n" + data;
String sendCmd = "AT+CIPSEND="; //determine the number of caracters to be sent.
esp.print(sendCmd);
esp.println(postRequest.length());
Serial.println(postRequest);
delay(500);
if(esp.find(">")) {
Serial.println("Sending..");
esp.print(postRequest);
String tmpResp = esp.readString();
Serial.println(tmpResp);
if(esp.find("SEND OK")) {
Serial.println("Packet sent");
while(esp.available()) {
String line = esp.readString();
Serial.print(line);
}
// close the connection
esp.println("AT+CIPCLOSE");
}
}
}
1 ответ
Положить delay(1)
под esp.readString()
и использовать .read()
вместо char
как это:
while(esp.available())
{
char line = esp.read(); // read one char at a time
delay(1); // prevent freezing
Serial.print(line);
if (line == '\0') continue; // terminate the `while` when end of the data
}
.readString()
Метод, указанный @gre_gor, читает до тех пор, пока в течение 1 секунды не поступят входящие данные.
Поэтому лучше использовать метод read()
а также char
так как вы можете проверить символ, чтобы увидеть, если вы достигли конца символа данных \0
,
Когда используешь .read()
рассмотрите возможность использования пользовательского тайм-аута, поскольку данные могут доставляться с задержками, поэтому вы можете продолжать попытки в течение определенного периода времени, если вы еще не достигли конца символа данных \0
, как это:
long int time = millis(); // current time
long int wait = 1000 * 10; // wait 10 seconds before terminating the read process
while ((time + wait) > millis())
{
while (esp.available())
{
char line = esp.read();
delay(1);
Serial.print(line);
if (line == '\0') continue;
}
}