IR + RGB PWM реально ли?

Тема в разделе "Arduino & Shields", создана пользователем Awaking, 14 май 2017.

  1. Awaking

    Awaking Нерд

    Хочу сделать плавное без дрыганий управление цветом rgb ленты. Залог этого - одинаковая частота ШИМ на всех трех каналах. Сделать это можно только с помощью таймера 1 (пины 9, 10) и таймера 2 (пины 11, 3), которые стандартно работают на 31250 Гц. Проблема в том, что нужно так же подключить IR приемник. Библиотека IRRemote работает на выбор как раз либо на 1 таймере, либо на 2... Вопрос: что делать?
    Если один из цветовых компонентов ленты перенести на Таймер 0, то получаются неравномерные, с дрыганием, переходы цветов ибо работает таймер на удвоенной частоте 62500 Гц. Изменить ее чревато, т.к на таймере 0 висят системные функции (delay, mills и тп),
     
  2. rkit

    rkit Гуру

    На прием таймер не нужен. Только на передачу.
     
  3. Awaking

    Awaking Нерд

    Но библиотека что-то делает с таймерами в момент инициализации, потому что после вызова irrecv.enableIRIn(); отрубается нормальное управление ШИМ. На прием используется прерывание таймера


    Код (C++):
    #include <IRremote.h>

    #define REDPIN    9
    #define GREENPIN  10
    #define BLUEPIN  11

    //IR Remote  ---------------------------------------------------------
    const int ir_pin = 10;
    IRrecv irrecv(ir_pin);
    decode_results results;

    void ir_remote_setup() {
      irrecv.enableIRIn(); // Start the receiver
    }

    void ir_remote_loop() {
      if (irrecv.decode(&results)) {
        Serial.println(results.value);
        irrecv.resume(); // Receive the next value
      }
    }
    //-----------------------------------------------------------------

    void setup() {
      ir_remote_setup(); //Comment to make PWM work
      Serial.begin(115200);
    }

    void loop() {
      static unsigned long lastPWMMills = 0;
      static uint8_t brightness = 0;
      if (millis() - lastPWMMills >= 10) {
        lastPWMMills = millis();
        brightness++;
        analogWrite(REDPIN,   brightness);
        analogWrite(GREENPIN, brightness);
        analogWrite(BLUEPIN,  brightness);
      }
    }
     
    Аналогичная ситуация с другой подобной библиотекой IRLib2
     
    Последнее редактирование: 14 май 2017
  4. Awaking

    Awaking Нерд

    Посоны, я нашел способ: есть еще один класс в либе IRLib2, использующий attachInterrupt() и не убивающий ШИМ: IRLibRecvPCI:

    Код (C++):
    #include <IRLibDecodeBase.h>
    #include <IRLib_P01_NEC.h>  
    #include <IRLib_P02_Sony.h>
    #include <IRLib_HashRaw.h>  //Must be last protocol
    #include <IRLibCombo.h>     // After all protocols, include this
    #include <IRLibRecvPCI.h>

    #define REDPIN    9
    #define GREENPIN  10
    #define BLUEPIN  11

    IRdecode myDecoder;

    IRrecvPCI myReceiver(2);  

    void setup() {
      Serial.begin(115200);
      myReceiver.enableIRIn(); // Start the receiver
      Serial.println(F("Ready to receive IR signals"));
    }

    void loop() {
      static unsigned long lastPWMMills = 0;
      static uint8_t brightness = 0;
      if (millis() - lastPWMMills >= 10) {
        lastPWMMills = millis();
        brightness++;
        analogWrite(REDPIN,   brightness);
        analogWrite(GREENPIN, brightness);
        analogWrite(BLUEPIN,  brightness);
      }

      if(myReceiver.getResults()) {
        myDecoder.decode();
        if(myDecoder.protocolNum==UNKNOWN) {
          Serial.print(F("Unknown protocol. Hash value is: 0x"));
          Serial.println(myDecoder.value,HEX);
        } else {
          myDecoder.dumpResults(false);
        };
        myReceiver.enableIRIn();
      }
    }
     
     
    Tomasina, arkadyf и UA4FAS нравится это.
  5. UA4FAS

    UA4FAS Нуб

    Спасибо дорогой! Я был просто в отчаянии. Думал придётся две прошивки делать. Пусть тебя не покидает удача!!! Зарегистрировался только для того, чтоб поблагодарить за поиск и проделанную работу.
     
    Последнее редактирование: 4 авг 2017