IR remote на atmega8

kiril22
Offline
Зарегистрирован: 06.11.2013

Задача, казалось бы, тривиальная - включать/выключать лампу накаливания с ик пульта. Примеров масса. В самой бибилиотеке IR remote есть такой пример (IRrecvDemo). И на atmega328 (arduino uno) все прекрасно работает. Но если захотеть залить IRrecvDemo в atmega8, то облом! Не хватает 8 кб. Хотя головой понимаю, что для этой задачи atmega8 должно хватить с избытком.

Отсюда вопрос - как  решить проблему включения нагрузки с ик пульта на atmega8?

Для себя вижу 2 пути решения:

1. Как то "ужать" библиотеку IR remote.

2. Писать скетч без этой библиотеки.

Подскажите в каком направлении двигаться правильнее?

Может есть готовые решения в среде Arduino IDE?

MaksMS
Offline
Зарегистрирован: 11.03.2013

Только если переписать прошивку на чистом Си.

kiril22
Offline
Зарегистрирован: 06.11.2013

Для меня на данный момент это сложновато :(

MaksMS
Offline
Зарегистрирован: 11.03.2013

Какая именно библиотека IR remote используется ? Ссылка ?

Клапауций
Offline
Зарегистрирован: 10.02.2013

kiril22 пишет:

Задача, казалось бы, тривиальная - включать/выключать лампу накаливания с ик пульта. Примеров масса. В самой бибилиотеке IR remote есть такой пример (IRrecvDemo). 

ну, и включайте лампу - зачем для этого нужно что-то в компорт писать?

kiril22 пишет:

Может есть готовые решения в среде Arduino IDE?

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

Размер скетча в двоичном коде: 6 548 байт (из 8 192 байт максимум)
 

#include <IRremote.h>

IRrecv irrecv(4);
decode_results results;

unsigned long ir;

void setup() {

pinMode(14, OUTPUT);
digitalWrite(14, LOW);

irrecv.enableIRIn(); // включить приемник
ir = results.value;
}

void loop() {

if (irrecv.decode(&results)) {if ((results.value > 0) && (results.value < 0xFFFFFFFF)) {unsigned long nir = results.value; if (nir != ir) {ir = nir; LED();}} irrecv.resume();}
}

void LED() {

if (ir == 50168445) {if (digitalRead(14) != HIGH) {digitalWrite(14, HIGH);}}
if (ir == 50156205) {if (digitalRead(14) != LOW) {digitalWrite(14, LOW);}}

}

и, сделать "Step 2" отсюда(на пару байтов некс похудеет) - там чел много чего ещё делал, но я не понял

http://ubiyubix.wordpress.com/2012/05/05/porting-the-arduino-irremote-library-to-the-attiny4313/

kiril22
Offline
Зарегистрирован: 06.11.2013

вот  ссылка на библиотеку

https://github.com/shirriff/Arduino-IRremote

MaksMS
Offline
Зарегистрирован: 11.03.2013

Да,кстати , если убрать все упоминания сериал порта,то скетч меньше вроде бы на пару кб :)

kiril22
Offline
Зарегистрирован: 06.11.2013

Клапауций пишет:

ну, и включайте лампу - зачем для этого нужно что-то в компорт писать?

Вот верно в народе говорят "Утро вечера мудреннее" :)

Сел переписал свой код (подобен Вашему) и мой скетч стал меньше 8 кб. Вчера вечером-ночью у меня это не удавалось. Точно косяк у меня в мозгу.

Вот мой код:


#include <IRremote.h>
 
int RECV_PIN = 11;
int LED_PIN = 13; 
IRrecv irrecv(RECV_PIN);
 
decode_results results;

int x=0;
int power=0; 
void setup()
{

irrecv.enableIRIn(); 
 
pinMode(LED_PIN, OUTPUT);

}
 
void loop() 

{
  
  if (irrecv.decode(&results)) {

 delay (50);
if (results.value==0xFFB24D) {
x=1;
power=!power;
}

if (x==1) {
digitalWrite(LED_PIN, power);
}

irrecv.resume(); 
}
}

Спасибо за помощь!

triada13
Offline
Зарегистрирован: 04.01.2013

kiril22? обратитесь к уважаемому камраду kisoft, он перелопатил библиотеку IRremote, под atmega16, и теперь мой скетч занимает всего 8 с небольшим килобайт, а в нем задействовано 11 кнопок.

Вот скрин: http://clip2net.com/s/675xdG

Вот код:

#include <IRremote.h>


//#include <IRremote.h> //Зацепили библиотеку

/////////////////////Секция переменных//////////////////////

int RECV_PIN = 10; //Назначили пин для ИР приемника

/*
 * Храним индекс пина (только для PWM) который выбран последним
 */
int8_t g_index = -1;
/*
 * Код последней нажатой кнопки. Используется для выдачи кода при получении кода повтора
 */
unsigned long last_button = 0;

/*
 * Начальная яркость LEDов с PWM
 */
#define START_BRIGHT    200
/*
 * Шаг изменения яркости
 */
#define BRIGHT_STEP     10

/*
 * Обработка IR сигналов с пульта
 */
IRrecv irrecv(RECV_PIN);
decode_results results;

/*
 * Если нужна отладка на Serial, закомментарь эту строку (код будет больше по объему)
 */
#define USE_RELEASE 1

#if !defined(USE_RELEASE)
#define INIT_SERIAL(x) Serial.begin( (x) )
#define PRINT_DEBUG(x) Serial.print( (x) )
#define PRINTLN_DEBUG(x) Serial.println( (x) )
#define PRINTLNHEX_DEBUG(x) Serial.println( (x), HEX )
#else
#define INIT_SERIAL(x)
#define PRINT_DEBUG(x)
#define PRINTLN_DEBUG(x)
#define PRINTLNHEX_DEBUG(x)
#endif

/////////////////////Секция констант////////////////////////

/*
 * Это мои коды от Yamaha пульта
 
#define BTN_0 0x3EC1C936
#define BTN_1 0x3EC129D6
#define BTN_2 0x3EC1A956
#define BTN_3 0x3EC16996
#define BTN_4 0x3EC1E916
#define BTN_5 0x3EC119E6
#define BTN_6 0x3EC19966
#define BTN_7 0x3EC159A6
#define BTN_8 0x3EC1D926
#define BTN_9 0x3EC139C6
#define BTN_UP 0x3EC12DD2
#define BTN_DOWN 0x3EC1CD32
#define BTN_LEFT 0x3EC1AD52
#define BTN_RIGHT 0x3EC16D92
#define BTN_POWER 0x3EC101FE
#define BTN_VOL_UP 0x5EA158A7
#define BTN_VOL_DOWN 0x5EA1D827
#define BTN_STOP 0x3EC1A15E
#define BTN_EQ 0x3EC11DE2
#define BTN_REPT 0x3EC141BE
#define BTN_RETENTION 0xFFFFFFFF
*/

#define BTN_0 16593103L // Определяем константы для кнопок пульта. (коды кнопок)
#define BTN_1 16582903L
#define BTN_2 16615543L
#define BTN_3 16599223L
#define BTN_4 16591063L
#define BTN_5 16623703L
#define BTN_6 16607383L
#define BTN_7 16586983L
#define BTN_8 16619623L
#define BTN_9 16603303L
#define BTN_UP 16601263L
#define BTN_DOWN 16584943L
#define BTN_LEFT 16589023L
#define BTN_RIGHT 16605343L
#define BTN_POWER 16580863L
#define BTN_VOL_UP 16613503L
#define BTN_VOL_DOWN 16617583L
#define BTN_STOP 16597183L
#define BTN_EQ 16625743L
#define BTN_REPT 16609423L
#define BTN_RETENTION 4294967295L

////////////////////Секция массивов///////////////////////// 
/*
 * Под массив пинов выделяем N + 1 байт. Мы обрабатываем N кнопок, но поскольку удобно индекс с 1, то 0 элемент не используется
 */
#define MAX_PINS (9+1)

/*
 * Внимание! Сейчас нельзя использовать PWM на выводе PD7 (пин 7), поскольку этот таймер используется для формирования прерываний для распознавания кодов PWM
 */
enum PinState
{
  pdIS_OFF = 0,
  pdIS_ON = 0x01,
  pdPWM_ENABLED = 0x02
};

/*
 * Информация об одном пине
 */
struct PinInfo
{
  /* Номер пина */
  uint8_t    pin_number;
  /* Состояние пина */
  uint8_t    pin_state;    // PinState
  /* Яркость пина (только для PWM) */
  int16_t    pin_bright;

  /*
   * Возвращает признак, что LED включен
   */
  uint8_t isOn() const
  {
    return pin_state & pdIS_ON;
  }
  /*
   * Возвращает признак, что LED выключен
   */
  uint8_t isOff() const
  {
    return !isOn();
  }
  /*
   * Возвращает признак, что LED может управляться PWM
   */
  uint8_t isPWMEnabled() const
  {
    return pin_state & pdPWM_ENABLED;
  }
  /* Выключение LED */
  void LEDOff()
  {
    pin_state &= ~pdIS_ON;
    if( pin_state & pdPWM_ENABLED )
    {
      analogWrite( pin_number, 0 );
    }
    else
    {
      digitalWrite( pin_number, LOW );
    }
  }
  /* Включение LED */
  void LEDOn()
  {
    pin_state |= pdIS_ON;
    if( pin_state & pdPWM_ENABLED )
    {
      analogWrite( pin_number, pin_bright );
    }
    else
    {
      digitalWrite( pin_number, HIGH );
    }
  }
  /* Добавление яркости LED. Только для PWM, для остальных - игнорируется */
  void addBright( uint8_t step )
  {
    if( isPWMEnabled() )
    {
      pin_bright += step;
      if( pin_bright > 255 )
      {
        pin_bright = 255;
      }
      LEDOn();
    }
  }
  /* Уменьшение яркости LED. Только для PWM, для остальных - игнорируется */
  void subBright( uint8_t step )
  {
    if( isPWMEnabled() )
    {
      pin_bright -= step;
      if( pin_bright < 0 )
      {
        pin_bright = 0;
      }
      LEDOn();
    }
  }
};

/*
 * Конфигурация пинов (LEDов) системы. 0 элемент не используется
 */
PinInfo pins[MAX_PINS] =
{
  /* Не используется */
  {  0, pdIS_OFF, 0 },

  /* Далее реальные пины */
  {  4, pdPWM_ENABLED, START_BRIGHT },
  {  5, pdPWM_ENABLED, START_BRIGHT },
  { 19, pdIS_OFF, 0 },
  { 20, pdIS_OFF, 0 },
  { 21, pdIS_OFF, 0 },
  { 18, pdIS_OFF, 0 },
  { 6, pdIS_OFF, 0 },
  { 3, pdIS_OFF, 0 },
  { 2, pdIS_OFF, 0 }
};

/*
 * Погасить все светодиоды. Сбрасывает индекс последней нажатой кнопки
 */
void off_pins( void )
{
  for( uint8_t p = 1; p < MAX_PINS; p++ ) // Выключаем все светодиоды
  {
    pins[ p ].LEDOff();
  }
  g_index = -1;
}

void setup()  
{
  INIT_SERIAL( 57600 );       // Инициализируем порт, скорость 57600.
  PRINTLN_DEBUG("Port Init"); // Выводим в порт сообщение.

  for( byte p = 1; p < MAX_PINS; p++ ) // Определяем пины светодиодов на вывод и моргаем для тестирования
  {
    pinMode( pins[ p ].pin_number, OUTPUT );
    digitalWrite( pins[ p ].pin_number, HIGH );
    delay(500);
    pins[ p ].LEDOff();
    delay(500);
  }
  /*
   * Начальное значание индекса устанавливаем в -1 иначе будут глюки
   */
  g_index = -1;

  /*
   * Включаем датчик на приём
   */
  irrecv.enableIRIn();
}

void loop() 
{
  /*
   * Ожидание кода с пульта. В это время мы ничего больше не делаем, только ожидаем сигнал (цикл ожидания организован в библиотеке)
   */
  if(irrecv.decode(&results))
  {
    /* Сохраняем полученный код, чтобы его не затер следующий код */
    unsigned long l_value = results.value;
    /* И сразу разрешаем прием следующего кода */
    irrecv.resume();
    /* Если это не код повтора, сохраняем полученный код */
    if( BTN_RETENTION != l_value )
    {
      last_button = l_value;
    }
    /* Если это код повтора, обрабатываем его отдельно */
    else
    {
      /* Повторяем предыдущую нажатую кнопку, только если это увеличение или уменьшение яркости */
      if( BTN_VOL_UP == last_button || BTN_VOL_DOWN == last_button )
      {
        l_value = last_button;
      }
      /* Иначе игнорируем */
      else
      {
        return;
      }
    }
    /* Определяем, какая кнопка нажата и выполняем нужное действие */
    switch (l_value)
    {
    case BTN_0: // Выключение ВСЕХ светодиодов
      PRINTLN_DEBUG("Button 0: OFF all LEDs");       
      off_pins();
      break;

#if MAX_PINS > 1
    case BTN_1:  // Включение/выключение LED1 (разрешен ШИМ)
      PRINT_DEBUG("Button 1: on/off LED on pin: ");
      PRINTLN_DEBUG( pins[ 1 ].pin_number );
      check_button( 1 );
      break;
#endif

#if MAX_PINS > 2
    case BTN_2:  // Включение/выключение LED2 (разрешен ШИМ)
      PRINT_DEBUG("Button 2: on/off LED on pin: ");
      PRINTLN_DEBUG( pins[ 2 ].pin_number );
      check_button( 2 );
      break;
#endif

#if MAX_PINS > 3
    case BTN_3:  // Вкл/выкл LED3 (без ШИМ)
      PRINT_DEBUG("Button 3: toggle pin: ");
      PRINTLN_DEBUG( pins[ 3 ].pin_number );
      check_button( 3 );
      break;
#endif

#if MAX_PINS > 4
    case BTN_4:  // Вкл/выкл LED4 (без ШИМ)
      PRINT_DEBUG("Button 4: toggle pin: ");
      PRINTLN_DEBUG( pins[ 4 ].pin_number );
      check_button( 4 );
      break;
#endif

#if MAX_PINS > 5
    case BTN_5:  // Вкл/выкл LED5 (без ШИМ)
      PRINT_DEBUG("Button 5: toggle pin: ");
      PRINTLN_DEBUG( pins[ 5 ].pin_number );
      check_button( 5 );
      break;
#endif

#if MAX_PINS > 6
    case BTN_6:  // Вкл/выкл LED6 (без ШИМ)
      PRINT_DEBUG("Button 6: toggle pin: ");
      PRINTLN_DEBUG( pins[ 6 ].pin_number );
      check_button( 6 );
      break;
#endif

#if MAX_PINS > 7
    case BTN_7:  // Вкл/выкл LED7 (без ШИМ)
      PRINT_DEBUG("Button 7: toggle pin: ");
      PRINTLN_DEBUG( pins[ 7 ].pin_number );
      check_button( 7 );
      break;
#endif

#if MAX_PINS > 8
    case BTN_8:  // Вкл/выкл LED8 (без ШИМ)
      PRINT_DEBUG("Button 8: toggle pin: ");
      PRINTLN_DEBUG( pins[ 8 ].pin_number );
      check_button( 8 );
      break;
#endif

#if MAX_PINS > 9
    case BTN_9:  // Вкл/выкл LED9 (без ШИМ)
      PRINT_DEBUG("Button 9: toggle pin: ");
      PRINTLN_DEBUG( pins[ 9 ].pin_number );
      check_button( 9 );
      break;
#endif

    /* Эти кнопки не обрабатываются, можно их совсем отсюда убрать, но пока оставляем так */
    case BTN_UP:
    case BTN_DOWN:
    case BTN_LEFT:
    case BTN_RIGHT:
    case BTN_POWER:
    case BTN_STOP:
    case BTN_EQ:
    case BTN_REPT:
    default: 
      PRINT_DEBUG("Button ignored, code: ");
      PRINTLNHEX_DEBUG(l_value); 
      break;

    case BTN_VOL_UP:
      PRINTLN_DEBUG("Volume Up");
      brightness_control_up( g_index );
      break;
    case BTN_VOL_DOWN:
      PRINTLN_DEBUG("Volume Donw");
      brightness_control_down( g_index );
      break;
    }
  } 
}

/////////////////////Секция функций/////////////////////////////////

/*
 * Функция обрабатывает кнопки, как PWM, так и обычные
 */
void check_button( int8_t index )
{
  if( index >= 0 )
  {
    if( pins[ index ].isPWMEnabled() )
    {
      /* Сохраняем индекс нажатой кнопки только PWM LEDов */
      g_index = index;
    }
    /*
     * Если пин выключен, включаем его на сохраненной яркости
     */
    if( pins[ index ].isOff() )
    {
      /* Устанавливаем признак включения LED */
      pins[ index ].LEDOn();
    }
    /*
     * Если пин включен, выключаем его
     */
    else
    {
      /* Выключаем пин */
      pins[ index ].LEDOff();
      /* Сбрасываем индекс последней нажатой кнопки */
      g_index = -1;
    }
  }
}

/*
 * Увеличение яркости для пина с индексом index
 */
void brightness_control_up( int8_t index )
{
  if( index >= 0 )
  {
    /* Увеличиваем яркость на определенный шаг и выводим на LED */
    pins[ index ].addBright( BRIGHT_STEP );
  }
}

void brightness_control_down( int8_t index )
{
  if( index >= 0 )
  {
    /* Уменьшаем яркость на определенный шаг и выводим на LED */
    pins[ index ].subBright( BRIGHT_STEP );
  }
}




 

kiril22
Offline
Зарегистрирован: 06.11.2013

triada13 пишет:

kiril22? обратитесь к уважаемому камраду kisoft, он перелопатил библиотеку IRremote, под atmega16, и теперь мой скетч занимает всего 8 с небольшим килобайт, а в нем задействовано 11 кнопок.

Спасибо! Попробую покопаться в вопросе оптимизации библиотек под конкретные задачи.

Lipt0n
Offline
Зарегистрирован: 04.11.2013

Я тут вчера тоже задумался над построением пульта. В интернете все примеры на TSOP22. А можно ли сделать это на ИК фототранзисторе(тот который в мышках)? Всеравно сигнал цифровой.

А если попробовать так? -

(по сути это некое подобие осцилографа)

//запись пока нажата кнопка
while(digitalRead(StartButton)==1){
array[i]=digitalRead(2);
time[i]=milis();
i++;
delay(10);
}

....

//вывод массивов
for(int k=0;k<i;i++)
{
Serial.Println(array[k]+':'+time[k]);
}

На выходе мы получим массив данных из которых можно построить график на компьютере с шагом 10 милисекунд. А затем можно выяснить какой длительности сигналы и просто эмулировать их и переслать на ИК светодиод.

*Хотел попробовать, но никак не могу найти фототранзистор, а разбирать мышь основываясь только на своей теории как-то нехочется.

kiril22
Offline
Зарегистрирован: 06.11.2013

Думаю, так работать не должно.

Вот  здесь можно почитать про ИК приемники

http://www.myrobot.ru/wiki/index.php?n=Components.TSOP

Lipt0n
Offline
Зарегистрирован: 04.11.2013

kiril22 пишет:

Думаю, так работать не должно.

Вот  здесь можно почитать про ИК приемники

http://www.myrobot.ru/wiki/index.php?n=Components.TSOP

Спасибо, интересная статья.

Всё отличие между транзистором и датчиком которую я увидел - это фильтрация сигналов, отличных от " 36, 38, 40 кГц". Я так понял - если датчик ловит "пачку" с кол-вом испульсов от 15 до 50 - он устанавливает соответствующее напряжение на Vo , а дальше всю работу делает софт - кодирует и декуодирует значения в более читабельные пакеты. 

По моему предположению (если частоты считывания хватит), ардвинка должна ловить именно те самые пачки - то есть самый низкий уровень(физический уровень). А закодировать их через функцию не составит труда - Например массив для включения телевизора будет выглядеть так:

int TVOn[]={27,15,27,27,27};  - где элементы массива представляют колличство импульсов на частоте приемника

27 - некое значение представляющее собой логическую единицу.

15 - логический ноль.

Через вывод каждого элемента вводится задержка равная времени между пачками.

Итого на выходе мы получим значение 10111.

Так что по моему мнению все упирается только в частоту считывания сигнала.

kiril22
Offline
Зарегистрирован: 06.11.2013

Вот немного оптимизировал свой код, добавил комментарии для начинающих. Проверил на atmega8, прекрасно работает. Всем спасибо за участие и помощь!

/*
Скетч для включения/выключения одной нагрузки ИК пультом одной кнопкой.
Размер скетча 6 824 байта, что позволяет использовать  его с Atmega8
*/

#include <IRremote.h> // подключаем библиотеку IR remote https://github.com/shirriff/Arduino-IRremote

int RECV_PIN = 11; // к 11 пину подключаем выход фотоприемника
int LED_PIN = 13; // к 13 пину подключаем нагрузку (светодиод, реле и т.д.)
IRrecv irrecv(RECV_PIN);
decode_results results;
int power=0; // вводим переменную состояния включения, присваиваем значение "0"

void setup()
{
  irrecv.enableIRIn(); // включаем приемник
  pinMode(LED_PIN, OUTPUT);
}

void loop() 

{
  if (irrecv.decode(&results)) {
    if (results.value==0xFFB24D) {// если декодированный сигнал равен нужному, в данном случае 0xFFB24D 
                                  //(соответствующая кнопка на пульте), 
      power=!power;               // то меняем переменную состояния включения на протовоположное значение 
      digitalWrite(LED_PIN, power);// записываем это значение в LED_PIN (нагрузка)
    }

    irrecv.resume(); // конец 
  }
}

 

kazakoff
Offline
Зарегистрирован: 07.06.2013

Жирно конечно, на чистом Си у меня заняло 1350 байт.

kiril22
Offline
Зарегистрирован: 06.11.2013

Полностью согласен, что жирно. Однако, считаю это адекватной платой за удобство и низкий порог вхождения в программирование микроконтроллеров (в плане знаний). Где мне такой подход мешает, я начинаю применять "чистый Си". Жаль, что время на его изучение и практическое применение у меня сильно ограничено.

kazakoff
Offline
Зарегистрирован: 07.06.2013

Поддержу пожалуй тему

Вот что мне удалось сделать на Atmega8 и Arduino

Это запись в память одной кнопик пульта в память и с дальнейшим управлением.

#include <IRremote.h>
#include <EEPROM.h>

#define BUTTON 12

int RECV_PIN = 11;
int a=0;
int val = 0;
int state = 0;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;

void setup(){
  
  irrecv.enableIRIn();
  DDRB = 0b00100100;
  
}


void loop() {
   
  val = digitalRead(BUTTON);
  delay(100);
  if (val == HIGH) {
    state = 1 - state;
  }
 
 
  if (state == 1) {     
  
      for (int i = 0; i < 512; i++)
      EEPROM.write(i, 0);
      
        PORTB |= _BV(PC5);
      
      if (irrecv.decode(&results)) {
        
        EEPROM.write(0, results.value);
        irrecv.resume();
        
        if (results.value != ' '){
          
          PORTB &= ~_BV(PC5);
          
          state = 0;
      
        }
      }
      
     

  } else {
    
    uint8_t counter;
    
    counter = EEPROM.read(0);
    
    if (irrecv.decode(&results)) {
      
      uint8_t (results.value);  
      delay(300);
      
      if (uint8_t(results.value) == counter) {
        
        //PORTB |= _BV(PC2);
        //delay(4000);
        //PORTB &= ~_BV(PC2);
        
        if (uint8_t(results.value) == counter) {a=a+1;}
        if (a==1){PORTB |= _BV(PC2);} else {PORTB &= ~_BV(PC2); a=0;}

    }
    
         
      {
        delay(50);
      }
    
      irrecv.resume();
    
    }
  }
}

 

kazakoff
Offline
Зарегистрирован: 07.06.2013

Кстати сейчас вполне недорогие Atmega168 ссыль

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

немного дороже 328 можно взять

http://www.aliexpress.com/item/10pcs-lot-Free-Shipping-ATmega328P-AU-ATM...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
//----------------------------------------------------------------------------------------------------------------------
// TinyPCRemote 
// By Nathan Chantrell nathan.chantrell.net
// Receives infra red codes and emulates a USB keyboard for remote control
//
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// creativecommons.org/licenses/by-sa/3.0/
//----------------------------------------------------------------------------------------------------------------------
//#define F_CPU 9600000

#define IRpin_PIN      PINB
#define IRpin          0

#define MAXPULSE 5000 // max IR pulse length, default 5 milliseconds
#define NUMPULSES 100 // max IR pulse pairs to sample
#define RESOLUTION 1 // time between IR measurements

uint16_t pulses[NUMPULSES][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing
#define led 1

void setup() {
  pinMode(0, INPUT); // Make sure IR pin is set as inpu
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH); 
  delay(1000);
  digitalWrite(led, LOW);
}

void loop() {

  unsigned long irCode=listenForIR(); // Wait for an IR Code

  // Process the pulses to get our code
  for (int i = 0; i < 32; i++) {
    irCode=irCode<<1;
    if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
      irCode|=0; 
    } 
    else {
      irCode|=1;
    }
  }

  // ---------------------------------------------------------------------------------------
  // Enter IR codes and keystrokes to send below, see keyboard_commands.txt for list of keys
  // ---------------------------------------------------------------------------------------

  if (irCode==3305615295) {        // String example with trailing space, "hello "
    digitalWrite(led, HIGH); 
  } 
  else if (irCode==3317670975) {        // String example with enter, "world <enter>"
    digitalWrite(led, LOW); 
  }

} // loop end

// IR receive code
int listenForIR() {  
  currentpulse = 0;
  while (1) {
    unsigned int highpulse, lowpulse;  // temporary storage timing
    highpulse = lowpulse = 0; // start out with no pulse length 

    while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
      highpulse++; 
      delayMicroseconds(RESOLUTION);
      if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse; 
      }
    }
    pulses[currentpulse][0] = highpulse;

    while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
      lowpulse++; 
      delayMicroseconds(RESOLUTION);
      if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse; 
      }
    }
    pulses[currentpulse][1] = lowpulse;
    currentpulse++;
  }
}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Только на тини13 почему-то не канает, код кнопки походу другой нежели как на ардуино.
Может когда-то будет желание то разберусь с этим...
 

axill
Offline
Зарегистрирован: 05.09.2011

поддержу тему. сделал управление открытием/закрытием экрана для домашнего кинотеатра с проектором на атмега8

пока только управление с пульта

хочу сделать еще "автоматически" пульт, который бедет слать коды IR при включении проектора автоматически. Хочу тоже сделать на мега8, но вот IRremote принципиально не компилируется для атмега8

знает ли кто решение?

axill
Offline
Зарегистрирован: 05.09.2011

все получилось, пролистал исходники библиотеки и обнаружил, что для мега8 надо использовать 9-й пин вместо 3-го