Помогите с алгоритмом serial

Тема в разделе "Arduino & Shields", создана пользователем ArcticBear, 22 ноя 2015.

  1. ArcticBear

    ArcticBear Нерд

    Приветствую!

    Голова кипит
    Есть вот такой кусок кода

    Код (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 и далее отправляется в парсер.

    как ее переработать, чтобы не было остановок ? никак? голову сломал. Чтобы основной алгоритм не останавливался ...
     
  2. Вам надо считывать строку из сериал ?
    Если правильно понял то как то так:

    Код (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 = "";
      }

    }
    Текст в сериал должен заканчиваться переводом строки
     
    Tomasina и ArcticBear нравится это.
  3. ArcticBear

    ArcticBear Нерд

    Спасибо!
     
  4. ArcticBear

    ArcticBear Нерд

    Друзья, пытаюсь ... сделать простое serial меню.
    Не могу понять, как сделать ... может подкините идею.

    Принимаю строку по условию Serial.readStringUntil('\n');
    Далее хочу изобразить "подменю", в котором я снова запрашиваю с клавиатуры значение чего либо.

    Например ввожу config, и снова от меня ждут ввода строки Until('\n');, чтобы это значение уже применилось к определенной переменной.

    а у меня ничего не получается. мне нужно получается после приема строки глянуть в какому if она относится, и в этом if внутри снова сделать прием строки, и отпарсить далее его.
     
  5. Tomasina

    Tomasina Сушитель лампочек Модератор

    вот фрагмент из моего скетча, где есть простое 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...
    }
     
     
    ArcticBear нравится это.
  6. ArcticBear

    ArcticBear Нерд

    Спасибо за ответ! А как доработать алгоритм (Ваш, или мой, или любой), чтобы можно было ввести значение переменной?
    Например:
    Первый уровень.
    а) P
    б) N
    с) - попадаем в подменю, образно говоря на одно вложение ниже,
    где мне нужно ввети значение именно с клавиатуры?
    блин, я даже не знаю как грамотно объяснить.
    Код (C++):
    case 'p':
          Serial.print("Power key\t");
          pressKey(KEY_POWER);
          break;  
    например в таком кейсе внутри сделать запрос на ввод значения переменной Х.
    нажимаю p и после этого пока я не введу значение для переменной определенной, дальше ничего не едет.

    грубо говоря чтение с сериал внутри такого вот кейса.

    извините за кривое объяснение :(
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    зачем городить подменю? Клавиш на клавиатуре много, экран большой - выводи все меню сразу, а подменю выдели отступами.
    Ввод чисел из Serial есть в стандартном примере ReadASCIIString.
     
    Последнее редактирование: 17 дек 2015
    ArcticBear нравится это.
  8. ArcticBear

    ArcticBear Нерд

    Мы друг друга не правильно понимаем.
    Выше предложен вариант, когда я ввожу букву, алгоритм ее парсит и в результате выполняет кусок какого то кода. кейс ...
    а я хочу добиться варианта, когда можно внутри этого кейса еще раз запросить что то с клавиатуры.

    например:
    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);
    вот так мне нужно. но это не правильно.
     
  9. ArcticBear

    ArcticBear Нерд

    Код (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;
    кажется получилось вот так ... но на сколько это грамотно? пойдет?
     
  10. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (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();
    }
     
    Последнее редактирование: 17 дек 2015
    ArcticBear нравится это.
  11. ArcticBear

    ArcticBear Нерд

    Низкий поклон. Даже не знаю ... как отблагодарить.