a strange thing is happening

hi there!

I’m having a strange phenomenon with a struct and two classes which contain it.

All the variables are supposed to have the same value (0), however when I print them I get some mistakes with a specific pattern…

  1. .129. .131. .END
  2. .14A. .141. .END
  3. .14D. .0. .END
  4. .0. .0. .END
  5. .0. .0. .END
  6. .0. .0. .END
  7. .0. .0. .END
  8. .0. .0. .END

the next iteration:

C69. .129. .F71. .END
135. .10A. .141. .END
147. .14D. .0. .END
0. .0. .0. .END
0. .0. .0. .END
0. .0. .0. .END
0. .0. .0. .END
0. .0. .0. .END

did i reach a bottleneck? or there could be a solution for this?

very strange… :-/

here is the code:

main

#include "pi_classes.h"

pi_row bi_row(8);


void setup(){
  Serial.begin(57600);
  
}

void loop(){
   
  bi_row.row_prtdat();
  Serial.println("  ");
  delay(20000);

}

pi_classes.cpp

#include "pi_classes.h"

pi_row_led::pi_row_led(pi_row_led_col led_in_r, pi_row_led_col led_in_g, pi_row_led_col led_in_b){
  
  led_r.cdata = led_in_r.cdata;
  led_g.cdata = led_in_g.cdata;
  led_b.cdata = led_in_b.cdata;
  
}

void pi_row_led::change_r(pi_row_led_col led_in_r) { led_r.cdata = led_in_r.cdata; }
void pi_row_led::change_g(pi_row_led_col led_in_g) { led_g.cdata = led_in_g.cdata; }
void pi_row_led::change_b(pi_row_led_col led_in_b) { led_b.cdata = led_in_b.cdata; }

pi_row_led_col pi_row_led::get_r() { return led_r; }
pi_row_led_col pi_row_led::get_g() { return led_g; }
pi_row_led_col pi_row_led::get_b() { return led_b; }


// *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .*


pi_row::pi_row (byte pi_row_len_in) {
  
  pi_row_len = pi_row_len_in;
  
  pi_row_led_col col_tmp;
  col_tmp.cdata = 0;
  
  row_pix[pi_row_len];
  row_pix_pnt[pi_row_len];
  for (byte i = 0; i < pi_row_len; i++) { 
    
    row_pix_pnt[i] = &row_pix[i];
    row_pix[i].change_r(col_tmp);
    row_pix[i].change_g(col_tmp);
    row_pix[i].change_b(col_tmp);    
    
  }
  
}

void pi_row::row_prtdat() { 
  
    for (byte i = 0; i < pi_row_len; i++) { 
      
    Serial.print(row_pix[i].get_r().cdata, HEX);
    Serial.print(".  .");
    Serial.print(row_pix[i].get_g().cdata, HEX);
    Serial.print(".  .");
    Serial.print(row_pix[i].get_b().cdata, HEX);
    Serial.println(".  .END");
    
  }
  
}

classes.h

#include <WProgram.h>

struct pi_row_led_col {
  unsigned cdata:12;
};

class pi_row_led {

  public:

  pi_row_led(pi_row_led_col led_in_r, pi_row_led_col led_in_g, pi_row_led_col led_in_b);
  void change_r(pi_row_led_col led_in_r);
  void change_g(pi_row_led_col led_in_g);
  void change_b(pi_row_led_col led_in_b);

  pi_row_led_col get_r();
  pi_row_led_col get_g();
  pi_row_led_col get_b();
  
  private:

  pi_row_led_col led_r;
  pi_row_led_col led_g;
  pi_row_led_col led_b;

}; 


// *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .* *. .*


class pi_row {
  
  public:
  
  pi_row(byte pi_row_len_in);
  byte pi_row_len;
  void row_prtdat();

  private:
  pi_row_led row_pix[];
  pi_row_led *row_pix_pnt[];
  
};
  private:
  pi_row_led row_pix[];
  pi_row_led *row_pix_pnt[];

Just how big is the row_pix array?

  row_pix[pi_row_len];
  row_pix_pnt[pi_row_len];

What do you think this code is doing?

In reality it is dereferencing the pi_row_len element of the array (whose size is undefined), and discarding the dereferenced value.

hi,

when the object is constructed the size of the array is define through the variable pi_row_len, this means that the array size is == pi_row_len. I'm wrong??

I removed the pointer and kept getting a smaller mistake...

  1. .0. .1. .END
  2. .C. .0. .END
  3. .0. .0. .END
  4. .0. .0. .END
  5. .0. .0. .END
  6. .0. .0. .END
  7. .0. .0. .END
  8. .0. .0. .END

thanks!!!

I'm wrong??

Yes. You can't dynamically set the size of an array.

To use dynamic datatypes you have to use malloc() free() and pointer math ... Not that it becomes easier to do (correctly)

And with “struct pi_row_led_col { unsigned data:12; };” you’re being misled as this is in reality occupying 16-bits, the sizeof(int) which is the default data type when specifying just “unsigned” as the data type.

Verify by printing the sizeof(pi_row_led_col)!

Hi! thanks for your feedback.

I realized that the whole thing can de done easily with structures. I post the code if someone have also this trouble.

struct pi_col {
unsigned col:
  12;
};

struct pi_led {
  pi_col r;
  pi_col g;
  pi_col b;
};

struct pi_row {
  pi_led led[8];
};

pi_row bi_row;

And with "struct pi_row_led_col { unsigned data:12; };" you're being misled as this is in reality occupying 16-bits, the sizeof(int) which is the default data type when specifying just "unsigned" as the data type.

Verify by printing the sizeof(pi_row_led_col)!

I also had my doubts but I tested the method and is working fine... sizeof returns 2 because sizeof returns the number of bytes as an integer and 12 bits make 1.5 byte. I tried with an struct which had 2x12bits = 24bits and sizeof returned 3...

thanks for your help.

You can try this: [NOT ACTUALLY TESTED]

struct test1 {  unsigned  data1:12; };
struct test2 {  unsigned  data1:12; unsigned  data2:12; };

void  setup() {
  Serial.begin(9600);
  
  Serial.print("sizeof test1: "); Serial.println(sizeof(test1));
  Serial.print("sizeof test2: "); Serial.println(sizeof(test2));

  test1 test1x10[10];
  test2 test2x10[10];


  Serial.print("sizeof test1x10: "); Serial.println(sizeof(test1x10));
  Serial.print("sizeof test2x10: "); Serial.println(sizeof(test2x10));
}
void loop() {}

I also had my doubts but I tested the method and is working fine... sizeof returns 2 because sizeof returns the number of bytes as an integer and 12 bits make 1.5 byte. I tried with an struct which had 2x12bits = 24bits and sizeof returned 3...

My mistake I specified the wrong struct. I meant to use the whole rgb-triple with sizeof(pi_led).