Как использовать Serial в качестве прерывания для других функций - PullRequest
0 голосов
/ 20 января 2019

Я делаю программу управления светодиодами (конечно, с помощью FastLED) и использую Serial (с монитором Serial) для управления ею.Просто подключен через USB и по большей части работает просто отлично.Тем не менее, с длинными, мигающими процедурами я заметил, что не могу их остановить и заставить светодиоды делать что-то еще.Процедура прошивки в моем коде очень проста:

void flash(CRGB color, int count, int del){
  for(int i = 0; i < count; i++){
    if(pause){
      break;
    }
    fillLeds(color.r, color.g, color.b);
    milliDelay(del);
    fillLeds(0,0,0);
    milliDelay(del);
  }
}

С fillLeds(r,g,b) в качестве цикла for, циклом и настройкой всех светодиодов на определенный цвет, а milliDelay это просто delay() с использованием millis а не функция delay().Что мне нужно, так это уметь приостанавливать не только это, но и другие функции (вероятно, используя break;), а затем выполнять другой код.Кажется, легко, правда?Ну, я заметил, что когда я посылаю байт через последовательный порт, он попадает в эту «очередь», если хотите, и затем последовательно читается.Я не могу этого случиться.Что мне нужно, так это следующий байт, вводящий Serial, чтобы активировать какое-то событие, которое приостанавливает выполнение другой функции flash() и затем используется.Я реализовал это следующим образом:

void loop()
{
    if (Serial.available() > 0) {
      int x = Serial.read();
      Serial.print(x);
      handleRequest(x);
    }

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

, где handleRequest(x); - это просто длинный оператор switch с вызовами метода flash, с использованием разных цветов и т. Д.

Howможно ли заставить Arduino приостанавливать другие циклы при получении нового байта, вместо того, чтобы добавить его в эту «очередь» для последующей обработки?Если это невозможно, спасибо за чтение в любом случае.Я пытался использовать serialEvent(), который не работает.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Я думаю, вам нужно 2 петли. У вас есть один, который является вашим основным циклом, вы можете добавить другой (например, многопоточность) с библиотекой TimerOne. Как это:

Timer1.initialize(your desired delay in this loop);
Timer1.attachInterrupt( your desired function in this loop);

Возможно, вы можете добавить оператор if с переменной var во второй цикл, чтобы предотвратить использование какой-либо функции и обновить переменную в вашем первом цикле или что-то в этом роде.

0 голосов
/ 21 января 2019

Насколько я понимаю, вам нужна функциональность, подобная прерыванию, когда приходит новый байт?

К сожалению, serialEvent и не является настоящим прерыванием. Он запускается только в конце loop, если доступны последовательные данные.

Однако serialEvent - это просто функция, и нет никаких причин, по которым вы не можете вызывать ее в своем коде так часто, как вам нравится. Это эффективно опрос новых серийных данных как можно чаще. Поэтому, пока ваши циклы работают, во время задержек вызовите serialEvent и обработайте там последовательные данные.

Возможно, вам придется реструктурировать код, чтобы избежать рекурсии. Если flash вызывает serialEvent, что вызывает flash, что вызывает serialEvent и т. Д., То вы можете в конечном итоге переполнить стек.

...