ESP8266-来自服务器的响应被切断 [英] ESP8266 - Response from server gets cut

查看:98
本文介绍了ESP8266-来自服务器的响应被切断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用通过SoftwareSerial连接到Arduino的ESP8266向节点Web服务器发出发布请求.ESP8266将一些数据发送到服务器,并且它应该取回其他数据.数据正确到达了服务器,但是来自服务器的响应是不完整的(每次都以不同的方式被削减),并且我无法从Arduino草图中访问响应的主体.服务器已正确发送响应,就像我用hurl检查过的一样.

I'm using an ESP8266 connected to an Arduino one via SoftwareSerial to make a post request to a node web server. The ESP8266 sends some data to the server and it should get back other data. The data arrives at the server correctly, but the response from the server is incomplete (it gets cut each time in a different way) and I can't access the body of the response from my Arduino sketch. The server sends the response correctly, as i've checked with 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");

        }
    }
} 

推荐答案

esp.readString()下放置 delay(1)并使用.read()而不是 char ,像这样:

Put a delay(1) under the esp.readString() and use .read() instead with char like this:

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
}

@gre_gor 指出的 .readString()方法读取直到1秒钟内没有传入数据.

The .readString() method as pointed out by @gre_gor reads until there is no incoming data for 1 second.

所以更好的方法是使用 read() char ,因为您可以测试char以查看是否已到达数据字符 \的末尾.0 .

So the better method is to use read() and char since you can test the char to see if you have reached the end of data character \0.

使用 .read()时,请考虑使用自定义超时,因为数据可能会延迟交付,因此如果您尚未达到要求的时间,则可能要继续尝试一段时间.数据字符 \ 0 的结尾,如下所示:

When using .read() consider using a custom timeout, because data can be delivered with delays so you might want to keep trying for a certain period of time if you haven't yet reached the end of data character \0, like this:

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;
    }
}    

这篇关于ESP8266-来自服务器的响应被切断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆