Cannot flash code after firmware update

@corey, @bko First up big thanks to all particularly @ScruffR. I have proven there is definitely a problem / anomaly running software on firmware 0.4.6 that works on version 0.4.5. Luckily, we have found the bug – and it’s simple – a delay is required in the serial comms code. The following code ( a snippett from our project) without the 300ms delay at the end causes the crashes described in the following “Test Results’ part of this post. This was tested on two rigs. I hope this might be of help to someone.
Code....

if (Serial1.available() > 0)
{
newVolumeReading = 0;

    while(1)
    {
        inByte = Serial1.read();
        if( (inByte >= '0') && (inByte <= '9') )
        {
            inString[stringPos] = inByte;
            stringPos++;
        }
        //if there is a line end character, this string is done. Clear the string when done
        if(inByte == '\r')
        {
             newVolumeReading = atoi(inString);
             newVolumeReading = 10*newVolumeReading;
             //clear values from string
             for (int c =0; c < stringPos ; c++ )
             {
                 inString[c] = 0;
             }
             stringPos = 0;
             break;
        }
        delay(300);
    }

Test Results
Test setup Photon connected by serial to Moteino 1. Photon connected to a sensor via A0. Moteino 1 maintains radio connection to a second Moteino (Moteino 2), which sends a “ping” to Moteino 1 every 20 seconds – after every ping, serial communication is commenced between Moteino 1 and Photon.
Test results

  1. If I load blinky, with the Photon not in circuit, i.e. just hooked up to a USB power source - no problem – breaths cyan and all good
  2. If I load my code and have the Photon as above (not in circuit) the photon will breath cyan for about 3 to ten seconds – then crash and commence breathing green (not cyan).
  3. If I put the photon in circuit – but do not initiate any serial communication with the Moteino, the photon will operate normally, breathing Cyan and updating a webhook that reads values from the pressure sensor. Tested for 15 minutes – and observed both in place and on the Particle dashboard.
  4. If I maintain the conditions set above, and commence serial transmission from the Moteino to the Photon the Photon will crash within 3 seconds of receiving the first serial data. It will make several attempts to reconnect to WiFi, on one occasion breathing cyan for nearly a minute – then it will crash and breathe green until the program cycle (three minutes is up) – and it will reset and the process repeats. Watching the Particle dashboard, I can see it come online, then offline about ten to 12 times – then stay offline.
1 Like

There are some possible issues with that code that might explain what you see and why the delay() helps.

One thing is the while(1) that only breaks out under circumstances that might not occure in time.
When running in default SYSTEM_MODE(AUTOMATIC) (without SYSTEM_THREAD(ENABLED) under 0.4.6) you need to make sure to allow for cloud service by either droping out of loop() every few (<10) seconds, or explicitly calling Particle.process(), or having a delay() which in turn calls Particle.process() implicitly once per waited second (cummulated).
The latter is (I think) also the reason why the delay(300) helped (try reducing it to delay(1)).

Another possible issue is that I can’t see a range check for this part

    if( (inByte >= '0') && (inByte <= '9') )
    {
        inString[stringPos] = inByte;
        stringPos++;
    }

There is the possibility that stringPos overruns inString[] causing lots of trouble.
Always add a range check, even if you think it’ll never overrun.
If you miss the one '\r' you are waiting for (for whatever reason), you’re doomed :wink:
Good code needs to be error tolerant.

The same goes for breaking out of while(1), if you miss (or just don’t get) the '\r', you might want to put a timeout in place and deal with that case explicitly.

I’d suggest instead of doing this

  if (Serial1.available() > 0)
  {
    ...
    while(1)
    {
      ...
      if (someCondition)  // which might fail to come
        break;
    }
  }

to do something like this (pseudocode)

  while(Serial1.available() && timeoutNotReached())
  {
    ...
  }
  if (timedOut)
  {
    ...
  }
  if (msgNotComplete)
    setCarryOnFlag;

And you could also give the beta feature SYSTEM_THREAD(ENABLED) a try :wink:


But it’s not clear to me why the same problem does not show up under 0.4.5 :confused:
An unverified possibility might be that Serial1 got somehow crippled, which now makes the missing error tolerance noticable.

So my suggestion would be to have a closer look at the raw serial data being received by the Photon with 0.4.6 and see if there is something fishy with that.
I hope to get a second oppinion on this from @bko

3 Likes