ИК-приемник начинает выдавать неверные показания при настройке изменения цвета светодиода

Во-первых, я новичок в этом деле, так что извините, если вопрос глупый.

У меня есть ИК-модуль, который я использую для управления светодиодной лентой. Я установил кнопки 1–3 на пульте дистанционного управления для выбора трех основных статических цветов, а также кнопки вверх и вниз для регулировки яркости. Пока все хорошо.

Я установил кнопку 4 для постепенного переключения между разными цветами. После активации этого кода ИК-приемник, похоже, перестает работать, а Serial.print показывает, что теперь он сообщает случайные значения, какую бы кнопку я ни нажал на пульте дистанционного управления.

Я пробовал приемники типа Vishay TSOP4838 и KY-022, а также пробовал различные комбинации резисторов и конденсаторов в блоке питания приемника. Я пробовал питать его от 3,3 В и 5 В.

Код, который я использую, изменяет только числовые значения для настройки цвета, поэтому, если только где-то в оборудовании нет «шума», я не понимаю, почему только этот код его нарушает. Светодиод питается от адаптера 12 В. ИК-приемник — единственное, что питается от Arduino.

Мой полный код выглядит следующим образом, я знаю, что он неаккуратный. Я нуб:

Спасибо

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

//Чтобы изменить контакты светодиода/ИК-приемника, вам просто нужно изменить эти значения
#define PIN 13 //Светодиодная лента
int receiver = 10; //ИК-приемник

unsigned long debouncing = 0;
unsigned long rotatedelay = 6;
unsigned long fadegap = 5;
byte state = 0; //поддерживает функцию на основе последнего нажатия кнопки
byte red = 0;
byte blue = 0;
byte green = 0;
byte brightness = 250;
byte rotate = 0; //используется для циклического переключения цветов в состоянии 4

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

//Объявляем объекты IR
IRrecv irrecv(receiver);     // создаем экземпляр 'irrecv'
decode_results results;      // создать экземпляр 'decode_results'

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

// Наименование удаленных ИК-кодов и назначение «состояния»

{

  switch(results.value)

  {
  case 0xFFA25D: state = 10; Serial.println("POWER"); break;
  case 0xFF629D: state = 11; Serial.println("VOL+"); break;
  case 0xFFE21D: state = 12; Serial.println("FUNC/STOP"); break;
  case 0xFF22DD: state = 13; Serial.println("FAST BACK");    break;
  case 0xFF02FD: state = 14; Serial.println("PLAY/PAUSE");    break;
  case 0xFFC23D: state = 15; Serial.println("FAST FORWARD");   break;
  case 0xFFE01F: Serial.println("DOWN");    break;
  case 0xFFA857: state = 17; Serial.println("VOL-");    break;
  case 0xFF906F: Serial.println("UP");    break;
  case 0xFF9867: state = 19; Serial.println("EQ");    break;
  case 0xFFB04F: state = 20; Serial.println("ST/REPT");    break;
  case 0xFF6897: state = 0; Serial.println("0");    break;
  case 0xFF30CF: state = 1; Serial.println("1");    break;
  case 0xFF18E7: state = 2; Serial.println("2");    break;
  case 0xFF7A85: state = 3; Serial.println("3");    break;
  case 0xFF10EF: state = 4; Serial.println("4");    break;
  case 0xFF38C7: state = 5; Serial.println("5");    break;
  case 0xFF5AA5: state = 6; Serial.println("6");    break;
  case 0xFF42BD: state = 7; Serial.println("7");    break;
  case 0xFF4AB5: state = 8; Serial.println("8");    break;
  case 0xFF52AD: state = 9; Serial.println("9");    break;
  case 0xFFFFFFFF: Serial.println("REPEAT");break;  

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

  }// Конец случая


} //КОНЕЦ translateIR

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Запускаем ИК-приемник
  strip.begin();
  colorBlock(strip.Color(0, 0, 0)); 
  strip.show(); // Инициализируем все пиксели как «выкл»

//Уменьшает яркость светодиодной ленты при запуске
for(uint8_t b = 0; b <255; b++) {
     for(uint8_t i=0; i < strip.numPixels(); i++) {
        strip.setPixelColor(i, 255 * b/255, 255 * b/255, 255 * b/255);
     }

     strip.show();
     delay(5); //скорость появления (20 x 255 = общее время)
  };
}

void loop() {

//Код обнаружения ИК
//if (irrecv.decode(&results) && millis() - debouncing > 1000) // получили ли мы ИК-сигнал? игнорирует нажатие кнопки, если прошло менее секунды после предыдущего
if (irrecv.decode(&results)) // получили ли мы ИК-сигнал?
{
    translateIR(); 
    irrecv.resume(); // получить следующее значение
    Serial.println(results.value, HEX);

if (state == 1){
  rotate = 0;
  red = 0; blue = 255; green = 0;
colorBlock(strip.Color(red, blue, green));  
}

if (state == 2){
  rotate = 0;
  red = 0; blue = 0; green = 255;
colorBlock(strip.Color(red, blue, green));  
}

if (state == 3){
  rotate = 0;
  red = 255; blue = 0; green = 255;
colorBlock(strip.Color(red, blue, green));  
}

//яркость
if (results.value == 16769055 && brightness > 0){
  brightness = brightness - 10;
  strip.setBrightness(brightness); strip.show();  
  Serial.println(brightness);
}

if (results.value == 16748655 && brightness < 241){
  brightness = brightness + 10;
  strip.setBrightness(brightness); colorBlock(strip.Color(red, blue, green));     strip.show();  
  Serial.println(brightness);
}
}

//смена цветов
if (state == 4){
  //Serial.println (состояние);
  //Serial.println (поворот);
  //Serial.print ("красный"); Serial.print (красный); Serial.print ("синий"); Serial.print (синий); Serial.print ("зеленый"); Serial.println (зеленый);
  //Serial.println (rotatedelay);
}

if (state == 4 && rotate == 0 && red < 255 && millis() - rotatedelay > 1){
  red = red + fadegap; 
  if (blue >= 1){
    blue = blue - fadegap;} 
  if (green >= 1){
    green = green - fadegap;}
  colorBlock(strip.Color(red, blue, green)); 
  rotatedelay = millis();
}

if (state == 4 && rotate == 0 && green > 0 && millis() - rotatedelay > 1){
  green = green - fadegap; 
  colorBlock(strip.Color(red, blue, green)); 
  rotatedelay = millis();
}

if (state == 4 && rotate == 0 && red == 255 && green == 0 && blue == 0 &&         millis() - rotatedelay > 1){
  rotate = 1;
}

if (state == 4 && rotate == 1 && blue < 255 && millis() - rotatedelay > 1){
  blue = blue + fadegap; 
  if (red >= 1){
    red = red - fadegap;} 
  if (green >= 1){
    green = green - fadegap;}
  colorBlock(strip.Color(red, blue, green)); 
  rotatedelay = millis();
}

if (state == 4 && rotate == 1 && red == 0 && green == 0 && blue == 255 &&     millis() - rotatedelay > 1){
  rotate = 2;
}

if (state == 4 && rotate == 2 && green < 255 && millis() - rotatedelay > 1){
  green = green + fadegap; 
  if (red >= 1){
    red = red - fadegap;} 
  if (blue >= 1){
    blue = blue - fadegap;}
  colorBlock(strip.Color(red, blue, green)); 
  rotatedelay = millis();
}

if (state == 4 && rotate == 2 && blue == 0 && red == 0 && green == 255 &&     millis() - rotatedelay > 1){
  rotate = 0;
}
}

//Сплошной цвет
 void colorBlock(uint32_t c) { //Похоже, это способ раскрасить всю полоску
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    }
 }

, 👍1

Обсуждение

Возможно, создайте две альтернативные тестовые установки: одну, где ИК-приемник может «видеть» светодиодную ленту, но нет никакого электрического соединения (т. е. вторая установка с другим Arduino на другом компьютере). Другая с вашими типичными электрическими соединениями, но где ИК-приемник полностью экранирован от любого вида светодиодов — обернут в несколько слоев изоляционной ленты или что-то в этом роде., @Chris Stratton

удалить весь код внутри операторов if (state == 4 && и вставить операторы Serial.println( для отладки, @jsotola

совет: вы можете использовать такой код: if (blue >= 1) blue -= fadegap;, @jsotola

У меня были некоторые проблемы с ШИМ светодиода, мешающей ИК-сигналу. Или так мне показалось, по крайней мере. Теоретически, приемник должен иметь полосовой фильтр на 38 кГц. Кроме того, ваш код не компилируется: в конце вашей функции цикла отсутствует '}'., @tttapa

Спасибо за идеи. Я пробовал изолировать свет от приемника, но безуспешно. Возможно, это ШИМ, мне нужно почитать, как работает фильтр. О, и код компилируется, это была просто ошибка копирования/вставки. Спасибо, @Simontheintrepid


1 ответ


1

Перед строками

//смена цветов
if (state == 4){

У вас есть лишняя закрывающая скобка. ЕСЛИ она есть в вашем реальном коде, я не уверен, как она компилируется.

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

if (state == 4)
{
    if (millis() - rotatedelay > 1)
    {
        if (rotate == 0)
        {
            checkFadeGap (red, blue, green);

            if (green > 0)
            {
                green -= fadegap; 
                colorBlock(strip.Color(red, blue, green)); 
                rotatedelay = millis();
            }//если (зеленый > 0)
            if (red == 255  && green == 0 && blue == 0)
            {
                rotate = 1;
            }//если (красный == 255)
        }
        if (rotate == 1)
        {
            checkFadeGap (blue, red, green);
            if (red == 0 && green == 0 && blue == 255)
            {
                rotate = 2;
            }//если (синий == 255)
        }
        if (rotate == 2)
        {
            checkFadeGap (green, reb, blue);
            if (red == 0  && green == 255 && blue == 0)
            {
                rotate = 0;
            }//если (зеленый == 255)
        }
    }//если (millis() - rotatedelay > 1)
}    // конец if (состояние == 4)

Эта функция устраняет часть сложности в коде выше.

void checkFadeGap (byte& inc, byte& dec1, byte& dec2)
{
    if (inc < 255)
    {
        inc += fadegap;
        if (dec1 > 0)
            dec1 -= fadegap;
        if  (dec2 > 0);
            dec2 -= fadegap;
        colorBlock(strip.Color(red, blue, green)); 
        rotatedelay = millis();
    }
}
,