Прочитать 4 типа данных... но подождать ответов

Я хочу спросить, используя последовательный монитор....для Имя игрока, Возраст, Деньги, логическое значение Счастлив....

Из прочитанного я не знаю, как заставить Arduino считывать каждое значение... Когда мне удаётся заставить это частично работать, во втором цикле он не дожидается ввода пользователя...

Пример #кода ниже...но он больше не правильный??? Пожалуйста, помогите...

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

void loop( ){
  Serial.print("Enter name: ");
  while(Serial.available( ) ==0);//wait
  String myName=Serial.readString();
  Serial.println(myName);

  Serial.print("age ");
  int age=Serial.parseInt();
  Serial.println(age);

  Serial.print("Money");
  double money=Serial.parseFloat();
  Serial.println(money);

  Serial.println("Happy (true/false)");
  bool blnHappy=Serial.read();
  Serial.println(blnHappy);
}

, 👍0

Обсуждение

какой у вас конкретный вопрос? ... пожалуйста, добавьте в свой пост конкретный вопрос, на который можно ответить ... также добавьте свой код, @jsotola

Это может помочь: [Чтение последовательного интерфейса на Arduino](https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27), автор Majenko., @Edgar Bonet

Вот еще одна ссылка, которая может помочь: https://forum.arduino.cc/t/serial-input-basics-updated/382007, @Delta_G

что вы подразумеваете под Arduino Processing App?, @jsotola

@jsotola Arduino IDE (по крайней мере версии 1) основана на [Processing](https://en.wikipedia.org/wiki/Processing)., @the busybee


1 ответ


1
while(Serial.available( ) ==0);  //wait
String myName=Serial.readString();

Ваш цикл while будет ожидать поступления одного символа, но вам нужна целая строка. Вам нужно немного переработать код.

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

// возможные состояния конечного автомата
typedef enum {  WANT_NAME, WANT_AGE, WANT_MONEY, WANT_HAPPY, RUNNING } states;

// текущее состояние конечного автомата
states state = WANT_NAME;

// сколько последовательных данных мы ожидаем до новой строки
const unsigned int MAX_INPUT = 50;

char name [MAX_INPUT];
int age;
long money;
bool happy;

void setup ()
  {
  Serial.begin (115200);
  Serial.println ("Enter your name ...");
  } // конец настройки

// здесь для обработки входящих последовательных данных после получения терминатора
void process_data (const char * data)
  {
  switch (state)
    {
    case WANT_NAME:
      strncpy (name, data, MAX_INPUT);
      state = WANT_AGE;
      Serial.println ("Enter your age ...");
      break;
    case WANT_AGE:
      age = atoi (data);
      state = WANT_MONEY;
      Serial.println ("Enter your money ...");
      break;
    case WANT_MONEY:
      money = atol (data);
      state = WANT_HAPPY;
      Serial.println ("Are you happy? Y/N ...");
      break;
    case WANT_HAPPY:
      happy = toupper (data [0]) == 'Y';
        
      state = RUNNING;
      Serial.println ("Ready to play!");
      Serial.print ("Your name is ");
      Serial.println (name);
      Serial.print ("Your age is ");
      Serial.println (age);
      Serial.print ("Your money is ");
      Serial.println (money);
      Serial.print ("Your happiness is ");
      Serial.println (happy ? "yes" : "no");
      
      break;
      

    } // конец switch(состояния)
  }  // конец 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 ());
    
  // здесь можно выполнять другие действия, например, тестировать цифровой вход (нажатия кнопок) ...

  }  // конец цикла

Более простой пример, использующий более или менее ваш оригинальный код, выглядит следующим образом:

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

  Serial.setTimeout(100000);   // долго ждать, пока они что-то введут
    
  Serial.print("Enter name: ");
  String myName=Serial.readStringUntil('\n');
  Serial.println(myName);

  Serial.print("age ");
  int age=Serial.parseInt();
  Serial.println(age);

  Serial.print("Money");
  double money=Serial.parseFloat();
  Serial.println(money);

  Serial.println("Happy (true/false)");
  bool blnHappy=Serial.readStringUntil('\n');
  Serial.println(blnHappy);
}

void loop( ){

}

Вызов setTimeout означает, что readString не завершается через секунду, давая вам время ввести своё имя. Я использовал readStringUntil, чтобы функция дожидалась символа новой строки в конце строки. Это не идеально, но отражает общую идею.

,

>bool blnHappy=Serial.readStringUntil('\n'); Вы уверены, что происходит неявное преобразование объекта String в bool, которое в конечном итоге приводит к false ?, @DataFiddler

Я не уверен, и когда я тестировал, он не ждал, пока я введу значение true или false, так что, думаю, эта часть не работает. Я упомянул, что «она не идеальна», и это как раз на это и намекало. Однако правильное выполнение этой части — задача для читателя. :), @Nick Gammon

Вероятно, все четыре вопроса следует задавать с помощью readStringUntil, а затем анализировать результаты с помощью atoi, atol или atof и сравнивать строки на предмет «истина» или «ложь»., @Nick Gammon

@DataFiddler Мне не особо нравятся функции parseInt и т.п. с таймаутами и прочим, потому что они лишают вас контроля. Что произойдёт, если, например, не будет введено целое число? Я бы предпочёл прочитать строку, проанализировать её, а затем выдать какую-нибудь ошибку, если введён неверный параметр, например, «не число» или «пустая строка» (нет входных данных)., @Nick Gammon

Это общая проблема использования программного обеспечения: если оно не делает то, что вам нужно, и вы с этим не согласны, вы не можете его использовать. Но вам стоит изучить его поведение, и, возможно, вы сами не сможете сделать лучше. Кстати: bool blnHappy=Serial.readStringUntil('\n'); — это бессмыслица., @DataFiddler

@DataFiddler Я уже писал в паре комментариев, что эта строка не работает. Возможно, вы могли бы опубликовать ответ, который идеально и оптимально отвечает на вопрос? Публикация хорошего решения полезнее, чем расплывчатое указание на то, что мой ответ неверен, без уточнения., @Nick Gammon