Strange issues with serial coms

Hello! So I am currently unable to connect to my Photon over serial using Putty or Particle Dev. However, if close Particle Dev and then unplug and plug everything back in, suddenly serial will work for me again. The really strange part however is that it’s running an old version of the code which I can tell by the wrong Serial.print() outputs showing up on the serial terminal. I reflash the photon back to the new code and the serial stops once again. If I reflash to the old code that it seems to somehow still have on there, the serial stops as well. I can only open serial after I restart everything like I mentioned before.

I’ve tried safe mode and listening mode and in both I can see the device and which COM it’s on, but I can’t connect to it for some reason. I’ve tried switching out cables and adding a USB2.0 hub like I’ve seen some other threads mention and still no luck. Any help would be greatly appreciated!

Here’s the new code:

//Here we declare our server and our client objects
TCPServer server = TCPServer(80);
TCPClient client;

//Here we have the IP address for the other photon we're communication with and
//it's port number.
byte IP[4] = {192,168,11,101};
int port = 81;

//This is a value unique to this code to send out
byte val = 0x0f;

//Here's the pin for the button we're using
/*int buttonPin = D0;
//User LED pin
int userLED = D7;

//Array used for debouncing the switch
uint8_t debounce = 0b00000000;
//Holds the state of the userLED
bool userLED_state = false;*/

void setup() {
//Turn off wifi so we can set up our static ip
WiFi.off();
//Set static ip info
IPAddress myAddress(192,168,11,100);
IPAddress netmask(255,255,255,0);
IPAddress gateway(192,168,11,1);
IPAddress dns(192,168,11,1);
//Actually set the static ip
WiFi.setStaticIP(myAddress, netmask, gateway, dns);
//Tell the photon to use the static ip
WiFi.useStaticIP();
//Reconnect to wifi
WiFi.on();
WiFi.connect();

//Start listening for clients
server.begin();

//Start up serial so we can communicate various commands
Serial.begin(9600);
//Hold still and check wifi until we're connected over serial
while(!Serial.available()) Particle.process();
Serial.println("Sup guys! I'm Photon 1!");

//Print out wifi credentials, just to make sure everything is ok
Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("gateway IP: ");
Serial.println(WiFi.gatewayIP());
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

//Some pinMode calls to initialize our GPIO
/*pinMode(buttonPin, INPUT);
pinMode(userLED, OUTPUT);
digitalWrite(userLED, LOW);*/
}

void loop() {
//Runs for maintenance
Particle.process();

//If we're connected to a client, which we should be most of the time, send
//a value to the client to make sure we're connected. If not try to connect
//to a client.
if(client.connected())
{
    Serial.println("Oh hey there!");
    server.write(val);
}
else
{
    Serial.println("And nobody came....");
    client = server.available();
}

//Here we read
/*debounce = debounce<<1;
debounce |= digitalRead(buttonPin);
Serial.print("debounce: ");
Serial.print(debounce,BIN);
if(debounce == 0b10000000)
{
  userLED_state = true;
}
else if(debounce == 0b01111111)
{
  userLED_state = false;
}

Serial.print("\tUser LED state: ");
Serial.println(userLED_state);
digitalWrite(userLED, userLED_state);*/
delay(100);
}

Here’s the persistent old code:

TCPServer server = TCPServer(81);
TCPClient client;
byte IP[4] = {192,168,11,100};
int port = 80;
byte val = 0x0f;

void setup() {
    //Turn off wifi so we can set up our static ip
    WiFi.off();
    //Set static ip info
    IPAddress myAddress(192,168,11,101);
    IPAddress netmask(255,255,255,0);
    IPAddress gateway(192,168,11,1);
    IPAddress dns(192,168,11,1);
    //Actually set the static ip
    WiFi.setStaticIP(myAddress, netmask, gateway, dns);
    //Tell the photon to use the static ip
    WiFi.useStaticIP();
    //Reconnect to wifi
    WiFi.on();
    WiFi.connect();

    //Start listening for clients
    server.begin();

    //Start up serial
    Serial.begin(9600);
    while(!Serial.available()) Particle.process();
    Serial.println("Sup guys! I'm a client!");

    //Print out wifi credentials, just to make sure everything is ok
    Serial.print("Local IP: ");
    Serial.println(WiFi.localIP());
    Serial.print("Subnet Mask: ");
    Serial.println(WiFi.subnetMask());
    Serial.print("gateway IP: ");
    Serial.println(WiFi.gatewayIP());
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());

    if(client.connect(IP,port))
    {
        Serial.print("Oh hey there!");
    }
    else
    {
        Serial.print("And nobody came....");
    }
}

void loop() {
    Particle.process();
    if(client.available())
    {
        Serial.println("Here's a value! ");
        val = client.read();
        Serial.println(val);
    }
    if(!client.connected())
    {
        Serial.println();
        Serial.println("Ok bye...");
        client.stop();
        for(;;) Particle.process();
    }
    delay(100);
}

Are you using the Serial Monitor in Particle Dev? What happens if you press the disconnect/connect button after an OTA flash?

I’ve tried using the built in monitor and PuTTY to see if that makes any difference with no luck. I’m not sure if I tried disconnecting after an OTA flash, so I’ll give that a go when I get back to the lab tomorrow and update with what I find! Thanks for the reply!

If you’re running Window, make sure it’s showing up as a COM port in Device Manager. Sometimes it can be auto detected as that serial Ballpoint mouse.

@CuriousTech
Windows recognizes the board as a photon and I can see which COM port is assigned in the device manager, so I don’t think I’m having that particular issue.

@kennethlimcp
With the connect/disconnect button, you mean the button in the serial monitor build into Particle Dev correct? If that’s the case, what happens is when I hit connect initially it seems like the Serial Monitor connects as normal for a split second, moving my cursor to the “enter string to send” box before disconnecting on its own.

I got the board briefly working correctly this morning, I have no idea what I did to make that happen. There were no changes in chords, hubs or code. As soon as I un-commented the section of code below however, this problem immediately reemerged. It’s pretty weird. Thanks again for the replies!

debounce = debounce<<1;
debounce |= digitalRead(buttonPin);
Serial.print("debounce: ");
Serial.print(debounce,BIN);
if(debounce == 0b10000000)
{
  userLED_state = true;
}
else if(debounce == 0b01111111)
{
  userLED_state = false;
}

Serial.print("\tUser LED state: ");
Serial.println(userLED_state);
digitalWrite(userLED, userLED_state);

So I think I might be narrowing in on the problem. I can’t even flash new code now it turns out. I’ve tried commenting out all of the button reading code and just blinking the LED on D7 with this simple code below. I did make sure to comment out the line that waits for serial com’s since that’s where the whole issue lies and this change is just a sanity check. Maybe I should be worried it didn’t turn out well…

digitalWrite(D7, LOW);
delay(500);
digitalWrite(D7, HIGH);
delay(500);

The LED never flashes, so I figured I’m using Particle Dev improperly. I copy and pasted this code into Particle Build to try and do this online through another IDE and I get the same result. The indicator LED tells me everything is fine, magenta while flashing, then the standard pattern connecting to the cloud and then it breaths cyan. Maybe I should just try a new board? Hopefully that’s not the problem. The entire program is below in case there’s something I missed that I should have added.

//Here we declare our server and our client objects
TCPServer server = TCPServer(80);
TCPClient client;

//Here we have the IP address for the other photon we're communication with and
//it's port number.
byte IP[4] = {192,168,11,101};
int port = 81;

//This is a value unique to this code to send out
byte val = 0x0f;

//Here's the pin for the button we're using
int buttonPin = D0;
//User LED pin
int userLED = D7;

//Array used for debouncing the switch
uint8_t debounce = 0b00000000;
//Holds the state of the userLED
bool userLED_state = false;

void setup() {
//Turn off wifi so we can set up our static ip
WiFi.off();
//Set static ip info
IPAddress myAddress(192,168,11,100);
IPAddress netmask(255,255,255,0);
IPAddress gateway(192,168,11,1);
IPAddress dns(192,168,11,1);
//Actually set the static ip
WiFi.setStaticIP(myAddress, netmask, gateway, dns);
//Tell the photon to use the static ip
WiFi.useStaticIP();
//Reconnect to wifi
WiFi.on();
WiFi.connect();

//Start listening for clients
server.begin();

//Start up serial so we can communicate various commands
Serial.begin(9600);
//Hold still and check wifi until we're connected over serial
/*while(!Serial.available()) Particle.process();*/
Serial.println("Sup guys! I'm Photon 1!");

//Print out wifi credentials, just to make sure everything is ok
Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("gateway IP: ");
Serial.println(WiFi.gatewayIP());
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

//Some pinMode calls to initialize our GPIO
/*pinMode(buttonPin, INPUT);
pinMode(userLED, OUTPUT);
digitalWrite(userLED, LOW);*/
}

void loop() {
//Runs for maintenance
Particle.process();

//If we're connected to a client, which we should be most of the time, send
//a value to the client to make sure we're connected. If not try to connect
//to a client.
/*if(client.connected())
{
    Serial.println("Oh hey there!");
    server.write(val);
}
else
{
    Serial.println("And nobody came....");
    client = server.available();
}*/

//Here we read
/*debounce = debounce<<1;
debounce |= digitalRead(buttonPin);
Serial.print("debounce: ");
Serial.print(debounce,BIN);
if(debounce == 0b10000000)
{
  userLED_state = true;
}
else if(debounce == 0b01111111)
{
  userLED_state = false;
}

Serial.print("\tUser LED state: ");
Serial.println(userLED_state);
digitalWrite(userLED, userLED_state);*/
/*userLED_state = digitalRead(D0);
digitalWrite(D7, userLED_state);*/
digitalWrite(D7, LOW);
delay(500);
digitalWrite(D7, HIGH);
delay(500);
}

Try flashing while in Safe Mode.

I’ve tried that before, sorry I forgot to mention that. I tried again this morning with the same code I posted above and it doesn’t seem to actually make it onto the photon, i.e. D7 never flashes.

Oddly enough however, I can flash tinker onto the board from the phone app and I can turn D7 on and off from there so I don’t think this is a board issue, it has to be something wrong with my code. Maybe it’s how I’ve set up the static IP? I’ve tried disabling that with no luck. Theoretically I should be able to completely disconnect from wi-fi and still blink D7 right?

There was one mistake in the code above. I forgot to uncomment the pinmode calls for D7 and D0. I uncommented those and there was no change.

Maybe if I describe my goal here you might be able to point me in a direction maybe not. We’re building an installation for a learning center and we have several portions that will be on opposite sides of an atrium. We want these components to be able to communicate with each other relatively quickly, so I figured I could set up Photons as TCP servers and clients and then send the data over LAN to avoid possible issues with internet connectivity and to make sure the communication stays fast. I don’t know if any of that is helpful but I figured I might as well mention it.

@Cherler, just a few recommendations:

The code in setup() runs:

WiFi.on();
WiFi.connect();
server.begin();

I suggest you wait for WiFi.ready() to be true before doing server.begin. You can do with:

if (waitFor(WiFi.ready, timeout))
  server.begin();
else
  //timeout occured - Serial print an error??

You may want to test your code without a static IP (DHCP) to see if it works, then switch to static.

I’m not sure why you use debounce since you are reading the pin directly, not the entire port. As such, you can test the bit directly using HIGH or LOW.

You may want to enable system threading with SYSTEM_THREAD(ENABLED) at the top of your file. If you do, you can remove Particle.process() fromloop().

Finally, comment out everything in loop() except the LED blink code and see if that works. Then start adding things back.

Thanks for the reply @peekay123!

Thanks for the suggestions with waiting for WiFi.ready() and SYSTEM_THREAD(ENABLED), both of those sound like really good additions to the code.

I’ve tried commenting out everything you said, and I noticed that Particle Dev wouldn’t actually compile my code when I clicked on the compile in cloud option. Out of curiosity I decided to copy paste the code into the onlinde IDE and complie/flash from there. Suddenly it works! So I most definitely have something messed up in Particle Dev. I’m not sure why that didn’t work for me before, but I think it’s safe to assume the error was between my keyboard and my chair.

So is there a way to make sure that Particle Dev is compiling the right file and then flashing the right binaries? If it was using different files than the ones I was editing this whole time that would make a whole lot of sense.

Remove all binaries from your project folder and add a syntax error. If you build and don’t get an error message you are building the wrong project :wink:

I think that was the problem! Once I removed the binaries, it caught my intentional syntax error, compiled the newest code and flashed it onto the Photon! I added back some of the Serial functionality and I seem to be able to consistently connect to the serial port!

As of now, I’m removing the binary every time I want to compile the code. It’s a little bit of a pain but it seems to be working consistently. If I don’t it just flashes the last version again it seems. Is there a convenient way around this?

I think what happened was an old binary that didn’t have serial enabled was in the project folder and that’s all that was getting flashed. I probably had serial disabled for debugging in that binary and that’s what lead to my problems. At least that’s my theory.

I’m going to keep messing around with this and I’ll post back if the problem comes back or if I’m successful getting the data streaming working, thanks for all the help everyone!

1 Like