Прочитать 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);
}
@BJO, 👍0
Обсуждение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
- Как получить тип данных переменной?
- Преобразование в Unix Timestamp и обратно
- Невозможно создать массив типа const char*
- Ошибка Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
- ардуино - миллисекунды ()
- Получение шестнадцатеричных данных с терминала
- Какой тип данных Arduino допускает десятичные дроби?
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
какой у вас конкретный вопрос? ... пожалуйста, добавьте в свой пост конкретный вопрос, на который можно ответить ... также добавьте свой код, @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