0

I have a 2d array:

const byte messages_for_measurement[2][8] PROGMEM = 
{
  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
  { 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 },
};

I want to send one of these sub-array over software serial.

Initially, this produced junk data:

swSerial.write( messages_for_measurement[0], sizeof(messages_for_energy_meter[0]) );

Then I learned about pgm_read_byte_near() and pgm_read_word(). I tried every combination but I did not get this to work:

swSerial.write(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0]))), sizeof(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0])));

and

swSerial.write(pgm_read_byte_near(&pgm_read_word(messages_for_measurement[0]))), sizeof(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0])));

and

swSerial.write(char(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0])))), sizeof(char(pgm_read_byte_near(pgm_read_word(messages_for_measurement[0]))));

and

swSerial.write(char(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0])))), sizeof(char(pgm_read_byte_near(pgm_read_word(&messages_for_measurement[0]))));

How can I send the sub-array over serial, when the 2d array is in PROGMEM?

1 Answer 1

1

The write() method from SoftwareSerial (which is inherited from the abstract Print class) does not support printing PROGMEM-based binary buffers. The print() method does have some PROGMEM support, but it is limited to printing NUL-terminated character strings, and is meant to be used with the F() macro. You could coerce this method into printing your data, but this would require you to add a null byte at the end of each inner array, and the trick would break if you ever have to send a null byte.

Also, the pgm_read_stuff() macros cannot read an array at a time. You could do achieve this with memcpy_P(), but that would require allocating an array in RAM. I think the simplest solution here is to get the bytes from the flash one by one with pgm_read_byte():

const byte *message = messages_for_measurement[0];
size_t size = sizeof messages_for_measurement[0];
for (size_t i = 0; i < size; i++) {
    swSerial.write(pgm_read_byte(&message[i]));
}

Note that the first line does not attempt to access the array data: it only copies into message the address of the first byte: this is the decay-to-pointer semantics.

Your Answer

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

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