Post topics, source code that relate to the Arduino Platform

User avatar
By swilson
#11633 Got my Pro Mini v3.3 and ESP8266 doing a thingspeak channel update as well as twiiter tweet at the same time. I have ran into a problem that I just can't figure out. If the update string I send to the ESP8266 to send to thingspeak is over 80 chars in length it will give me a 400 error bad request. If I back it down to 80 chars or under it send just fine. Here are my errors and the code if someone can help me out. PS: I know the code is messy as I am a newb so please be gentle but any pointers will be appreciated. ESP8266 is running AI-v0.9.5.0 AT Firmware.

This is what happens when it is over 80 chars long
Code: Select allAT+CIPSTART="TCP","api.thingspeak.com",80
CONNECT

OK
AT+CIPSEND=90
> GET /update?key=XXXXXXXXXXXXXXXX&field1=1&twitter=xxxxxx&tweet=Gen at Old HE is running!1
SEND OK

+IPD,323:HTTP/1.1 400 Bad Request
Server: nginx/1.7.5
Date: Mon, 09 Mar 2015 05:09:15 GMT
Content-Type: text/html
Content-Length: 172
Connection: close

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

OK
CLOSED


This is what happens when it is 80 chars or less
Code: Select allAT+CIPSTART="TCP","api.thingspeak.com",80
CONNECT

OK
AT+CIPSEND=80
> GET /update?key=XXXXXXXXXXXXXXXX&field1=1&twitter=xxxxxx&tweet=Gen at running!1
SEND OK

+IPD,3:376
OK
CLOSED


My sloppy code:
Code: Select all#include <SoftwareSerial.h>

#define DEBUG

#define _ledpin     13
int genPin = 5;

//*-- Hardware Serial
#define _baudrate   9600

//*-- Software Serial
#define _rxpin      10
#define _txpin      11
SoftwareSerial debug( _rxpin, _txpin ); // RX, TX

//*-- IoT Information
#define SSID "ssid"
#define PASS "password"
#define IP "api.thingspeak.com" // ThingSpeak IP Address: 184.106.153.149
String api_key = "XXXXXXXXXXXXXXXX";

// Variables will change:
int genPushCounter = 0;   // counter for the number of button presses
int genState = 0;         // current state of the button
int lastGenState = 0;     // previous state of the button

void setup() {
    pinMode(genPin, INPUT);
    Serial.begin( _baudrate );
    debug.begin( _baudrate );
    debug.println("ESP8266");
    Serial.println("AT+RST");
    delay(1000);
    if(Serial.find("ready"))
    {
        debug.println("ESP8266 CONNECTED\nREADY TO SEND DATA");
        connectWiFi();
    }
}

void loop() {
   
    delay(15000);   // 30 second
    // ESP8266 Client
    String cmd = "AT+CIPSTART=\"TCP\",\"";
    cmd += IP;
    cmd += "\",80";
    Serial.println(cmd);
    debug.println(cmd);
    if(Serial.find("Error"))
    {
        debug.print( "CANNOT CONNECT\nEXITING" );
        return;
    }
    String getStr = "GET /update?key=";
    String getStr2 = "GET /update?key=";
    genState = digitalRead(genPin);
    if (genState != lastGenState) {
     
      if (genState == HIGH)
      {
        genPushCounter++;
        getStr += api_key;
        getStr += "&field1=";
        getStr += 1;
        getStr += "&twitter=";
        getStr += "xxxxxx";
        getStr += "&tweet=";
        getStr += "Gen at Old HE is running!! Total=";
        getStr += genPushCounter;
        getStr += "\r";
        String send = "AT+CIPSEND=";
        send += String(getStr.length());
        Serial.println(send);
        debug.println(send);
      } else
      {
        getStr2 += api_key;
        getStr2 += "&field1=";
        getStr2 += 0;
        getStr2 += "&twitter=";
        getStr2 += "xxxxxx";
        getStr2 += "&tweet=";
        getStr2 += "Gen at Old HE has shut down!!";
        getStr2 += "\r";
        String send = "AT+CIPSEND=";
        send += String(getStr2.length());
        Serial.println(send);
        debug.println(send);
      }
    }
    lastGenState = genState;
      if(Serial.find( ">" ) )
      {
        debug.print(">");
        if (genState == HIGH)
        {
          Serial.println(getStr);
          debug.println(getStr);
        } else
        {
          Serial.println(getStr2);
          debug.println(getStr2);
        } 
      }
      else
      {
        Serial.println( "AT+CIPCLOSE" );
        debug.println( "AT+CIPCLOSE" );
      }
    Serial.find("+IPD");
    while (Serial.available())
    {
      char c = Serial.read();
      debug.write(c);
      if (c == '\r') debug.print('\n');
    }
    if( Serial.find("OK") )
    {
        debug.println( "DATA SENT" );
    }
    else
    {
        debug.println( "DATA NOT SENT\nEXITING" );
    }
}

void sendDebug(String cmd)
{
    debug.print("SEND: ");
    debug.println(cmd);
    Serial.println(cmd);
}
 
boolean connectWiFi()
{
    Serial.println("AT+CWMODE=1");
    debug.println("AT+CWMODE=1");
    delay(2000);
    String cmd="AT+CWJAP=\"";
    cmd+=SSID;
    cmd+="\",\"";
    cmd+=PASS;
    cmd+="\"";
    Serial.println(cmd);
    delay(5000);
    if(Serial.find("OK"))
    {
        debug.println("WIFI CONNECTED");
        delay(3000);
        Serial.println("AT+CIFSR");
        while (Serial.available())
          debug.write(Serial.read());
    }
    else
    {
        debug.println("ERROR CONNECTING TO WIFI");
        return false;
    }

    cmd = "AT+CIPMUX=0";
    Serial.println( cmd );
    debug.println( cmd );
   
    if( Serial.find( "Error") )
    {
        debug.print( "CANNOT SET SINGLE CONNECTION MODE" );
        return false;
    }
}


Thanks if anyone can help me out.
User avatar
By ricg
#11704 I don't think it's a limitation of the esp8266. According to the esp8266 documentation the cipsend string can be a max of 2048 bytes.
Try breaking the string into two calls to Serial.print() and see if that succeeds. if it still fails then it could be a problem with the GET cmd you'r sending.
Here's an example: You don't need the id since you have mux=0.
sprintf(cmd,"AT+CIPSEND=%d,%d",id,total_len);
espSerial.println(cmd); // note this send ends with newline
// wait for '>' and send data
if( waitcmd( ">", 50 ) ) { // this function waits for the '>' then the loop sends a series of strings
for(int i=0; hdr[i]!=NULL; i++) // to the esp8266, which is waiting for the total length to appear in
espSerial.print(hdr[i]); // it's buffer before sending.
-------------------------
BTW i've had problems using the String class in a loop. the memory gets fragmented and weird stuff starts happening. To see if you r running low on memory check this out:
http://playground.arduino.cc/Code/AvailableMemory
I switched to using arrays and sprintf which solved my problems. Of course I'm not suggesting that is your problem here, but it's something to be aware of.
---------------------------