Последовательный монитор возвращает «48», когда я ввожу «0».
Я просматриваю Учебное пособие по Arduino (978-1-59327-448-1) и уже дважды столкнулся с одной и той же проблемой.
Когда я ввожу данные в последовательный монитор, число, которое он считывает и отображает (когда его просят распечатать), сильно отличается от того, что я ввожу.
Для диагностики проблемы я перешел на https://www.arduino.cc/en/Serial/Read
Скопировал код в новый скетч и попробовал запустить его.
Когда я ввожу 0, я получаю 48 и вторую строку с надписью 10. Ввожу 1, я получаю 49, 10 и т. д. Вот результаты, когда я ввожу 0, затем 1, затем 2, затем 3
Я получил: 48 Я получил: 10
Я получил: 49 Я получил: 10
Я получил: 50 Я получил: 10
Я получил: 51 Я получил: 10
вот код, который я использую
int incomingByte = 0; // для входящих последовательных данных
void setup() {
Serial.begin(9600); // открывает последовательный порт, устанавливает скорость передачи данных 9600 бит/с
}
void loop() {
// отправляем данные только тогда, когда вы их получаете:
if (Serial.available() > 0) {
// читаем входящий байт:
incomingByte = Serial.read();
// скажем, что у вас есть:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
У меня последовательный монитор настроен на 9600. Все скетчи до сих пор работали нормально, включая те, которые используют функции Serial.print, но когда я использую Serial.read, кажется, что-то идет не так.
Я уверен, что упускаю что-то глупое, но я погуглил и все ответы гораздо более высокого уровня, чем просто попытка запустить код в примере Arduino.cc
Заранее благодарим за помощь новичку!
PS: Я пытался поместить весь код в серый блок, используя различные стратегии межстрочного интервала и отступов, но это не идеально. Есть ли у кого-нибудь какие-нибудь советы по этому поводу?
@Mechanical-ish, 👍2
Обсуждение2 ответа
Serial.println(incomingByte, DEC);
Вы сказали ему печатать входящий байт в десятичном формате, и он так и сделал. 48 — десятичный эквивалент ASCII 0.
Замените эту строку на:
Serial.println((char) incomingByte);
Это преобразует то, что вы печатаете, в символ, а затем соответствующая версия Serial.println печатает это как символ, а не десятичное число.
10 — это десятичный эквивалент новой строки (новой строки), поэтому вы также видите напечатанное число 10.
Мне нужно преобразовать входящие данные в целые числа, чтобы они могли видеть, правильно я угадал или нет
Предполагая, что вы имеете в виду целое число, отличное от 0 до 9 (например, 42), вам потребуется немного больше работы. У меня есть страница о подобном:
http://www.gammon.com.au/serial
Пример кода:
/*
Example of processing incoming serial data without blocking.
Author: Nick Gammon
Date: 13 November 2011.
Modified: 31 August 2013.
Released for public use.
*/
// сколько последовательных данных мы ожидаем перед переводом строки
const unsigned int MAX_INPUT = 50;
void setup ()
{
Serial.begin (115200);
} // конец настройки
// здесь для обработки входящих последовательных данных после получения терминатора
void process_data (const char * data)
{
// пока просто отображаем это
// (но вы можете сравнить его с каким-то значением, преобразовать в целое число и т. д.)
Serial.println (data);
} // конец Process_data
void processIncomingByte (const byte inByte)
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte)
{
case '\n': // конец текста
input_line [input_pos] = 0; // завершающий нулевой байт
// терминатор достигнут! обработать input_line здесь...
process_data (input_line);
// сбрасываем буфер для следующего раза
input_pos = 0;
break;
case '\r': // отбрасываем возврат каретки
break;
default:
// продолжаем добавлять, если не заполнено... разрешаем завершающий нулевой байт
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // конец переключателя
} // конец процессаIncomingByte
void loop()
{
// если серийные данные доступны, обработаем их
while (Serial.available () > 0)
processIncomingByte (Serial.read ());
// выполняем здесь другие действия, например, проверяем цифровой ввод (нажатие кнопок) ...
} // конец цикла
В этом примере функция process_data
вызывается, когда необходимо обработать полное число.
Хорошо, я изменил его, как вы предложили, и получил: «Я получил: 1 Я получил: «Итак, это работает над печатью введенного мной числа, но я все еще не понимаю, почему печатается эта дополнительная строка. Кроме того, когда я возвращаюсь к игре в угадайку в книге, мне нужно преобразовать входящие данные в целые числа, чтобы он может увидеть, правильно я угадал или нет., @Mechanical-ish
Дополнительная строка — это перевод строки, который вы повторяете. Вы настроите монитор терминала на отправку перевода строки после нажатия кнопки «Отправить»., @Nick Gammon
Вы можете использовать Serial.parseInt()
для чтения числа, отправленного из Serial Monitor. parseInt ожидает всех числовых символов отправленного текста и блокирует выполнение вашего скетча за очень короткое время до получения всех символов. При более высокой скорости передачи данных это будет быстрее. Если вашему скетчу не нужно зацикливаться как можно быстрее, вы можете использовать его. parseInt
останавливается на первом символе, который не является цифрой (например, символе новой строки), и возвращает полученное число такой же длины.
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available() > 0) {
long number = Serial.parseInt();
Serial.println(number);
}
}
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- В чем разница между Serial.write и Serial.print? И когда они используются?
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Программы построения последовательных данных
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Очистить существующий массив при получении новой последовательной команды
Вы просто пропустили [это](https://ascii.cl/)., @Edgar Bonet
Пожалуйста объясните далее. Мне было интересно, нужен ли ввод ASCII вместо обычных чисел, но код в моей книге и на этом сайте не содержит каких-либо специальных положений или упоминаний о различных стилях ввода., @Mechanical-ish
вы видите ascii-код символа, который вы ему передали. вы можете использовать
Serial.print((char)49);
, чтобы вернуть его обратно в1
, @dandavisКомментарии под вопросами предназначены для разъяснения вопроса, а не для ответа на него. Пожалуйста, оставьте **ответ**, если вы хотите ответить. Это дает вам преимущество в том, что вы получаете репутацию, если за него проголосовали или приняли., @Nick Gammon
*Я пытался поместить весь код в серый блок с различными стратегиями межстрочного интервала и отступов, но это не идеально.* - какой серый блок? В чем оно не идеально? Вы имеете в виду форум или Arduino IDE?, @Nick Gammon
ОК, теперь я вижу, он читается как «символ» на этой связанной странице или «символ» в другом месте и сохраняет связанный код ASCII. Я могу обманом заставить его сократить что угодно до 33 с помощью "!" в качестве ответа, но для эскиза в книге мне нужно, чтобы он хранил значения от 0 до 255 (я играю в угадайку с доской). Так какой у меня обходной путь? Книга просто ожидает, что их код волшебным образом сработает, и код выглядит похоже на arduino.cc. Наконец, откуда взялась эта дополнительная цифра «10»? как в «Я получил: 10» на последовательном мониторе (исходный пример arduino.cc), @Mechanical-ish
@nick, серый квадрат на этой странице. В моем первоначальном вопросе... подождите, неважно, теперь все в коробке, этого не было до того, как я задал вопрос. но для справки, код после моей строки «вот код, который я использую» и еще раз спасибо всем, @Mechanical-ish
@Mechanical-ish О «сером поле на этой странице». Это был я. Я отредактировал ваш вопрос, чтобы весь эскиз вписывался в «Пример кода». Вы можете выделить эскиз и отформатировать его, используя сочетание клавиш «Ctrl+K», вставить 4 пробела перед каждой строкой кода или выделить эскиз, а затем нажать ссылку «{}» в редакторе., @VE7JRO