ESP8266 - 来自服务器的响应被切断

时间:2018-01-09 21:39:08

标签: arduino esp8266 arduino-esp8266 software-serial

我正在使用通过SoftwareSerial连接到Arduino的ESP8266来向节点Web服务器发出请求。 ESP8266将一些数据发送到服务器,它应该返回其他数据。数据正确到达服务器,但服务器的响应不完整(每次都以不同的方式切换),我无法访问Arduino草图的响应体。服务器正确发送响应,因为我已经用投掷检查了。

这是我的代码:

#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 个答案:

答案 0 :(得分: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
}

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

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

使用.read()时考虑使用自定义超时,因为数据可以延迟传送,因此如果尚未达到数据末尾{{{},您可能希望继续尝试一段时间1}},像这样:

\0