Приветствую! Голова кипит Есть вот такой кусок кода Код (C++): Var=""; long time = millis(); while (!Serial.available() and (millis()-time<2000))//пока нет данных для приема стоим на месте 2 секунды и выходим delay(20); delay(200);//ожидаем получения всего сообщения while (Serial.available()) //пока не конец сообщения, читаем данные и формируем строку Var = Var + (char)(Serial.read()); if (Var!=0){//если пришло сообщение parseParams(Var); } принадлежит он bigbarrel он отлично работает. Смысл в том, что с помощью этого кода в var собирается строка из serial и далее отправляется в парсер. как ее переработать, чтобы не было остановок ? никак? голову сломал. Чтобы основной алгоритм не останавливался ...
Вам надо считывать строку из сериал ? Если правильно понял то как то так: Код (C++): String str = ""; long time = millis(); void setup() { Serial.begin(9600); } void loop() { while (Serial.available() > 0) { str = Serial.readStringUntil('\n'); } if(str != 0) { Serial.println(str); if(str == "on") { digitalWrite(13,1); } if(str == "off") { digitalWrite(13,0); } str = ""; } } Текст в сериал должен заканчиваться переводом строки
Друзья, пытаюсь ... сделать простое serial меню. Не могу понять, как сделать ... может подкините идею. Принимаю строку по условию Serial.readStringUntil('\n'); Далее хочу изобразить "подменю", в котором я снова запрашиваю с клавиатуры значение чего либо. Например ввожу config, и снова от меня ждут ввода строки Until('\n');, чтобы это значение уже применилось к определенной переменной. а у меня ничего не получается. мне нужно получается после приема строки глянуть в какому if она относится, и в этом if внутри снова сделать прием строки, и отпарсить далее его.
вот фрагмент из моего скетча, где есть простое Serial-меню. Реакция по одной клавише, а не вводу целой команды. Код (C++): void setup() { Serial.begin(9600); // draw a menu on the serial port Serial.println( "----------- MENU ------------" ); Serial.println( "P - Power" ); Serial.println( "N - Enter" ); Serial.println( "L - Left" ); Serial.println( "R - Right" ); Serial.println( "I - Input" ); Serial.println( "E - Esc" ); Serial.println( "-----------------------------" ); Serial.println("Ready..."); } void loop() { inputKey(); // ждем команды из Serial } void inputKey() { byte c; if( Serial.available() ) { Serial.print("#9 "); c = Serial.read(); // execute the menu option based on the character recieved switch( c ) { case 'p': Serial.print("Power key\t"); pressKey(KEY_POWER); break; case 'n': Serial.print("Enter key\t"); pressKey(KEY_ENTER); break; case 'l': Serial.print("Left key\t"); pressKey(KEY_LEFT); break; case 'r': Serial.print("Right key\t"); pressKey(KEY_RIGHT); break; case 'i': Serial.print("Input key\t"); pressKey(KEY_INPUT); break; case 'e': Serial.print("Esc key\t"); pressKey(KEY_ESC); break; default: Serial.print("Error!");// wrong character! display the menu again! break; } } // repeat the main loop and redraw the menu... }
Спасибо за ответ! А как доработать алгоритм (Ваш, или мой, или любой), чтобы можно было ввести значение переменной? Например: Первый уровень. а) P б) N с) - попадаем в подменю, образно говоря на одно вложение ниже, где мне нужно ввети значение именно с клавиатуры? блин, я даже не знаю как грамотно объяснить. Код (C++): case 'p': Serial.print("Power key\t"); pressKey(KEY_POWER); break; например в таком кейсе внутри сделать запрос на ввод значения переменной Х. нажимаю p и после этого пока я не введу значение для переменной определенной, дальше ничего не едет. грубо говоря чтение с сериал внутри такого вот кейса. извините за кривое объяснение
зачем городить подменю? Клавиш на клавиатуре много, экран большой - выводи все меню сразу, а подменю выдели отступами. Ввод чисел из Serial есть в стандартном примере ReadASCIIString.
Мы друг друга не правильно понимаем. Выше предложен вариант, когда я ввожу букву, алгоритм ее парсит и в результате выполняет кусок какого то кода. кейс ... а я хочу добиться варианта, когда можно внутри этого кейса еще раз запросить что то с клавиатуры. например: press A to enter X value нажал A, и с клавиатуры вводишь значение для переменной Х. и пока не введешь, дальше ничего не едет. у меня так сделать не получается Код (C++): case 'p': Serial.print("Power key\t"); while (Serial.available() > 0) { red = Serial.parseInt(); } Serial.print(red); вот так мне нужно. но это не правильно.
Код (C++): switch ( c ) { case 'p': Serial.print("Power key\t"); while (!Serial.available()) delay(20); { red = Serial.parseInt(); } Serial.println(red); //pressKey(KEY_POWER); break; кажется получилось вот так ... но на сколько это грамотно? пойдет?
Код (C++): int x; // глобальная переменная void setup() { Serial.setTimeout(1000); // timeout duration in milliseconds (long). It defaults to 1000 milliseconds. Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); } void loop() { serialMainMenu(); } void serialMainMenu() // draw a menu on the serial port { Serial.println( "\n----------- MENU ------------" ); Serial.println( "C - Input command only" ); Serial.println( "V - Input command with value" ); Serial.println( "R - Restart" ); Serial.println( "H - Help" ); Serial.println( "-----------------------------" ); Serial.println("Please input hotkey:\n"); while(!Serial.available()); byte key; if(Serial.available()) { key = Serial.read(); switch(key) { case 'c': serialSubmenuCommand(); break; case 'C': serialSubmenuCommand(); break; case 'v': serialSubmenuComValue(); break; case 'V': serialSubmenuComValue(); break; case 'r': serialRestart(); break; case 'R': serialRestart(); break; case 'h': serialHelp(); break; case 'H': serialHelp(); break; default: Serial.println("Unknown hoktey! Try again.\n"); // wrong character! display the menu again! break; } } } void serialSubmenuComValue() // Ввод команды с числовым параметром, через пробел: left 55 { Serial.println("Enter text command and value com separator. Example: led 87"); while(!Serial.available()); String command; if(Serial.available() > 0) { command = Serial.readStringUntil(' '); x = Serial.parseInt(); Serial.print(">I received: command = "); Serial.print(command); Serial.print(", x = "); Serial.println(x); if(command == "led") { analogWrite(D9, x); Serial.print(">pin D9 is set to "); Serial.println(x); } } } void serialSubmenuCommand() // Ввод команды без числовых параметров: power on { Serial.println("Enter text command. Enter \"M\" to return to Main Menu. Example: led on/off"); while(!Serial.available()); String command = ""; char character; while(Serial.available()) { command = Serial.readString(); } if(command != "") { if(command == "led on") { digitalWrite(LED_BUILTIN, HIGH); Serial.println(">LED on pin 13 is ON"); } else if(command == "led off") { digitalWrite(LED_BUILTIN, LOW); Serial.println(">LED on pin 13 is OFF"); } else if(command == "m" || command == "M" || command == "menu") { serialMainMenu(); } } else Serial.println("Unknown command!"); serialSubmenuCommand(); } void serialRestart() { Serial.println( "cRestarting... \n" ); serialMainMenu(); } void serialHelp() { Serial.println( "----------- HELP ------------" ); Serial.println( "Bla-bla-bla"); Serial.println( "-----------------------------" ); Serial.println( "Press input anything to return to Main Menu"); while(!Serial.available()); serialMainMenu(); }