3

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

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).

13
  • 1
    for len is byte small too
    – Juraj
    Commented 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 Commented Jun 26, 2019 at 19:30
  • 1
    Personally 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. Commented Jun 26, 2019 at 20:56
  • 1
    I seem to remember problems using unsigned as types for loop indexes. Someone please correct me if I’m wrong.
    – RubberDuck
    Commented 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. Commented Jun 26, 2019 at 22:36

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.