Получить сокет в цикле arduino (прервать цикл while с помощью сокета)

В настоящее время я работаю над проектом Arduino. Если Arduino взаимодействует с сервером NodeJS через веб-сокеты.

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

Я нашел страницу с решением этой проблемы, но только с кнопкой, прикрепленной к Arduino.

Ссылка на страницу (Прерывание кнопкой)

Это цикл, который я хочу прервать с помощью сокета:

bool loopRunning = true;

void rainbow(int wait) {
while(loopRunning == true) {

      for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
        for(int i=0; i<strip.numPixels(); i++) { 
          int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
          strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
        }
        strip.show(); 
        delay(wait);  
      }
    }
}

Я хочу установить для loopRunning значение false, когда получаю эмитированный сокет.

У кого-нибудь есть идеи, как это реализовать?

Страница с функциональностью сокета, которую я использую

, 👍1


2 ответа


1

Существует два способа обработки событий: прерывания (аппаратный запуск) и опрос (программный запуск). Прерывания намного эффективнее, но и сложнее в использовании. SocketIoClient использует опрос

Необходимой частью опроса является... опрос. То есть много раз в секунду вам (или вашей библиотеке) нужно проверять, не происходит ли чего интересного.

С этой библиотекой вам придется вызывать SocketIoClient::loop() много раз в секунду. Вот почему существует SocketIoClient::loop(). Поэтому его нужно добавить во внешний цикл for.

(Если ваша delay(wait) занимает слишком много времени, возможно, вам придется разбить ее на несколько более коротких, но я думаю, что в этом случае вам это сойдет с рук.)

Тогда все, что вам нужно сделать, это использовать SocketIoClient::on() для выполнения действия при возникновении события. В документации есть пример. Вам нужно будет сделать loopRunning глобальной переменной.

,

0

Проблема заключается в выполнении перехвата цикла while. Когда у вас есть небольшой участок петли, который вы хотите вставить, вы можете сделать это двумя способами. Вы можете делать то же, что и с циклом while, который задерживает выполнение внутри цикла while, и больше ничего не происходит. Или вы можете позволить функции цикла быть циклом и использовать флаги и операторы if, чтобы решить, что выполняется.

Представьте себе этот код:

void loop() {
  if(loopRunning){
     // делаем вещи в вашем цикле while
  }
  else {
     // все остальные вещи в цикле, которые вы не хотите запускать во время этого
  }
  // все, что вы хотите запустить независимо, например, прослушивание вашего сокета.
}

Когда вы делаете это таким образом, вы по-прежнему получаете то, что вы собирались сделать в цикле while, чтобы оно происходило само по себе, без остальной части цикла, но вы также можете иметь некоторые вещи, которые работают в обоих направлениях. Эту логику можно расширить любыми способами. Возможно, вы хотите, чтобы эта часть выполнялась всегда, а остальная часть цикла пропускалась, если loopRunning имеет значение false.

void loop(){
   // все, что должно работать постоянно (например, ваш сокет)
   if(!loopRunning) {
       // все то, что вы бы поместили в код while(!loopRunning)
       // но не сможет поймать сокет.
   }
}
,

Вам также придется отказаться от вызовов задержки и перейти к использованию миллиса в стиле «Мигание без задержки», если вы действительно хотите реагировать на свой сокет. Циклы for также блокируются, вы можете сделать так, чтобы этот код выполнял один шаг за раз и ждал вызова из цикла, чтобы сделать следующий шаг. Погуглите для Arduino neopixel и non-blocking. Вы не первый, кто понимает, что демонстрационные материалы для неопикселей не работают в больших программах. Это не код для взлома, это просто для демонстрации., @Delta_G