Выход из цикла while с помощью ИК-пульта для neopixel

led ir loop neopixel

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

Сейчас я немного застопорился. Я создал цикл, который, кажется, не заканчивается. Я осмотрелся, но не могу понять, как исправить свой код. Извините за продвинутость, я новичок в использовании ардуино, но если кто-нибудь может помочь, это будет очень признательно. Спасибо!

//www.elegoo.com
//2016.12.9

#include "IRremote.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6


Adafruit_NeoPixel strip = Adafruit_NeoPixel(20, PIN, NEO_GRB + NEO_KHZ800);

int receiver = 11; // Сигнальный контакт ИК-приемника на цифровой контакт Arduino 11

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // создать экземпляр 'irrecv'
decode_results results;      // создать экземпляр 'decode_results'
int Remote = 0;

/*-----( Function )-----*/
void translateIR() // выполняет действие на основе полученного кода IR

// описание удаленных ИК-кодов

{

  switch(results.value)

  {
  case 0xFFA25D: Serial.println("POWER"); 
  ArrowRight(strip.Color(25, 0, 0), 100); //Красный
  ArrowRight(strip.Color(0, 0, 25), 100); //Синий
// Удаленный = 0xFFA25D;
  break;

  case 0xFFE21D: Serial.println("FUNC/STOP"); 
  ArrowLeft(strip.Color(25, 0, 0), 100); // Красный
  ArrowLeft(strip.Color(0, 0, 25), 100); // Синий
// Удаленный = 0xFFE21D;
  break;

  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK");    break;
  case 0xFF02FD: Serial.println("PAUSE");    break;
  case 0xFFC23D: Serial.println("FAST FORWARD");   break;
  case 0xFFE01F: Serial.println("DOWN");    break;
  case 0xFFA857: Serial.println("VOL-");    break;
  case 0xFF906F: Serial.println("UP");    break;
  case 0xFF9867: Serial.println("EQ");    break;
  case 0xFFB04F: Serial.println("ST/REPT");    break;
  case 0xFF6897: Serial.println("0");    break;
  case 0xFF30CF: Serial.println("1");    break;
  case 0xFF18E7: Serial.println("2");    break;
  case 0xFF7A85: Serial.println("3");    break;
  case 0xFF10EF: Serial.println("4");    break;
  case 0xFF38C7: Serial.println("5");    break;
  case 0xFF5AA5: Serial.println("6");    break;
  case 0xFF42BD: Serial.println("7");    break;
  case 0xFF4AB5: Serial.println("8");    break;
  case 0xFF52AD: Serial.println("9");    break;
  case 0xFFFFFFFF: Serial.println(" REPEAT");break;  

  default: 
    Serial.println(" other button   ");

  }// Конец регистра

  delay(0); // Не получать немедленный повтор


} // КОНЕЦ перевода IR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode"); 
  irrecv.enableIRIn(); // Запускаем приемник
  strip.begin();
  strip.show();
  Remote = 0;

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if (irrecv.decode(&results)) // получили ли мы ИК-сигнал?

  {
    translateIR(); 
    irrecv.resume(); // получаем следующее значение
  }  
}/* --(end main loop )-- */

void ArrowRight(uint32_t c, uint8_t wait) {
  while (Remote = 0xFFA25D) { 
    for (uint16_t i = strip.numPixels()/2; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
    for (uint16_t i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, 0);
    }
    strip.show();
    delay(wait);
  }
}

void ArrowLeft(uint32_t c, uint8_t wait) {
  while (Remote = 0xFFE21D) { // j<# определяет, сколько циклов
    for (uint16_t i = strip.numPixels()/2-1; i + 1 > 0 ; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
    for (uint16_t i = strip.numPixels(); i + 1 > 0 ; i--) {
      strip.setPixelColor(i, 0);
    }
    strip.show();
    delay(wait);
  }
}

, 👍0

Обсуждение

какой цикл работает постоянно?, @Chad G

Оба они, кажется, делают это в данный момент. Я думаю, это потому, что у меня есть Remote, равный значению, которое соответствует нажатию кнопки на моем пульте дистанционного управления. Я думаю, проблема в том, что я не смог реализовать «переопределение», как вы можете сказать, чтобы переключиться на другой цикл. Ваше здоровье., @YaBo11

оба какие? Вы имеете в виду циклы while в функциях Arrow? И они работают вечно, когда вы нажимаете соответствующую кнопку и отпускаете ее?, @Chad G

Я думаю, что вам не нужны циклы while — вы должны убрать их и превратить в одноразовые вызовы, а также убрать translateIR() из условного оператора в цикле(). Внутри условия, если вы получаете новое сообщение, скопируйте его из временной переменной в &result вместо обновления &result в каждом loop(), @Dave X

while (Remote = 0xFFE21D) Здесь вы должны использовать ==, иначе это будет присваивание, @chrisl


1 ответ


1

Есть несколько причин возникновения вечных циклов и других проблем в коде.

Как КрисЛ отметил выше, вы присваиваете значение Remote в условии while, что почти наверняка не то, что вы хотели сделать. Положительным моментом является то, что каждый программист на C/C++ в то или иное время совершал ту же ошибку.

Теперь, если вы измените его на while (Remote == 0xcFFE21D), он все равно не будет работать, потому что Remote всегда равен 0. Вы закомментировали строки, устанавливающие Remote, но они после вызов функции. Честно говоря, поскольку вы знаете значение до вызова функции (из-за оператора switch), вам не нужно проверять значение внутри функции, чтобы вы могли полностью удалить цикл while. Если вы намерены многократно вызывать эту функцию, пока на пульте не будет нажата другая кнопка, способ, которым вы это делаете, не сработает. вам нужно сохранить значение последней нажатой кнопки, а затем передать его в оператор switch. Когда нажата другая кнопка, обновите значение «последнее нажатие кнопки».

Вы должны посмотреть условия цикла. Я не думаю, что количество огней на полосе изменится во время работы программы. Если это так, то вы тратите впустую инструкции процессора, выполняя strip.numPixels()/2-1, возможно, вы захотите посмотреть на установку глобальных значений в настройке.

Кроме того, циклы for могут выиграть от использования i >= 0, потому что тогда вам не нужно выполнять i+1 каждый цикл.

,

Привет Горилла, спасибо вам и всем остальным за вашу помощь. Я новичок в C/C++, что вполне очевидно. Как вы и предложили, я хочу многократно вызывать определенную функцию, пока не будет нажата другая кнопка, чтобы переключиться на другую функцию. Я собираюсь попробовать это сейчас, но если кто-нибудь может помочь мне изменить код, это было бы очень полезно, спасибо!, @YaBo11

Вы узнаете больше, если сделаете это сами. :) Вы сказали, что вам нужно сделать в комментарии выше: «... многократно вызывать определенную функцию, пока не будет нажата другая кнопка ...» Поэтому убедитесь, что функция, которую вы вызываете, думает один раз, а затем возвращается. Код, который вызывает функцию, проверяет, не произошло ли «пока...», потому что именно этот код решил вызвать функцию в первую очередь. Вы прошли 90% пути., @Code Gorilla

Возможно, вам захочется поработать с концепциями программирования на C/C++ в среде IDE с символьным отладчиком, включая трассировку и точки останова. Отладка программ Arduino — это головная боль, поскольку у вас нет ни одного из этих инструментов. Вы должны добавить операторы печати последовательного порта и сделать достаточное количество догадок., @Duncan C

После того, как вы разработаете свою базовую логику, используя обычный не-Arduino C/C++, вы можете повторно реализовать свой код на Ardino., @Duncan C