Thingspeak TalkBack - Ethernet shield - Serial read => I need some help

Hi All,

My UNO & Eth. Shield are connected and want to control my LED (7) on the board using TalkBack. In my console I see the serial read coming in nice and I even see the Command I have set in ThingsPeak. However, when I do a check and print my "talkBackCommand", I see only the beginning of the content I expect. Since my command from Thingspeak is at the end of the string content, it is lost and therefore it does not work.

Arduino code:(basic parts)

failedCounterTalkBack = 0; talkBackCommand=""; int flag=0; int counter=0; while(client.connected() && !client.available()) delay(1); //waits for data while (client.connected() || client.available()) { char charIn = client.read(); Serial.print(charIn); talkBackCommand += charIn; }

Serial.println(); Serial.println("--CHECK--");

Serial.println(talkBackCommand); delay(10); Serial.println("--ENDCHECK--");

int commandindex = talkBackCommand.indexOf("OK"); (I just checked if the word OK was to found and this is works fine) talkBackCommand=talkBackCommand.substring(commandindex);

Serial.println("-----------2------------"); Serial.print("Command -> "); Serial.println(talkBackCommand); Serial.println("-----------3------------"); Serial.println();


This is what I see on my console: (and should be 2 times the same value but is not)

--ENDCHECK-- -----------2------------ Command -> -----------3------------

HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Connection: close Status: 200 OK X-Frame-Options: ALLOWALL Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH Access-Control-Allow-Headers: origin, content-type, X-Requested-With Access-Control-Max-Age: 1800 Last-Modified: Sun, 30 Aug 2015 10:55:06 GMT Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 00ecd0ae-c76c-429a-92bc-8a570e78b661 X-Runtime: 0.009102 X-Powered-By: Phusion Passenger 4.0.57 Date: Sun, 30 Aug 2015 10:55:06 GMT Server: nginx/1.9.3 + Phusion Passenger 4.0.57

_CMD_LEDON --CHECK-- HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Connection: close Status: 200 OK X-Frame-Options: ALLOWALL Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH Access-Control-Allow-Headers: origin, content-type, X-Requested-With Access-Control-Max-Age: 1800 Last-Modified: Sun, 30 Aug 2015 10:55:06 GMT Cache-Control: max-age=0, private, must-revalidate X-Req --ENDCHECK-- -----------2------------ Command -> -----------3------------

So now it stops at X-req. I would expect that the complete string was there but is not.

I also see some people do a check right away on the command word, but since it is a longer string, the command-word needs to be searched, no problem with that. When the keyword is available, the below would switch the relay-out on out7.

if(talkBackCommand == "LEDOFF") digitalWrite(RelayPin13, LOW); if(talkBackCommand == "LED_ON") digitalWrite(RelayPin13, HIGH);

Any idea why the string "talkBackCommand" is not complete?

Thanks in advance, Bob

You may be running out of SRAM. You are trying to store the entire response, and that may not be possible with an Uno.

Hint: Wait for the blank line before starting to store the response. The blank line is the signal that the header is complete and everything after that is the body.

Hi SurferTim: Sounds good. Is there a common way to do this? I guess insert an if statement on CRLF in the reading loop? thanks in advance,...

You can save each line and compare when you get a line feed. I don’t care for zoomkat’s connected/available check, nor do I like using the String data type, but I will accept those for expedience.

while (client.connected() || client.available())
{
  char charIn = client.read();
  Serial.print(charIn);

  // if charin is not a cr or lf
  if charin != '\n' && charin != '\r') 
  {
    // save the character in the String
    talkBackCommand += charIn;
  }
  else
  {
    // if it is a cr or lf
    // do your string compare check here

    // then clear the String
    talkBackCommand == "";
  }
}

SurferTim, Thanks for your valuable suggestion, it works!

Before it leaves the loop, it just remembers the last action, which is the correct command and therefore, testing can be done after the loop as original. So there are possibilities to improve the code and make it more roboust. After four days of testing and trying, this is my lucky day, thanks!

while(client.connected() && !client.available()) delay(1); //waits for data while (client.connected() || client.available()) { char charIn = client.read(); Serial.print(charIn); if (charIn != '\n' && charIn != '\r') { talkBackCommand += charIn; } else { Serial.print(talkBackCommand); talkBackCommand =""; } }

You might be able to use the text finder application below to limit what is captured. In the past I've used counting line feeds to skip most of headers before starting to capture the returned material.

http://playground.arduino.cc/Code/TextFinder

  if (client.available()) {
    char c = client.read();
    //Serial.print(c);  // uncomment to see raw feed
    if (c==lf) x=(x+1);
    if (x==14) readString += c;
    //readString += c;
  }

Yes thanks Zoomkat, this works as long as the input string is a fixed and in my case it probably helps. I think I will check for a double linefeed, since the command is printed with a blank line just before.

pluto99: Yes thanks Zoomkat, this works as long as the input string is a fixed and in my case it probably helps. I think I will check for a double linefeed, since the command is printed with a blank line just before.

The double line feed will probably have a carriage return in between that you may need to account for.