Serial читает несколько цифр и всегда читает 10 в конце?
Итак, я пытаюсь создать программу, которая позволяет вводить число в десятичном виде и отображать его в двоичном виде, и после некоторых первоначальных усилий она работает довольно хорошо (по какой-то причине она читает целые числа как на 48 больше, чем они есть на самом деле). (5 читается как 53)) но я до сих пор кое-чего не понимаю и боюсь, что это может быть аппаратная проблема.
По какой-то причине я не могу отображать двузначные числа. Например, если я ввожу 12, он отображает 1, а ЗАТЕМ отображает 2. Кроме того, что еще хуже, он ВСЕГДА выводит 10 после того, как я ввожу ЛЮБОЕ число. Например, если я ввожу 5, отображается 5, а затем ВСЕГДА 10.
void setup() {
// поместите сюда свой код установки для однократного запуска:
Serial.begin(9600);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
}
void loop() {
// поместите сюда свой основной код для многократного запуска:
int number;
if (Serial.available() > 0) {
number = Serial.read();
Serial.print("Number to display: ");
Serial.println(number);
if (number <= 15){
int LEDPin = 2;
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
for (int n = 0; n <= 4; n++){
int binval = bitRead(number, n);
Serial.println(binval);
digitalWrite(LEDPin, binval);
LEDPin++;
}
}
else{
Serial.println("Number must be less than 16!");
}
delay(1000);
}
}
РЕДАКТИРОВАТЬ: И, конечно же, после того, как я задал вопрос, я повторно запустил код, и он СНОВА показал целые числа на 48 больше, чем они есть (5 как 53).
На данный момент я в крайнем замешательстве. Я делаю что-то неправильно? Это аппаратная проблема? Что я могу сделать?
@Diego Garcia, 👍2
Обсуждение3 ответа
Лучший ответ:
Я бы предложил получить пользовательский ввод с помощью Serial.readBytesUntil()
, сохранить его в массиве char
, а затем использовать itoa()
чтобы получить целочисленное значение. Вот модифицированная версия вашего скетча.
char inputBuffer[5];
byte number = 0;
void setup() {
Serial.begin(9600);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
Serial.readBytesUntil('\n', inputBuffer, 4);
number = atoi(inputBuffer);
Serial.print("Number to display: ");
Serial.println(inputBuffer);
if (number <= 15){
int LEDPin = 2;
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
for (int n = 0; n <= 4; n++){
int binval = bitRead(number, n);
Serial.println(binval);
digitalWrite(LEDPin, binval);
LEDPin++;
}
}
else{
Serial.println("Number must be less than 16!");
}
delay(1000);
}
}
или используйте parseInt(), @Juraj
Использование parseInt()
даст тот же результат, что и readBytesUntil()
с входным буфером и atoi()
. Изменение эскиза ОП на использование parseInt()
будет на 2 строки меньше кода, но будет стоить вам дополнительных 98 байтов размера компиляции. Одним из преимуществ использования parseInt()
является простота, с которой вы можете анализировать список целых чисел, разделенных запятыми, из последовательного монитора. Если ОП планирует сделать что-то более сложное, чем ввод одного целого числа, то лучше всего использовать parseInt()
. Спасибо за ваш комментарий, Юрай., @VE7JRO
по какой-то причине он читает целые числа как 48 больше, чем они есть (5 читается как 53)
Это потому, что вы вводите не цифры, а символы ASCII, представляющие числа.
Все, что вы видите на компьютере или аналогичном устройстве, на самом деле не является тем, что там есть. Все это переведено в форму, которую мы, простые люди, можем видеть. Каждое число переводится в читаемые символы, а читаемые символы необходимо преобразовать в числа.
Например, число 165 — это символы 1 (49), 6 (54) и 5 (53). Когда вы вводите это число, вы отправляете эти три отдельных символа.
Вы можете увидеть всю таблицу ASCII здесь.
Другим эффектом отправки отдельных символов является то, что вы также отправляете маркер с надписью «Это конец строки». Это может быть либо символ 13 (возврат каретки), либо символ 10 (перевод строки), либо их комбинация. Вы можете выбрать, что будет отправлено в последовательном мониторе.
Вам действительно следует использовать этот символ конца строки или комбинацию символов, чтобы определить, сколько символов в вашем номере, чтобы вы могли преобразовать их в правильное целочисленное значение.
Некоторые дополнительные материалы:
- Чтение сериалов на Arduino (мой блог)
- Функция
atoi()
Что касается вашего «он ВСЕГДА выводит 10 после того, как я ввожу ЛЮБОЕ число», у меня была та же проблема с использованием ASCII, и я думаю, что наконец-то разобрался с этим. Когда вы используете Serial.println где угодно, он выводит перевод строки. В ASCII это называется новой строкой и его значение равно 10. Я пока не нашел способа обойти это.
byte ASCII_Number;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Enter any single ASCII character:");
while (Serial.available()==0) {}
char ASCII_Character = Serial.read();
ASCII_Number = (int)ASCII_Character;
Serial.print("For your ASCII Character: ");
Serial.print(ASCII_Character);
Serial.print(" the ASCII Number is: [");
Serial.print(ASCII_Number);
Serial.println("] "); // print line always generates ASCII 10 (newline).
//This runs the loop again with a newline for the character.
delay (5000);
ASCII_Number = 0;
}
В настоящее время ваш ответ неясен. Пожалуйста, [измените], чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, вы можете найти [в справочном центре](/help/how-to-ответ)., @Community
1. Исходный вопрос касается получения НЧ **на входе**. 2. Serial.println()
выводит как CR (13), так и LF (10)., @Edgar Bonet
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Он называется [ASCII](https://en.wikipedia.org/wiki/Ascii), и да, «5» — это то же самое, что «53»., @Edgar Bonet
Возможный дубликат [Почему я всегда получаю 48 при последовательном соединении?](https://arduinoprosto.ru/q/26770/why-am-i-always-getting-48-with-serial-communication), @Juraj