Запись нескольких входов в последовательный порт с использованием цикла while

Я пытаюсь заставить серийный монитор предложить мне ввести две настройки — уровень ШИМ и уровень резонанса. Мне предлагается ввести уровень ШИМ, но прежде чем я могу ввести уровень резонанса, он устанавливается на ноль, а затем снова запрашивается уровень ШИМ.

Я использую Serial.flush(); между командами для очистки последовательного ввода, но я все еще не могу ввести уровень резонанса, пока он не будет установлен на ноль.

Вот мой код:

int PWMPin = 10;       // Контакт 10 подключается к затвору MOSFET на макетной плате
int ResPin = 4;        // Пин для резонаторного каскада


void setup() {
  // поместите сюда код установки для однократного запуска:
  Serial.begin(9600);   // Определяем скорость передачи для консоли 9600
  pinMode(PWMPin, OUTPUT);  
  pinMode(ResPin, OUTPUT);   

}

void loop() {
  // поместите сюда ваш основной код для многократного запуска:

Serial.println("What PWM level do you want to test?");   // Только тестирование
 while (Serial.available() == 0) {
     // Ждем ввода пользователя
  }
  int test_level_PWM = Serial.parseInt();
    analogWrite(PWMPin, test_level_PWM);
    Serial.print("PWM Level: ");
    Serial.println(test_level_PWM);
    
Serial.flush();

Serial.println("What Resonance level do you want to test?");    
 while (Serial.available() == 0) {
     // Ждем ввода пользователя
  }
  int test_level = Serial.parseInt();
    analogWrite(ResPin, test_level);
    Serial.print("Resonance Level: ");
    Serial.println(test_level);

   delay(1000); 

Вот вывод последовательного монитора. Я смог ввести уровень ШИМ, но сразу после этого уровень резонанса был установлен на ноль, а затем меня попросили снова ввести уровень ШИМ.

, 👍1

Обсуждение

Я бы подумал о реструктуризации этого в конечный автомат с (что-то вроде) состояниями «ввод» и «запуск». Я бы также пересмотрел использование parseInt, потому что его тайм-аут по умолчанию, равный 1 с, может привести к неожиданному поведению; может просто захотеть справиться с этим вручную., @Dave Newton

Serial.flush() делает не то, что вы думаете. символы конца строки останутся в буфере RX. flush() ожидает отправки буфера TX. https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/, @Juraj

в последовательном мониторе вместо окончания новой строки выберите без окончания строки. После внесения этого изменения ваш код работал в моей системе., @ARDUINO_S


1 ответ


1

Ваша линия

Serial.flush();

вероятно, предназначен для удаления дополнительного ввода после ожидаемого числового ввода. Но это не то, что он делает. (см. комментарий @jurai)

Либо избегайте дополнительного ввода, такого как символы новой строки, либо удалите их, используя что-то вроде

в то время как (Serial.available()) {delay(1); Serial.read();

(delay(1); обеспечивает медленное поступление последовательных данных на скорости 9600 бод)

,