Дополнительный «ноль», отображаемый на LCD, когда целое число отправляется с ПК на Arduino через последовательный порт

lcd

Каждый раз, когда я отправляю целое число с компьютера на Arduino, на ЖК-дисплее, подключенном к Arduino, отображается дополнительный ноль. Я не знаю причину. Почему?

Вот код:

#include <LiquidCrystal.h>

int en = 2, rs = 3, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
int a;
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

void setup() {    
    Serial.begin(9600);
    lcd.begin(16,2);

}

void loop() {
    Serial.println("Enter a number");
    while(Serial.available()==0){}
    a=Serial.parseInt();
    lcd.print(a);
}

Результат следующий:

  • Введите число
  • Когда я ввожу число 1
  • Отображается результат 10 вместо 1

, 👍1

Обсуждение

и что вы получите, если напечатаете a обратно в Serial Monitor?, @Juraj

Это типичная проблема при чтении последовательного ввода. Более опытные пользователи arduino не используют такой оператор while для ожидания ввода и не используют функции Serial.parseInt. Вы также можете отправить перевод строки, а Serial.parseInt не может сделать число из перевода строки и возвращает ноль или, возможно, имеет тайм-аут и возвращает ноль. https://www.arduino.cc/en/Reference/StreamParseInt, @Jot

Есть ли альтернативная команда/функция вместо использования Serial.available() и Serial.ParseInt()???, @Rizwan Ullah

@Джот, неправда. parseInt не имеет проблем с LF или любым другим символом. мы до сих пор не знаем, какова ценность, @Juraj

@Juraj может быть перевод строки и тайм-аут. Я почти уверен, что parseInt возвращает обычное число в первый раз и ноль при следующем вызове parseInt. На мой взгляд, это очень очевидно (даже без фактического тестирования)., @Jot

@Джот, правда. Ризван, добавьте while (Serial.read() != -1)' после parseInt();, @Juraj

Это проблема, связанная с дисплеем. Перед печатью номера необходимо очистить поле(я) дисплея., @Danijel


2 ответа


3

Serial.parseInt возвращает ноль, если не может найти число в течение времени ожидания. Этот тайм-аут по умолчанию составляет одну секунду.
Когда число набирается в последовательном мониторе, к нему часто добавляется перевод строки. Этот перевод строки читается Serial.parseInt. Он не может сделать из этого число и ждет, пока истечет время ожидания, и возвращает ноль.

Невозможно определить, возвращает ли Serial.parseInt ноль, потому что число было равно нулю, или возвращает ноль из-за тайм-аута.

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

int a;

void setup() {    
  Serial.begin(9600);
}

void loop() {
  Serial.println("Enter a number");
  while(Serial.available()==0){}
  a=Serial.parseInt();   // он возвращает ноль с переводом строки !
  Serial.println(a);
}

Самый простой способ исправить это — использовать однозначный номер. Функция isdigit используется для проверки входящих символов.

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a number (a single digit)");
}

void loop() {
  if (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isdigit(inChar)) {
      int value = inChar - '0';
      Serial.println(value);
    }
  }
}

Serial.parseInt не совсем бесполезен, но число ноль использовать нельзя. Следующий скетч игнорирует ввод, когда Serial.parseInt возвращает ноль.

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a integer, but not zero, with a linefeed at the end");
}

void loop() {
  if (Serial.available() > 0) {
    int value = Serial.parseInt();
    if (value != 0) {
      Serial.println(value);
      Serial.println("Enter a integer, but not zero, with a linefeed at the end");
    }
  }
}

Чтобы разрешить ввод числа 0, больше нельзя использовать Serial.parseInt. Чтобы избежать ожидания и задержек, каждый символ сразу помещается в буфер. Скетч становится больше, но по-другому нельзя. Либо используйте Serial.parseInt, либо делайте это правильно.

#define BUFFER_SIZE 40
char buffer[BUFFER_SIZE];
int index;

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a integer, with a linefeed at the end");
}

void loop() {
  if (Serial.available() > 0) {
    bool ready = false;

    int inChar = Serial.read();
    buffer[index] = (char) inChar;
    index++;
    if (index >= BUFFER_SIZE) {
      index = BUFFER_SIZE - 1;
      ready = true;
    }

    if (inChar == '\n' || inChar == '\r') {
      ready = true;
    }

    if (ready) {
      if (isdigit(buffer[0]) || buffer[0] == '-') {
        buffer[BUFFER_SIZE - 1] = '\0';
        int value = atoi(buffer);
        Serial.println(value);
        Serial.println("Enter a integer, with a linefeed at the end");
      }
      index = 0;
    }
  }
}
,

большое вам спасибо..@Jot.. Спасибо всем вам.., @Rizwan Ullah


1

2 вещи:

  1. используйте lcd.println() вместо lcd.print().

  2. Открыв монитор последовательного порта, установите для него значение "Без окончания строки" вместо "новой строки".

если вы выполните шаг 1, но пропустите шаг 2, в следующей строке будет напечатан 0.

,