0

I wrote the code below and the result is not what I expected at all! I'm not sure why it's happening!

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

const uint8_t pat[] PROGMEM = {
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x66
};

void loop() {
  delay(100);
  Serial.println(sizeof(pat));
  for (int i=0; i<8; i++){
    Serial.print(pat[int(i)],HEX);
  }
  Serial.println("");
  Serial.print(pat[0],HEX);
  Serial.print(pat[1],HEX);
  Serial.print(pat[2],HEX);
  Serial.print(pat[3],HEX);
  Serial.print(pat[4],HEX);
  Serial.print(pat[5],HEX);
  Serial.print(pat[6],HEX);
  Serial.print(pat[7],HEX);
  Serial.println("");
  while(true);
}

the output is surprisingly this:

8

008000010

FF0FF0FF0FF66

What is compiler doing in the background but it seems to be messing things up really bad! The loop should be doing the exact same thing as manually writing that code over and over but it's not! How can I fix the loop?

1
  • does the output represent one iteration of loop()? ..... you really need to print a delimiter by using something like Serial.println("--------------");
    – jsotola
    Feb 10, 2019 at 21:52

1 Answer 1

1

If you want to get a value from PROGMEM you must read it with pgm_read functions. Read the PROGMEM reference.

for (int i = 0; i < 8; i++) {
  Serial.print(pgm_read_byte_near(pat + i),HEX);
}

pat[0] in Serial.print(pat[0],HEX); is an item in a constant array const uint8_t pat[]. it can't change at runtime so the compiler uses the value 0xFF. that is why it is printed ok without pgm_read_byte_near

6
  • that would explain it, but why when I write pat[6] manually in print statement, it doesn't return the same value? somehow only the loop values are replaced at compile time?
    – OM222O
    Feb 10, 2019 at 22:00
  • @OM222O, as I write in the answer, the constant uses are replaced at compilation
    – Juraj
    Feb 11, 2019 at 10:31
  • My question still remains: Why is the code in the loop SPECIFICALLY replaced during compilation? if I do something i=0; print(pat[i]); it should not be different to print(pat[0]); ! it's almost as if the compiler is treating integers differently!
    – OM222O
    Feb 11, 2019 at 19:25
  • because using the value from the array position requires less instructions then getting the value from the array every time. the compiler optimizes for small size of the binary
    – Juraj
    Feb 11, 2019 at 20:39
  • that wouldn't make a ton of sense! they're both ints! I even made sure to use int(i)! The int is created and the increased ever cycle the program runs!
    – OM222O
    Feb 12, 2019 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.