Почему SoftwareSerial::read() возвращает int?
В документации на веб-сайте Arduino показано, что SoftwareSerial::read()
возвращает char
. (ссылка)
Заголовок показывает, что метод возвращает int
. (ссылка)
Определение cpp показывает, что SoftwareSerial::read()
возвращает значение из буферного массива значений uint8_t
. (ссылка)
Учитывая все это:
- Почему интерфейс возвращает
int
вместоuint8_t
? - Почему в документации по Arduino показано, что он возвращает
char
? - Безопасно ли отправлять/получать 8 бит за раз с помощью этой библиотеки?
Для (3) я использую HC-06, если это имеет значение.
@retrohacker, 👍1
3 ответа
Лучший ответ:
В коде чуть выше третьей ссылки вы увидите, что функция может возвращать значение
-1
, если данных нет. Таким образом, 16-битное значение используется для охвата диапазона 8-битныхuint8_t
плюс одно дополнительное значение, чтобы показать, что «действительные данные недоступны».Наверное, для простоты.
Да. Для этого он и создан.
Короче говоря, для всех намерений и целей возвращается только 8-битное значение, но если бы вы читали в int
, вы не могли бы отличить действительное значение от недопустимого.
Stream объявляет read
как возвращающий int
(смотрите в hardware/arduino/avr/cores/arduino/Stream.h
). SoftwareSerial
наследуется от Stream
, поэтому они должны переопределить это объявление, иначе было бы два метода read()
, один из которых возвращает int
и один возвращает uint8_t
. Поскольку SoftwareSerial::read()
вернет только int
от 0 до 255, что соответствует uint8_t
, проблем нет.
Что касается документации по Arduino, вы получаете то, за что платите :)
много слов, нет ответа. причина int - вернуть -1, что означает «нет данных для возврата»., @Juraj
В документации на веб-сайте Arduino показано, что SoftwareSerial::read() возвращает символ.
Нет. В документации нет ничего, что говорило бы вам о типе возвращаемого значения. Есть только пример, когда возвращаемое значение присваивается переменной char
. Это не означает, что он возвращает char — это просто означает, что любой возвращаемый тип данных может быть незаметно преобразован компилятором в char
.
Заголовок показывает, что метод возвращает целое число.
Это действительно так. Это потому, что это то, что он возвращает.
Определение cpp показывает, что SoftwareSerial::read() возвращает значение из буферного массива значений uint8_t.
Да, потому что действительные данные, с которыми он работает, имеют размер 8 бит. Тот факт, что он обрабатывает 8-битные «действительные» данные, не означает, что это все, которые он когда-либо хочет вернуть. Возвращаемое значение «нет доступных данных» равное -1, очевидно, не является чем-то, что хранится в данных. Это статус, а не данные.
Почему интерфейс возвращает int вместо uint8_t?
Поскольку uint8_t
не может включать в себя все функции, указанные в разделе "Возвраты":
прочитанный символ или -1, если он недоступен
Вы не можете вернуть -1 в uint8_t
.
Почему в документации Arduino указано, что он возвращает символ?
Как я уже упоминал выше, это не так. Он вообще не претендует на возвращаемый тип данных.
Безопасно ли отправлять/получать 8 бит за раз с помощью этой библиотеки?
Да. Он выполняет последовательную передачу данных, используя 8-N-1 по умолчанию. Это 8 бит данных, без четности и один стоповый бит.
Именно такая путаница с возвращаемыми типами, байтами, целыми числами и другими вещами заставляет людей задаваться вопросом, почему они продолжают получать ÿÿÿÿÿÿ на последовательном мониторе. Это -1 бросок как символ. То есть «нет доступных данных», но они игнорируют это и рассматривают все возвращаемое как char
— скорее всего, потому, что документация Arduino показывает чрезмерно упрощенный пример, который игнорирует возможность возврата -1 и обрабатывает все как char
.
ИМХО, большая часть документации Arduino несколько не соответствует стандарту и не должна восприниматься буквально — только как приблизительное руководство по тому, что доступно. То же самое касается большей части их примеров кода и проектов.
Однако есть надежда, поскольку похоже, что документация Arduino находится в процессе рефакторинга. [Документация для Serial.read()
](https://www.arduino.cc/reference/en/language/functions/communication/serial/read/), взятая из нового документа ASCII, размещенного на GitHub. на основе репозитория, четко указано «Тип данных: int
». Документация для SoftwareSerial
все еще находится в старом формате и, предположительно, еще не была перенесена., @Edgar Bonet
@EdgarBonet Это многообещающе. Может быть, они сделают то же самое со всеми плохими схемами и примерами проектов..., @Majenko
- Мусор последовательного монитора Arduino Pro Mini
- AT-команда не отвечает на последовательный монитор
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- Как остановить SoftwareSerial от получения данных и повторно включить его в какой-то другой момент?
- SIM800L не регистрируется в сети
- Ардуино для чтения с преобразователя RS232 в последовательный модуль TTL
- Модуль SIM808 GSM работает нормально, GPS не работает (нет сообщения о готовности GPS при включении питания)
Ах здорово! Значение
-1
имеет смысл. Итак, если предположить, что вызовread()
связан сavailable()
, похоже, что я могу прочитать его напрямую в uint8_t и работать с ним как с истинным байтом., @retrohackerВсе приложения, которые я видел (для всех объектов потокового типа), это
if(available()){read();}
. Код, на который вы ссылаетесь, считывает данные из кольцевого буфера во временныйuint8_t
перед возвратом вint
, поэтому вы не потеряете данные таким образом., @user85471Фактический ответ на номер 2: «Потому что, как и во многих случаях, документация Arduino — полный мусор»., @Majenko
Я немного удивлен, что никто не упомянул тот факт, что это та же самая причина, по которой [
getchar()
и друзья](http://man7.org/linux/man-pages/man3/fgetc.3.html ) возвращаетint
в стандартном C., @ilkkachu