Светодиод Arduino RGB не работает все время?

Я создавал светодиодную систему RGB с одним светодиодом RGB, управляемым с помощью ИК-пульта дистанционного управления. Я хотел назначить кнопку для запуска индикатора настроения, который циклически переключается по радуге, и это отлично работает. Но когда я пытаюсь создать режим, в котором вы можете напрямую изменять значения RGB, он не работает должным образом. Я назначил номера на пульте дистанционного управления для переключения цвета, который вы меняете (например, 1 — красный, 2 — зеленый и т. д.), а громкость контролирует количество поступающего света, но когда у меня есть два цвета с положительными значениями, отображается только один. Понятия не имею, почему, ведь подсветка работает нормально и даже плавно переключается.

//www.elegoo.com
//2016.12.9

#include "IRremote.h"

// Определить пины
int BLUE = 3;
int GREEN = 5;
int RED = 6;

int addValue = 10;

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

int blueValue = 0;
int greenValue = 0;
int redValue = 0;

bool isMoodLightOn = false;
bool isBlueModeOn = false;
bool isGreenModeOn = false;
bool isRedModeOn = true;

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

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

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

{

  switch(results.value)

  {
  case 0xFFA25D: Serial.println("POWER"); break;
  case 0xFFE21D: Serial.println("FUNC/STOP"); break;
  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK"); break;
  case 0xFF02FD: Serial.println("PLAY/PAUSE"); 
                 isMoodLightOn = !isMoodLightOn; 
                 if (isMoodLightOn == false) {
                  isBlueModeOn = true;
                  isGreenModeOn = false;
                  isRedModeOn = false;

                  setColor(redValue, greenValue, blueValue);
                 } else {
                  isBlueModeOn = false;
                  isGreenModeOn = false;
                  isRedModeOn = false;
                 }
                 break;
  case 0xFFC23D: Serial.println("FAST FORWARD"); break;
  case 0xFFE01F: Serial.println("DOWN"); 
                 if (isBlueModeOn) {
                  if (blueValue > 0) {
                    blueValue = blueValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue > 0) {
                    greenValue = greenValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue > 0) {
                    redValue = redValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 break;
  case 0xFFA857: Serial.println("VOL-"); break;
  case 0xFF906F: Serial.println("UP"); 
                 if (isBlueModeOn) {
                  if (blueValue < 100) {
                    blueValue = blueValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue < 100) {
                    greenValue = greenValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue < 100) {
                    redValue = redValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 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"); isRedModeOn = true; isGreenModeOn = false; isBlueModeOn = false; break;
  case 0xFF18E7: Serial.println("2"); isRedModeOn = false; isGreenModeOn = true; isBlueModeOn = false; break;
  case 0xFF7A85: Serial.println("3"); isRedModeOn = false; isGreenModeOn = false; isBlueModeOn = true; 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(500); // Не получать немедленное повторение


} //КОНЕЦ переводаIR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");

  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  setColor(redValue, greenValue, blueValue);

  isBlueModeOn = true;
  isGreenModeOn = false;
  isRedModeOn = false;

  irrecv.enableIRIn(); // Запускаем приемник

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


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{ 
  setColor(redValue, greenValue, blueValue);

  if (irrecv.decode(&results)) // получили ли мы ИК-сигнал?

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

  setColor(redValue, greenValue, blueValue);

  if (isMoodLightOn == true) {
      int delayTime = 10; // время плавного перехода между цветами

      redValue = 255; // выберите значение от 1 до 255, чтобы изменить цвет.
      greenValue = 0;
      blueValue = 0;

      // в этом нет необходимости, поскольку мы либо включили RED в НАСТРОЙКЕ
      // или в предыдущем цикле... независимо от того, это выключает RED
      // AnalogWrite(RED, 0);
      // задержка(1000);

      for(int i = 0; i < 255; i += 1) // исчезает красный цвет, становится зеленым, когда i=255
      {
        redValue -= 1;
        greenValue += 1;
        // Следующее было перевернуто, считая в неправильном направлении
        // AnalogWrite(RED, 255 - redValue);
        // AnalogWrite(GREEN, 255 - greenValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 255;
      blueValue = 0;

      for(int i = 0; i < 255; i += 1) // зеленый исчезает, а синий становится полным, когда i=255
      {
        greenValue -= 1;
        blueValue += 1;
        // Следующее было перевернуто, считая в неправильном направлении
        // AnalogWrite(GREEN, 255 - greenValue);
        // AnalogWrite(BLUE, 255 - blueValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 0;
      blueValue = 255;

      for(int i = 0; i < 255; i += 1) // синий исчезает, а красный становится полным, когда i=255
      {
        // Следующий код был переработан, чтобы соответствовать двум другим аналогичным разделам
        blueValue -= 1;
        redValue += 1;
        // Следующее было перевернуто, считая в неправильном направлении
        // AnalogWrite(BLUE, 255 - blueValue);
        // AnalogWrite(RED, 255 - redValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }
  }
  setColor(redValue, greenValue, blueValue);
}/* --(end main loop )-- */

void setColor(int red, int green, int blue) {
  analogWrite(BLUE, blue);
  analogWrite(GREEN, green);
  analogWrite(RED, red);
}

, 👍0

Обсуждение

Вы дважды используете setColor() внутри функции цикла вне кода настроения. Когда функция не находится в режиме настроения, эта функция быстро повторяется, выполняя множество аналоговых операций записи за короткое время. Это каждый раз сбрасывает аппаратное обеспечение ШИМ, эффективно искажая сигнал. Попробуйте удалить эти две строки (они вам не нужны, поскольку вы уже устанавливаете цвета в translateIR()). И вы можете захотеть, чтобы код был более отзывчивым в режиме настроения. Затем вам следует реструктурировать свой код, чтобы он был неблокирующим, как в примере BlinkWithoutDelay в Arduino IDE., @chrisl


1 ответ


Лучший ответ:

0

Я сформулирую свой комментарий как развернутый ответ.

Внутри функции loop() вы используете setColor() дважды, непосредственно на самом нижнем уровне. Когда вы не находитесь в режиме настроения, весь оператор if после него не будет выполнен, поэтому внутри одной итерации функции мало что происходит, и она будет выполняться очень быстро, устанавливая цвета снова и снова.

Функция setColor() состоит только из вызовов analogWrite(). Он настраивает оборудование Atmegas так, что на выводе будет генерироваться сигнал ШИМ. Для этого соответствующие аппаратные регистры (для одного из таймеров). Это также позволит снова запустить волну ШИМ. Если вы делаете это очень быстро (то есть в диапазоне самого сигнала ШИМ или быстрее), вы уничтожите всю форму сигнала ШИМ, начиная снова и снова. Представьте себе, что вы ждете, нажимая кнопку повтора на музыкальном плеере снова и снова, очень быстро. Вы сможете узнать музыку, так как она обрезана из-за повтора.

Вышеупомянутые две строки также не являются необходимыми, поскольку вывод волны ШИМ осуществляется аппаратно и не требует какого-либо кода после его включения с помощью analogWrite(). Так что вы можете просто удалить эти две строки.

,