Different behaviour between Photon and Argon

I have been testing code that worked on a Photon but is not working on an Argon. to home in on the problem I have cut a small test program based on a simple finite state model.

When run on a Photon (firmware 0.7) the D7 led is lit for approx 10 seconds, goes off for approx a second then the pattern repeats itself.

When the same code is built and executed on an Argon using RC26 the D7 led fllashes at a constant rate of the order of 1 second rather than the 10sec/1sec pattern observed on Photon.

Can anyone shed light on this behaviour ? Is there a bug in my code - but if so why do Photon and Argon behave quite differently?

I was going to try again with RC27 but have to work out how to install the DFU driver on Windows 10.

#include "Particle.h"
enum State {state_WAITING,state_CONNECT,state_RUNNING,state_FINISH};
State state=state_WAITING;
int count=0;

void setup() 
{
  Serial.begin(9600);
  pinMode(D7,OUTPUT);
  state=state_WAITING;
}

void loop() 
{
switch(state)
  {
    case state_WAITING:
    count=count+1;
    if (count>1000) {state=state_CONNECT;};
    break;

    case state_CONNECT:
    digitalWrite(D7,HIGH);
    state=state_RUNNING;

    break;

    case state_RUNNING:
    count=count+1;
    if (count> 10000) {state=state_FINISH;};
    break;

    case state_FINISH:
    digitalWrite(D7,LOW);
    delay(500);
    count=0;
    state=state_WAITING;
  }
}

The frequency of the calls to loop varies between devices and whether or not you’re using SYSTEM_THREAD(ENABLED) or not. On the Photon, it’s almost always 1000 times per second. On the Electron it can be as low as 100 times per second. In other cases, the loop will be free-running, called as often as possible, potentially in the hundreds of thousands of times per second.

I’m not positive that’s what’s happening, but that would be my guess.

1 Like

To put it blunt: Don’t use an iteration count for anything timing related.

There are better ways than that - the most common and widely used one is by use of the millis() count.

BTW, an an FSM there is no rightful place for delay(500) :wink:

To illustrate the millis() timing

void loop() {
  static uint32_t msStateTime = 0;
  switch {
    case state_WAITING:
      if (millis() - msStateTime >= 1000) {
        state = state_CONNECT;
        msStateTime = millis();
      }
      break;

    case state_CONNECT:
      digitalWrite(D7,HIGH);
      state = state_RUNNING;
      msStateTime = millis();
      break;

    case state_RUNNING:
      if (millis() - msStateTime >= 10000) {
        state = state_FINISH;
        msStateTime = millis();
      }
      break;

    case state_FINISH:
      digitalWrite(D7, LOW);
      if (millis() - msStateTime >= 500) {
        state = state_WAITING;
        msStateTime = millis();
      }
      break;
  }
}
3 Likes

I was working on the incorrect assumption that the loop timing was the same for all the processors. I am about to conduct some more careful tests on all 4 processors (Photon, Electron, Argon and Boron).

My ideal is to move to DMA based acquisition as that proved much more reliable than software timer-based acquisition at sampling frequencies of 2-500 Hz. Have you had the opportunity to revisit your DMA based ADC sampling using the HAL code for the mesh series processors?

Thanks

1 Like

Thanks. You are of course correct on all counts - Indeed I should have said ‘quick and very dirty’ code :smirk:!

My current operational code uses 3 software timers as well as millis() and Rick’s DMA based ADC code. In the absence of the equivalent DMA code for the Argon and Boron (which requires access to the underlying HAL code) I am having to revert to timer based ADC sampling. A pity since the DMA technique was much more reliable at sampling rates above 200 Hz than the software timer based approach.

At 18 pages long and having been developed iteratively it could do with a tidy up as well. I decided to build it up again in stages testing against all 4 processors as I go. This was a quick and dirty test of my ability to use Workbench. Although Workbench has some rough edges it proved a very effective tool. I was puzzled by the difference but should have developed a more careful test before firing it off to the bulletin board.

Thanks for your comments - like many on the board I appreciate your effort and commitment to providing comments on a large number of posts.

2 Likes

I’d like to add my appreciation to both @rickkas7 and @ScruffR for their contributions here and elsewhere…and to +1 to @OziGreybeard for DMA based ADC code to be translated to the Argon.

I’ve previously had @rickkas7 photonAudio working on a photon, compiled and flashed via the Web IDE, but:

  1. that doesn’t compile on the Web IDE when configured for Argon and
  2. doesn’t compile for Photon nor Argon on Workbench. (identifier RCC_AHB1PeriphClockCmd (and many other hardware related identifiers) undefined. This could be because STM32F2xx isn’t defined in Workbench, but I’m unsure of that, and of how to proceed further…

any suggestions welcome…

Sadly the answer is this is not likely to be available any time soon. There are fundamental software access limitations as identified in @rickkas7’s comments on a seperate thread. Let’s see if we can get the DMA added to Particle’s development program.

thanks @OziGreybeard- I can stay with Photon, but was attracted to the floating point hardware on Argon (much faster, although only for single precision).

But I can’t get photonAudio3 to even compile on Workbench- have you managed that?

I was able to compile it

@ScruffR : I can also now compile- created empty new project, git init and clone, moved photonAudio3 into/src and it worked first time- which is what I thought I’d done previously. Obviously not.

I’ll be more careful next time- but thanks for the nudge.

1 Like