Publish issue within state machine --- not printing cycle 3?

The reference docs will help solve that puzzle too

Your burst go through, till they don't anymore and then you have a cool down phase after which the first few can go through again but never all of them.

If you only want to redirect the output I'd suggest you keep the other code exactly the same or even better have one code do the preparation for the output and then only use that so prepared data either way.

something like this

         case PUBLISH: {
             char msg[1024];
             for ( current = 0; current < 4; current++ ) {
               snprintf(msg, sizeof(msg)
                 , "Cycle [mA]  Vbias   SiPM   LED1   LED2     Tw    Tbd       [ms]\r\n"
                   "%-4d %5.1f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %10lu"
                 , ((readCycle > 0) ? readCycle : 3)
                 , DAC_C[current]
                 , SensorDataPerCyclePublish.Vbias[current]
                 , SensorDataPerCyclePublish.SiPMCurrent[current]
                 , SensorDataPerCyclePublish.LED1Current[current]
                 , SensorDataPerCyclePublish.LED2Current[current]
                 , SensorDataPerCyclePublish.w_temp[current]
                 , SensorDataPerCyclePublish.bd_temp[current]
                 , millis()
               );
#ifdef TEST
               Serial.println(msg);
#else
               Particle.publish("readings", msg);
               delay(1000);
#endif
             }
             sm = (readCycle ? SOLENOID_POWER : SOLENOID_NOPWR);
         }
         break;

BTW, your pointer arithmetic here

could do with some clarification.
For one I'm surprised the pointer assignment didn't throw an error (it may have thrown a warning) since your seem to be assigning a *float[] pointer *float which should be incompatible in C++.
Given the definition here

I think it should be

float* pPublish = &SensorDataPerCyclePublish.Vbias[0][0];

If the above should not be the definition for sensorDataPerCyclePublish could you make it a habit to also provide the definitions of any non-trivial variables (as we already pointed out in multiple other discussions with you)?

Also - providing above definition does fit - I'd propose a more readable and clearer syntax for populating your data fields

const int SENSORS_COUNT  = 3;
const int CURRENTS_COUNT = 4;
...
  float (*pPublish)[CURRENTS_COUNT] = SensorDataPerCyclePublish.Vbias[0]; // should not be redefined inside loop over and over as it won't change between iterations anyhow
  for (current = 0; current < CURRENTS_COUNT; current++) {
    ...
    for (uint8_t sensor = 0; sensor < SENSORS_COUNT; sensor++){
      float k = GetAverage((&ReadingArray[sensor][0]), NUMBER_SAMPLES);
      pPublish[sensor][current] = k; // clearer than the "out of order" offsets 
    }
  }

It would also be advisable to have your array dimensions dynamic (use constants instead of anonymous numbers - as in my code above) to keep any reference to them consistent.
e.g. with

  for (current = 0; current < 4; current++) {
     ...
    for (uint8_t arr = 0; arr < NUMBER_SENSORS; arr++){
      float k = GetAverage((&ReadingArray[arr][0]), NUMBER_SAMPLES);
      *(pPublish + current + 4*arr) = k; //stuff struct t_PublishData
    }
  }

(i.e. is that 4 in 4*arr the same as the 4 in the outer loop? Or is NUMBER_SENSORS == 4)
You have a hard relationship between NUMBER_SENSORS and 4*arr and pPublish which comes with some ambiguity just reading the code and moreover will cause problems anytime you may decide to change one of these but forget to also apply the change to all entities related to that change.
Particularly without explicit validity checks where your pointer arithmetic will point to this is a recipe for trouble.

1 Like