запись в буфер из последовательного ввода

Может кто-нибудь объяснить это поведение, пожалуйста, у меня есть следующий код

  byte buffer[512];
  byte block;
  byte len;

  Serial.setTimeout(60000L) ;     // ждем 20 секунд для ввода с серийного номера
  // Запрашиваем личные данные: Фамилия
  Serial.println(F("Type text followed by #"));
  len = Serial.readBytesUntil('#', (char *) buffer, 500) ; // чтение из серийного номера
  Serial.print(len);
  for (byte i = len; i < 250; i++) buffer[i] = '#';     // дополнить #
  Serial.print(len);

Это работает, но если я изменю строку "for" на любую, превышающую 250, она перестанет работать, и возникнет состояние "недостаточно памяти в буфере")

Мой вопрос: почему цикл for не может сказать следующее, поскольку размер буфера равен 512?

for (byte i = len; i < 512; i++) buffer[i] = '#'; 

Правильно ли я думаю, что это как-то связано с (Char *), я скопировал этот код из примера кода ardunio и просто пытался увеличить длину ввода, который он принял.

, 👍3


1 ответ


Лучший ответ:

1

Байт может содержать только значения от 0 до 255 (включительно).

Полагаю, это работает для значений до 255.

Вы должны использовать другой тип, например unsigned int или unsigned short.

for (unsigned short i = len; i < 250; i++) buffer[i] = '#';     // дополнить #

Кроме того, я советую использовать константу или определить размер буфера, теперь у вас есть 3 значения (512, 500 и 250 в цикле, я предполагаю, что они должны основываться на одном и том же значении).

О char*: Глядя на StreamReadBytesUntil, кажется, что параметру требуется char* вместо byte* (что более или менее то же самое), но лучше приводить, чтобы показать, что параметр имеет тип char*, так как это, скорее всего, точный тип (но, к сожалению, официальная документация Arduino не показывает типы параметров).

,

Я согласен использовать ту же константу, она была оригинальной, но я играл, когда пытался перейти на 250. Тот факт, что 254 сломался, должен был сказать мне об этом., @DevilWAH

Нет проблем, кстати, я решил закрыть этот вопрос, так как он не связан с Arduino, но вы можете продолжать программировать, удачи., @Michel Keijzers

Вы также можете объяснить, почему (char *) используется в этом коде, чтобы обеспечить его запись в начало буфера. почему вы не можете просто использовать «буфер» или есть особое преимущество в этом?, @DevilWAH

Я добавил примечание об этом., @Michel Keijzers

для len тоже маленький байт, @Juraj

Это имеет смысл, спасибо, что нашли время, чтобы помочь., @DevilWAH

@ См. замечание Юрая ... кстати, если вы заранее не знаете, что можете столкнуться с проблемами памяти, всегда используйте int или unsigned int. Или, если вы хотите сделать это лучше, создайте для него специальный тип: typedef unsigned short buffer_length, @Michel Keijzers

Все отлично, и это решает некоторые другие проблемы в блоке кода, который я писал, в примере много использовалось «байт». кое-что для меня, чтобы помнить, взламывая примеры других людей. проверьте размеры подходят :), @DevilWAH

Лично мне нравится использовать такие типы, как int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t и bool... некоторые из них предопределены, некоторые нет. Но таким образом я всегда точно знаю, какие диапазоны я могу использовать. Когда диапазон может измениться в будущем, я использую typedef и даю ему конкретное имя, как я сказал выше (typedef uint16_t buffer_size). Это экономит много замены типа при изменении., @Michel Keijzers

Кажется, я помню проблемы с использованием unsigned в качестве типов для циклических индексов. Кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь., @RubberDuck

@RubberDuck Да, например, если вы ведете обратный отсчет, вы не можете проверить >= 0, потому что беззнаковое значение всегда >= 0, но для подсчета вверх (до максимального значения 254) можно использовать байт без знака., @Michel Keijzers

Ах. Да. Я сделал эту ошибку раньше. https://stackoverflow.com/a/9044067/3198973, @RubberDuck

@RubberDuck Да ... к сожалению, большинство компиляторов не выдают предупреждений., @Michel Keijzers