Проблема с одновременным использованием IR Remote и ШИМ (ардуино нано)

Тема в разделе "Arduino & Shields", создана пользователем Guri, 5 июн 2016.

  1. Guri

    Guri Нерд

    Добрый день!
    Возникает проблема с одновременным использованием IR Remote и ШИМ.
    Сначала все работает но после нескольких переключений перестает.
    При этом если использовать ИК пульт или ШИМ по отдельности, то все работает.
    Подскажите, в чем проблема.
    Спасибо!

    При нажатии на кнопку мы плавно опускаем яркость света до нуля, измененяем цвета светодиодов, и потом увеличиваем яркость до максимума.

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

    #define R 9
    #define G 10
    #define B 11

    int RECV_PIN = 17;

    IRrecv irrecv(RECV_PIN);
    decode_results results;

    #define ColChangePrecision 100
    bool ColChanged=true;
    int colChangeNum=0;

    #define pi 3.1415
    int col[]={0,0,255};

    void setup() {
      Serial.begin(9600);
      irrecv.enableIRIn();

      pinMode(R, OUTPUT);
      pinMode(G, OUTPUT);
      pinMode(B, OUTPUT);

    }

    void loop () {

      if (irrecv.decode(&results)) {
        //если мы считали сигнал изменяем цвет
        long val=results.value;
        if(val== 16761405 || val==553536955 || val==4294967295) {
          ColChanged=false;
          }
        irrecv.resume(); // Receive the next value
        Serial.println(results.value, DEC);
      }

      if (!ColChanged){
          colChange();
          delay(5);
        }
    }

    void colChange(){
      //плавное изменение яркости света до нуля, изменение цвета, и увеличение яркости до максимума
          colChangeNum++;
          double phase=double((colChangeNum))/(ColChangePrecision);
       
          if (colChangeNum>ColChangePrecision) {
            //здесь мы закончили
            colChangeNum=0;
            ColChanged= true;
          }
       
          if (colChangeNum==ColChangePrecision/2) {
            //посредине меняем цвет
            randCol(col);
          }
        double ampl=0.5*(cos(2*pi*phase)+1);
        // .                  .
        //    .            .    
        //     .          .
        //      .        .
        //         .  .

     
        int fc[]={int(ampl*col[0]),int(ampl*col[1]),int(ampl*col[2])};

       
        analogWrite(R,fc[0]);
        analogWrite(G,fc[1]);
        analogWrite(B,fc[2]);
      }

      void randCol(int arr[3]) {
        //генерирует случайный цвет
        analogWrite(G,fc[1]);
        analogWrite(B,fc[2]);
        int C1=rand()%3;
        int u=rand()%2;
        int C2=(C1+1+u)%3;
        int C3=(C1+1+!u)%3;

        double Bq1=50*(rand()%6);
        double Bq2=50*(rand()%5);
        double Bq3=50*(rand()%4);

        arr[C1]=Bq1;
        arr[C2]=Bq2;
        arr[C3]=Bq3;
      }
     
     
  2. Alex19

    Alex19 Гуру

    Библиотека IRremote использует таймер 1, он же используется для ШИМ на пинах 9 и 10 (если у Вас Arduino UNO\Nano).

    Воспользуйтесь другими пинами c ШИМ, у UNO кроме 9 и 10, есть еще 3, 5, 6 и 11
     
    Guri нравится это.
  3. vvr

    vvr Инженерище

    Guri нравится это.
  4. Guri

    Guri Нерд

    Спасибо!
    Сейчас попробую.
    Жаль что я не знал этого до того как все распаял.
     
  5. Guri

    Guri Нерд

  6. Alex19

    Alex19 Гуру

    Будут проблемы, говорите какая у Вас Ардуина (от этого зависит используемый таймер) и скидывайте ссылку на библиотеку, есть на 2 таймере, тогда ШИМ не будет работать на 3 и 11.

    UPD. У библиотеки IRremote используется 2 таймер для Uno\Nano запутался:(.

    Код (C++):
    // Arduino Mega
    #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      //#define IR_USE_TIMER1   // tx = pin 11
      #define IR_USE_TIMER2     // tx = pin 9
      //#define IR_USE_TIMER3   // tx = pin 5
      //#define IR_USE_TIMER4   // tx = pin 6
      //#define IR_USE_TIMER5   // tx = pin 46

    // Teensy 1.0
    #elif defined(__AVR_AT90USB162__)
      #define IR_USE_TIMER1     // tx = pin 17

    // Teensy 2.0
    #elif defined(__AVR_ATmega32U4__)
      //#define IR_USE_TIMER1   // tx = pin 14
      //#define IR_USE_TIMER3   // tx = pin 9
      #define IR_USE_TIMER4_HS  // tx = pin 10

    // Teensy 3.0
    #elif defined(__MK20DX128__)
      #define IR_USE_TIMER_CMT  // tx = pin 5

    // Teensy++ 1.0 & 2.0
    #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
      //#define IR_USE_TIMER1   // tx = pin 25
      #define IR_USE_TIMER2     // tx = pin 1
      //#define IR_USE_TIMER3   // tx = pin 16

    // Sanguino
    #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
      //#define IR_USE_TIMER1   // tx = pin 13
      #define IR_USE_TIMER2     // tx = pin 14

    // Atmega8
    #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
      #define IR_USE_TIMER1   // tx = pin 9

    // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
    #else
      //#define IR_USE_TIMER1   // tx = pin 9
      #define IR_USE_TIMER2     // tx = pin 3
    #endif
    И соответственно 3 и 11 ШИМ не будет работать.
     
    Последнее редактирование: 5 июн 2016
  7. Guri

    Guri Нерд

  8. Guri

    Guri Нерд

    А может вы за одно и подскажете, можно ли купить модуль который бы как на адресуемой светодиодной ленте принимал последовательный цифровой вход и задавал бы цвета. Что-то вроде HL1606
    http://we.easyelectronics.ru/part/a...a-s-hl1606-prodolzhaem-novogodnyuyu-temu.html
     
  9. Alex19

    Alex19 Гуру

    Библиотека другая, но для Nano используется тот же таймер 2, поэтому 3 и 11 ШИМ не будет работать.

    Не довелось работать с такими лентами, увы не подскажу.
     
  10. Guri

    Guri Нерд

    И как тогда исправлять? Изменить ШИМ 11 на 5 или 6?
     
  11. Alex19

    Alex19 Гуру

    Да это самый простой способ.

    Другие способы посложнее.
    Если это просто пайка, то проще перепаять, если это законченная плата, можно подумать как оставить все как есть и сделать софт ШИМ.
     
    Guri нравится это.
  12. Guri

    Guri Нерд

    Понял, спасибо!
     
  13. raptoridze

    raptoridze Нуб

    Задам вопрос тут
    есть ардуина Мега 2560
    к ней подключен олед єкран через SPI
    библиотека адафруит SSD1306
    вот пины к которым подключен экран
    Код (C++):
    #define OLED_MOSI   49
    #define OLED_CLK   53
    #define OLED_DC    51
    #define OLED_CS    50
    #define OLED_RESET 52
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
    IR приемник подключен к 9 пину
    IRrecv irrecv(9);
    если я физически не подключаю экран, но при этом вся инициализация в скетче есть
    то приемник четко принимает коды с пульта
    как только я физически подключаю экран к ардуине, то приемник начинает на нажатие кнопки ловить разные коды, их может быть десяток... и бывает разные...как будто в момент приема ловит какие то помехи
    библа IRremote висит на 2 таймере
    Код (C++):
    #define IR_USE_TIMER2
    пробовал разные пины для подключения инфракрасного приемника - результата нет ...
    подскажи как быть?
     
  14. BAR__MEN

    BAR__MEN Гуру

    Вы подключаете только на пины с шим?!)
    А на аналоговые пробовали?
     
  15. raptoridze

    raptoridze Нуб

    Только шимовские...
    Ок, попробую, спасибо)
     
  16. BAR__MEN

    BAR__MEN Гуру

    Я их на аналоги ставлю дабы экономить пины на уже:)
     
  17. raptoridze

    raptoridze Нуб

    на аналоговых, и не пвмных портах попробовал - таже ерунда (
     
  18. BAR__MEN

    BAR__MEN Гуру