incorrect/unexpected array test serial print out

When I serial print part of the array “BASE_TEMPLATE”. It does not display the data I am expecting, also the format is not quite right. I am not sure where my error is. The array is destined to be written on to some eeproms.

CODE:

I was gunna post it direct, but it is about 400 lines so I put in an attached txt.

What I am expecting to see is this:

0000: 30 00 00 90
0001: C0 00 00 68
0002: 00 00 00 00
0003: 00 00 00 00
0004: 00 00 00 00
0005: 00 00 00 00
0006: 00 00 00 00
0007: 00 00 00 00
0008: 00 00 00 00
0009: 00 00 00 00
000A: 00 00 00 00
000B: 00 00 00 00
000C: 00 00 00 00
000D: 00 00 00 00
000E: 00 00 00 00
000F: 00 00 00 00

But Instead am getting this:

0000: 00 90 2000 68
0001: 00 90 2000 68
0002: 00 90 2000 68
0003: 00 90 2000 68
0004: 00 90 2000 68
0005: 00 90 2000 68
0006: 00 90 2000 68
0007: 00 90 2000 68
0008: 00 90 2000 68
0009: 00 90 2000 68
000a: 00 90 2000 68
000b: 00 90 2000 68
000c: 00 90 2000 68
000d: 00 90 2000 68
000e: 00 90 2000 68
000f: 00 90 2000 68

I am doing my best to learn and understand the code. But it is not really my code, I just adapted it to fit my application. I have been pretty successful so far with other code I’ve modified, but this has me a little stumped.

Thanks

arduino code.txt (59 KB)

const PROGMEM uint32_t BASE_TEMPLATE[256][16]
...


char buf[80];
    sprintf(buf, "%04x: %02x %02x    %02x %02x ",
      address, BASE_TEMPLATE[0][0], BASE_TEMPLATE[0][1], BASE_TEMPLATE[0][2], BASE_TEMPLATE[0][3], BASE_TEMPLATE[0][4], BASE_TEMPLATE[0][5], BASE_TEMPLATE[0][6], BASE_TEMPLATE[0][7],
       BASE_TEMPLATE[0][8], BASE_TEMPLATE[0][9], BASE_TEMPLATE[0][10], BASE_TEMPLATE[0][11], BASE_TEMPLATE[0][12], BASE_TEMPLATE[0][13], BASE_TEMPLATE[0][14], BASE_TEMPLATE[0][15]);
       
      Serial.println(buf);

You know those special instructions you need to read from PROGMEM?

Where are they?

no, i am not too familiar with those, I only know of the "memcpy_P" cmd. from the context of the original code, but it did not seem to apply or would not work in my application due to ram limits.

could you give me some ideas on how to apply these instructions, or direct me somewhere i could learn how?

Thank you!

You could look at the PROGMEM page in the references.

I have been reading the PROGMEM reference page, but it is a lot to absorb and understand. I think what I need to use is the “pgm_read_word_near” cmd but I am struggling to get the proper syntax. I am having a hard time translating the example to my project. It then also sounds like I will need to use a bit shift on a second pass to read all 4 bytes in that location. correct?

does anyone have some sample code that could demonstrate what i am trying to achieve? it is so much easier to understand what it’s doing when you can see it function, I am flying pretty blind right now.

I am struggling to get the proper syntax.

Please post your best effort

attempt 1 - using pgm_read_word_near

//Program data bytes
Serial.println(“Programming EEPROM”);
for (long address = 0; address < 16; address += 1) {

char buf[80];
sprintf pgm_read_word_near(buf, "%04x: %02x %02x %02x %02x ",
address, BASE_TEMPLATE[0][0], BASE_TEMPLATE[0][1], BASE_TEMPLATE[0][2], BASE_TEMPLATE[0][3], BASE_TEMPLATE[0][4], BASE_TEMPLATE[0][5], BASE_TEMPLATE[0][6], BASE_TEMPLATE[0][7],
BASE_TEMPLATE[0][8], BASE_TEMPLATE[0][9], BASE_TEMPLATE[0][10], BASE_TEMPLATE[0][11], BASE_TEMPLATE[0][12], BASE_TEMPLATE[0][13], BASE_TEMPLATE[0][14], BASE_TEMPLATE[0][15]);

Serial.println(buf);

}
Serial.println(“done”);


attempt 2 - using (F macro

//Program data bytes
Serial.println(“Programming EEPROM”);
for (long address = 0; address < 16; address += 1) {

char buf[80];
sprintf(F(buf, "%04x: %02x %02x %02x %02x ",
address, BASE_TEMPLATE[0][0], BASE_TEMPLATE[0][1], BASE_TEMPLATE[0][2], BASE_TEMPLATE[0][3], BASE_TEMPLATE[0][4], BASE_TEMPLATE[0][5], BASE_TEMPLATE[0][6], BASE_TEMPLATE[0][7],
BASE_TEMPLATE[0][8], BASE_TEMPLATE[0][9], BASE_TEMPLATE[0][10], BASE_TEMPLATE[0][11], BASE_TEMPLATE[0][12], BASE_TEMPLATE[0][13], BASE_TEMPLATE[0][14], BASE_TEMPLATE[0][15]));

Serial.println(buf);

}
Serial.println(“done”);


i am thinking about the memcpy_p cmd, i think it can work too, my array is setup as an array of arrays, if i could copy each inner array over to ram one at a time, and then print…

here is an exerpt of some code i am working from a varation:

uint32_t ucode [16][256][16];

void initUCode() {
memcpy_P(ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));

memcpy_P(ucode[FLAGS_U0N0Z0C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));

16x…

}

this is from the final code i was gunna use, i am pretty sure it would all run because it is close to the original but my adaptation was way too large for the arduino.

i think if i change the last paramiter of the memcpy_p line, i could set it to only copy one inner array at a time instead of the entire template. would i change the “sizeof” variable?

or maybe i could just set the arrays via. “BASE_TEMPLATE[0][0]” would i still need the sizeof paramiter following?

sorry if this is not written very clear,

uint32_t ucode [1][256][16]; do i need to change this too? [1][1][16]?

void initUCode() {
memcpy_P(ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE[0][16])); Maybe?

or

memcpy_P(ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE[0][16]);

}

}

In the code in your attempts you declare the buff array inside the for loop
That can't be right, surely

UKHeliBob:
In the code in your attempts you declare the buff array inside the for loop
That can’t be right, surely

What’s wrong with that?

What's wrong with that?

Nothing if that is what he/she meant to do but why do it rather than just once before the for loop ?

Always limit scope to the bare minimum.