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
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.
Explore related questions
See similar questions with these tags.