[solved] Electron: TCPClient weirdness

Hi @mdma!

I came across some strange bugs with the Electron: I use the TCPClient to connect to a basic TCP server. The connection works fine, I send data to the TCP server, the data is received fine, and the server sends data back. The reception side does not really work. There are a couple of weird effects:

  • Client.available() will not indicate reception of data
  • Client.read() will return received data, but only after the sender side shutdown the connection and only if
    the data size is above a certain size (> ~150 bytes)
  • Client.read() will not return all data, some data at the end is always missing

The code is basically the TCPClient example from the documentation. Note, that the same code works fine on the Photon.

I tried with version 0.4.8 and 0.4.9.

Did anyone else see that?

1 Like

Thanks for reporting - we’ll look into it!

1 Like

Hi,

didn’t dig deeper into that, but I have an issue on electron not getting a single value (firmware-upgrade flag) from thingspeak. Same app works fine on photon.

keep me posted if you get any updates!

Thanks!

Hey @Stevie and @joky, it would help if you posted the code you are having trouble with so we can take a look. Recently I was using the TCPClient library to download some text files to test data usage and used the following app on the Electron U260 with no problems. Just compiled with the Build IDE and still working great. I can’t say it’s a perfect example, but one known to work. Open a serial terminal and press t to download a text file.

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    if (Serial.available() > 0)
    {
        char c = Serial.read();
        Serial.printf("Hey, you said \'%c\', so I'm gunna: ", c);
        if (c == 't') {
            uint32_t startTime = millis();
            uint32_t endTime = 0;
            Serial.printlnf("Read a text file\r\n[ START TIME ]: %.2f seconds", startTime/1000.0);
            TCPClient client;
            char host[] = "www.textfiles.com";

            Serial.println("connecting...");

            if (client.connect(host, 80))
            {
                Serial.println("connected");
                /* SMALL FILE */
                client.println("GET /100/hack7.txt HTTP/1.0"); // 3988 bytes
                /* LARGE FILE */
                // client.println("GET /100/phrack.29.phk HTTP/1.0"); // 235777 bytes
                client.println("Host: www.textfiles.com");
                client.println("Content-Length: 0");
                client.println();
            }
            else
            {
                Serial.println("connection failed");
            }

            while (client.available() || client.connected())
            {
              if (client.available())
              {
                char c = client.read();
                Serial.print(c);
              }

              if (!client.connected())
              {
                Serial.println();
                Serial.println("disconnecting.");
                client.stop();
              }
            }
            endTime = millis();
            Serial.printlnf("[ END / TOTAL TIME ]: %.2f / %.2f seconds", endTime/1000.0, ((endTime-startTime)/1000.0));
        }
        else {
            Serial.println("ignore you because you're not speaking my language!");
        }
        while (Serial.available()) Serial.read(); // Flush the input buffer
    }

}

There are also some HTTP request libraries in the Build IDE that wrap up the TCPClient library more completely, that should also work on the Electron. Those I haven’t tested, but please let us know what you find.

2 Likes

Hi @BDub ,

try this sketch. Its basically the thingspeak demo (readtemperature.ino) and always reads “0” from the thingspeak server. Same sketch runs perfectly on photon:

/*
  ReadLastTemperature
  
  Reads the latest temperature from the MathWorks weather station in Natick, MA
  https://thingspeak.com/channels/12397 on ThingSpeak, and prints to
  the serial port debug window every 30 seconds.
  
  ThingSpeak ( https://www.thingspeak.com ) is a free IoT service for building
  systems that collect, analyze, and react to their environments.
  
  Copyright 2016, The MathWorks, Inc.
  
  Documentation for the ThingSpeak Communication Library for Arduino is in the extras/documentation folder where the library was installed.
  See the accompaning licence file for licensing information.
*/

#include "ThingSpeak/ThingSpeak.h"


// On Particle Core, Photon, and Electron the results are published to the Particle dashboard using events.
// Go to http://dashboard.particle.io, click on the logs tab, and you'll see the events coming in. 
TCPClient client;

/*
  This is the ThingSpeak channel number for the MathwWorks weather station
  https://thingspeak.com/channels/12397.  It senses a number of things, including 
  Wind Direction, Wind Speed, Humidity, Temperature, Rainfall, and Atmospheric Pressure.

  Temperature is stored in field 4
*/

unsigned long weatherStationChannelNumber = 12397;
unsigned int temperatureFieldNumber = 4;

void setup() {
	Serial.begin(9600);
  ThingSpeak.begin(client);
  
}

void loop() {
  // Read the latest value from field 4 of channel 12397
  float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber);
	Serial.printlnf("Current temp is: %0.2f degrees F", temperatureInF); 
	Particle.publish("thingspeak-lasttemp", String::format("Current temp %.1f degrees F",temperatureInF),60,PRIVATE);
  delay(30000); // Note that the weather station only updates once a minute
}

@BDub, thanks for looking at this. In the end I was testing the unchanged example sketch from the TCPClient documentation. It works fine for the Photon. It loses data in the end for the Electron - which is easy to overlook. If I substitute it with the address of my own server which just returns < 100 bytes, then I will get nothing.

Thanks @Stevie! Trying smaller files, I’m seeing a similar issue… although when looking at the logs I do see all of the data being read. I’m seeing some issues though and will have to dig deeper. Tracking this issue here:

1 Like

Yes, that fits very well. The behavior is really a bit weird, but I agree this seems to be some buffer underrun which is leading to corruption. Thanks for looking into it!

Hi @BDub and @mdma, I tested the fix and it works like a charm now. Thanks for the fast fix!

1 Like

Thanks for testing @Stevie, we’ll be pulling this into the next firmware release for the Electron.

Hi guys,

just for your info: The fix doesn’t solve the issue on G350 (yet)!

regards

Now the problem is solved for the G350 :slight_smile:
@BDub Also I want to ask when to expect official v.0.5.0 firmware in Web IDE?

Early next week.

1 Like

Binaries are out if you want to take a go a updating your Electron. It solves the problem for the TCPClient issue with v0.4.8 or v0.5.0-rc.1 compiled user firmware. https://github.com/spark/firmware/releases/tag/v0.5.0-rc.2

1 Like

I want to share with others that firmware v0.5.0-rc.2 works great.
I have an application that performs measurements and sends value through http library.
Thread System is on, I also use a software timer and so far works great already 24 hours. The value is sent every minute and so far there is not a single failure.
Nice job guys :smiley:

3 Likes

Hi,
same here (G350): Issue solved, TCPclient (and Backup RAM) runs fine.
I used v0.5.0 (locally built to upgrade) both, locally & via particle cloud.

thank you!