Array not updating.....?

Can someone tell me what I am doing wrong:

    switch (sensor){
      case 0:
        pSensorData->Vbias[readCycle][sensor] = avg;  
        Serial.printlnf("%.2f", pSensorData->Vbias[readCycle][sensor]);      
        break;
      case 1:
        pSensorData->SiPMCurrent[readCycle][sensor] = avg; 
        Serial.printlnf("%.2f", pSensorData->SiPMCurrent[readCycle][sensor]);
        break;
      case 2:
        pSensorData->LEDCurrent[readCycle][0][sensor] = avg; 
        Serial.printlnf("%.2f", pSensorData->LEDCurrent[readCycle][0][sensor]);
        break;
      case 3:
        pSensorData->LEDCurrent[readCycle][1][sensor] = avg; 
        Serial.printlnf("%.2f", pSensorData->LEDCurrent[readCycle][1][sensor]);
        break;
      default:
        break;
    }    

If I replace each of the above printf with avg they work yet when I do the assignment and try and print it it prints 0.00 always…somehow the assignment isnt working

Here is a partial serial printout showing that cycle and current which the variables in the array are based on are changing …

0 — Cycle, 0 ---- Current
0 ---- Sensor
0.00
1 ---- Sensor
0.00
2 ---- Sensor
0.00
3 ---- Sensor
0.00

Hi,

could you please share the definition and declaration of the following variables:

  • pSensorData
  • Vbias
  • SiPMCurrent
  • LEDCurrent

On the top of my head I expect an incompatible datatype with the format string %f.

I’d have a similar suspicion as @johannes.nuwiel, but I’d also like to point out a possible way to find out what’s going on by directing you to the compile output (i.e. printf() datatype incompatibilities should be flagged as warnings).

Depending on your build environment you may need to take some extra steps for it to show you the warnings.
Particularly Web IDE is a bit of a pain in that regard as it will only show you the warnings list when your code has at least one critical error.
I usually add a stray { at the end of my code to trigger that error and then look at the SHOW RAW output for any warnings.

2 Likes

Declaration :

typedef struct {
  float Vbias[3][4]; //indexing reading 1/2/3 ; 10/50/100/200 mA
  float SiPMCurrent[3][4];  //indexing reading 1/2/3 ; 10/50/100/200 mA
  float LEDCurrent[3][2][4]; //indexing reading 1/2/3 ; LED 1/2 ; 10/50/100/200 mA
  float w_temp[3][4];  //indexing reading 1/2/3 ; 10/50/100/200 mA
  float bd_temp[3][4]; //indexing reading 1/2/3 ; 10/50/100/200 mA
} t_SenseDataRaw;

Definition:

t_SenseDataRaw SensorData = {0}, *pSensorData;

Hi again,

I hate to say this because I always read in other forums but it’s always good to provide the original code in all it’s consistency. Unfortunately, I am not able to solve your problem but I have a few suggestions you could try.

Is it correct that you intialize pSensorData on the same stack as the forementioned switch-case directive? Otherwise I wouldn’t be sure about the correct initialization of the underlying 2D-arrays and their availability when calling.

Other than that, I haven’t seen the use of Serial.printlnf. You may want to use Serial.print or Serial.println.

Finally, print the raw value of the array contents and check for non-zero values. In that case the format string might not be correct or the decimal point is at a wrong position. Plus I guess that variable avg is also of type float.

I hope this helps fixing your problem. Without any further error description I am not able to help you.

1 Like

Just a point of interest: You have switch(sensor) and then in each case use sensor as variable to reference the last dimension of your arrays - hence the last dimension seems somewhat superfluous.
Although seeing the entire code might clear that confusion :wink:

@johannes.nuwiel, Serial.printlnf() is a convenient (and proven) combination that acts like shorthand for

  char txt[1024];
  snprintf(txt, sizeof(txt), "...", ...);
  Serial.println(txt);

However, checking its result against vanilla Serial.println() won’t harm and may even reveal a bug in its implementation :blush:


I tested the code we got so far, and when used this way it works as expected :wink:

typedef struct {
  float Vbias[3][4]; //indexing reading 1/2/3 ; 10/50/100/200 mA
  float SiPMCurrent[3][4];  //indexing reading 1/2/3 ; 10/50/100/200 mA
  float LEDCurrent[3][2][4]; //indexing reading 1/2/3 ; LED 1/2 ; 10/50/100/200 mA
  float w_temp[3][4];  //indexing reading 1/2/3 ; 10/50/100/200 mA
  float bd_temp[3][4]; //indexing reading 1/2/3 ; 10/50/100/200 mA
} t_SenseDataRaw;

t_SenseDataRaw SensorData = {0}, *pSensorData;

void setup() {
  pSensorData = &SensorData;
}

void loop() {
   static int sensor = 0;    
   int readCycle = random(3);
   float avg = random(1000) / 100.0;
   sensor++;
   sensor %= 4;
   switch (sensor){
      case 0:
        pSensorData->Vbias[readCycle][sensor] = avg;  
        Serial.printlnf("%.2f (%d, %d)", pSensorData->Vbias[readCycle][sensor], readCycle, sensor);      
        break;
      case 1:
        pSensorData->SiPMCurrent[readCycle][sensor] = avg; 
        Serial.printlnf("%.2f (%d, %d)", pSensorData->SiPMCurrent[readCycle][sensor], readCycle, sensor);
        break;
      case 2:
        pSensorData->LEDCurrent[readCycle][0][sensor] = avg; 
        Serial.printlnf("%.2f (%d, %d)", pSensorData->LEDCurrent[readCycle][0][sensor], readCycle, sensor);
        break;
      case 3:
        pSensorData->LEDCurrent[readCycle][1][sensor] = avg; 
        Serial.printlnf("%.2f (%d, %d)", pSensorData->LEDCurrent[readCycle][1][sensor], readCycle, sensor);
        break;
      default:
        break;
    }    
    delay(100);
}
4 Likes

Hi ScruffR,

thanks for elaborating that! I guess there is always something one don’t know.

2 Likes

Well…not really sure why the pointer method isn’t working other than I can tell you it has to do with the assignment not the printlnf.

I was able to replace the pointers with code like (using . operator):

SensorData.Vbias[readCycle][sensor] = avg;

and all works fine…If I keep this statement in the printlnf but replace the assignment back to the pointer I again get 0.

At this time I have to move on …Would like to hear if you have any thoughts but not necessary.

As a side note I try to send code that is indicative of the situation and not all the code as it becomes overwhelming to look at a 1000 lines of code.

As we already said, without seeing your entire code we won’t be able to spot your error.
But since the pointer method works fine in my test code I’d think you are doing something wrong when assigning yours.

BTW, if you happen to use Web IDE you can always post a SHARE THIS REVISION link.
Since we do have a hunch what may be the reason we’d probably not need to read the entire 1000+ lines :wink:

Rereading this code for some other reply here just raised another question.
Why would you interject that extra dimension between the common two dimensions for all the other fields?

float LEDCurrent[2][3][4];

would be much cleaner and also allow for a generalized treatment of all fields in your struct.
This would even allow for a common typedef for float[READINGS_COUNT][CURRENTS_COUNT] to which you could refer all over your code for consistency, maintainability and code safety.

2 Likes

so what i’m attempting to do is, get the data entered in forms and store them in their respective variables within an object. After that I want to append said object to an empty array and repeat the process. using the function showMe() ., i want to print value at specified index. However, no matter the index i set, it only gives me the value of last item added to the array. Where did i go wrong??

var USERS = [];



var user= {

    firstName: "None",
    lastName : "None",
    age : 0,
    bodyType : "None",
    height : 0,
    bdayDay : 0,
    bdayMonth : "None",
    bdayYear : 0,
    gender: "None"

};

function addnew(){


   user.firstName = document.getElementById("fname").value;

   user.lastName =  document.getElementById("lname").value;

   user.age = document.getElementById("age").value;

   if (document.getElementById("genMale").checked)
        user.bodyType = document.getElementById("btMale").value;
   else
        user.bodyType = document.getElementById("btFemale").value;;


user.height = document.getElementById("Height").value;

    if (document.getElementById("genMale").checked)
        user.gender =  document.getElementById("genMale").value;
    else 
        user.gender = document.getElementById("genFemale").value;

    USERS.push(user);


}

function showMe(){

console.log(USERS[1].firstName);
}

When you create an object, push it to an array, and then further edit the object, you edit the object in the array as well because the array just holds a reference to the object.

For example:

var obj = {
    name:'mark'
}

var arr = [obj]
console.log(arr)
// [ { name: 'mark' } ]

obj.name= "tom"
console.log(arr)
//[ { name: 'tom' } ]

Basically, I have faced this issue on industry specific erp and related things.
You are overwriting your object in the array every time. You can instead do something like:

function addnew(){
   var user = {}
   user.firstName = document.getElementById("fname").value;
   // etc.
}

To create a new object every time the function runs.

Alternatively, you could use an approach where you define a constructor function and call new when you want to create an object:

function User(){
    this.firstName = "None"
    this.lastName = "None"
    this.age = 0
    this.bodyType = "None",
    this.height = 0
    this.bdayDay = 0
    this.bdayMonth = "None"
    this.bdayYear = 0
    this.gender = "None"
}

function addnew(){
   var user = new User()
   user.firstName = document.getElementById("fname").value;
   // etc.
}

This has the advantage of later being able to organize behaviour by defining methods on the User prototype.

It can be done also with -

var USERS = [];
var defaultUser= {
    firstName: "None",
    lastName : "None",
    age : 0,
    bodyType : "None",
    height : 0,
    bdayDay : 0,
    bdayMonth : "None",
    bdayYear : 0,
    gender: "None"
};

function addnew(){
   const newUser = {
       firstName: document.getElementById("fname").value,
       lastName:  document.getElementById("lname").value,
       age: document.getElementById("age").value,
       height: document.getElementById("Height").value,
       gender: document.getElementById("genMale").checked
           ? document.getElementById("genMale").value
           : document.getElementById("genFemale").value,
       bodyType: document.getElementById("genMale").checked
           ? document.getElementById("btMale").value
           : document.getElementById("btFemale").value
   };

   USERS.push(
       Object.assign(defaultUser, newUser); //creates a new object with defaults
   );
}

function showMe(){
    console.log(USERS[1].firstName);

Hope this article helps everyone properly.