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

На данный момент я в крайнем замешательстве. Я делаю что-то неправильно? Это аппаратная проблема? Что я могу сделать?

, 👍2

Обсуждение

Он называется [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


3 ответа


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

1

Я бы предложил получить пользовательский ввод с помощью 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


1

по какой-то причине он читает целые числа как 48 больше, чем они есть (5 читается как 53)

Это потому, что вы вводите не цифры, а символы ASCII, представляющие числа.

Все, что вы видите на компьютере или аналогичном устройстве, на самом деле не является тем, что там есть. Все это переведено в форму, которую мы, простые люди, можем видеть. Каждое число переводится в читаемые символы, а читаемые символы необходимо преобразовать в числа.

Например, число 165 — это символы 1 (49), 6 (54) и 5 (53). Когда вы вводите это число, вы отправляете эти три отдельных символа.

Вы можете увидеть всю таблицу ASCII здесь.

Другим эффектом отправки отдельных символов является то, что вы также отправляете маркер с надписью «Это конец строки». Это может быть либо символ 13 (возврат каретки), либо символ 10 (перевод строки), либо их комбинация. Вы можете выбрать, что будет отправлено в последовательном мониторе.

Вам действительно следует использовать этот символ конца строки или комбинацию символов, чтобы определить, сколько символов в вашем номере, чтобы вы могли преобразовать их в правильное целочисленное значение.

Некоторые дополнительные материалы:

  • Чтение сериалов на Arduino (мой блог)
  • Функция atoi()
,

0

Что касается вашего «он ВСЕГДА выводит 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