Can some one explain this behaviour please, i have the following code
byte buffer[512];
byte block;
byte len;
Serial.setTimeout(60000L) ; // wait until 20 seconds for input from serial
// Ask personal data: Family name
Serial.println(F("Type text followed by #"));
len = Serial.readBytesUntil('#', (char *) buffer, 500) ; // read from serial
Serial.print(len);
for (byte i = len; i < 250; i++) buffer[i] = '#'; // pad with #
Serial.print(len);
This works but if i change the "for" line to any thing higer then 250 it stops working and there is a "buffer out of memory condition)
My question is why can't the for loop say the below as the buffer size is 512?
for (byte i = len; i < 512; i++) buffer[i] = '#';
Am i right in thinking it has something to do with (Char *), i did copy this code from the example ardunio code and was jsut trying to incress the lenth of input it accpeted.
1 Answer 1
A byte can only contain values from 0 to 255 (including).
So my guess it works for values until 255.
You should use a different type, e.g. unsigned int or unsigned short.
for (unsigned short i = len; i < 250; i++) buffer[i] = '#'; // pad with #
Also, I advise to use a constant or define for the buffer size, now you have 3 values (512, 500 and 250 in the loop, I assume they should be based on the same value).
About the char*: Looking at StreamReadBytesUntil, it seems that the parameter wants a char* instead of a byte* (which is more or less the same), but it's better to cast to show the parameter is of type char* since that is high likely the exact type (but the official Arduino documentation does not show the parameter types sadly).
-
1for
len
is byte small too2019年06月26日 19:26:03 +00:00Commented Jun 26, 2019 at 19:26 -
1@See Juraj's remark ... btw, unless you know beforehand you might run into memory problems, always use int or unsigned int. Or if you want to do it better, create a specific type for it:
typedef unsigned short buffer_length
Michel Keijzers– Michel Keijzers2019年06月26日 19:30:41 +00:00Commented Jun 26, 2019 at 19:30 -
1Personally I like to use types as int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t and bool ... some of them are predefined, some are not. But this way I always know exactly what ranges I can use. When a range could change in the future, I use a typedef and give if a specific name, like I said above (typedef uint16_t buffer_size). That saves a lot of type replacement when changed.Michel Keijzers– Michel Keijzers2019年06月26日 20:56:31 +00:00Commented Jun 26, 2019 at 20:56
-
1I seem to remember problems using
unsigned
as types for loop indexes. Someone please correct me if I’m wrong.RubberDuck– RubberDuck2019年06月26日 22:28:29 +00:00Commented Jun 26, 2019 at 22:28 -
1@RubberDuck Yes, for example, if you count down, you cannot check for >= 0, because an unsigned value always is >= 0, but for counting up (until value 254 max) an unsigned byte can be used.Michel Keijzers– Michel Keijzers2019年06月26日 22:36:47 +00:00Commented Jun 26, 2019 at 22:36