Работа с ИК пультом.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Всем привет.

Пытаюсь програмировать прием ИК пачек с пульта ДУ , но появилась проблема.

Вот такой код (для одной кнопки ) работает нормально.

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

Вообще то в пачке 13 импульсов , но мне хватает приема 6.

 

unsigned long val=0;

void setup()

{
  
  pinMode(7,INPUT);//сюда подключен TSOP
   pinMode(13,OUTPUT);
    
  
}
void loop()

{
  val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==2)
  {
    val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==1)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
      val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    { 
   
     
      
      digitalWrite(13,!digitalRead(13));
      delay(200);
      
    
    
      
    
      
    } 
      
    }
      
    }
      
      
    }
      
      
     
    } 
  }
}

 

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

(просто размножив блоки кода и вставив соответствующие длины импульсов)

программа начинает работать некоректно (срабатывает раза с десятого , иногда вообще не срабатывает).

Почему так происходит и что с этим делать ?

Вот вторая программа.

 

unsigned long val=0;

void setup()

{
  
  pinMode(7,INPUT);
   pinMode(13,OUTPUT);
    pinMode(12,OUTPUT);
     pinMode(11,OUTPUT);
     pinMode(10,OUTPUT);
     pinMode(9,OUTPUT);
     pinMode(8,OUTPUT);
  
}
void loop()

{
  val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==2)
  {
    val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==1)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
      val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    { 
   
     
      
      digitalWrite(10,!digitalRead(10));
      delay(200);
      
    
    
      
    
      
    } 
      
    }
      
    }
      
      
    }
      
      
     
    } 
  }
  //*****************************************************8
  
  
  
  
  
   val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==2)
  {
    val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
      val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    { 
   
     
      
      digitalWrite(13,!digitalRead(13));
      delay(200);
      
    
    
      
    
      
    } 
      
    }
      
    }
      
      
    }
      
      
     
    } 
  }
  
  
  
  
  
  
 //*****************************************************8 
  
  
  
  
  
  
   val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==2)
  {
    val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==1)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
      val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    { 
   
     
      
      digitalWrite(11,!digitalRead(11));
      delay(200);
      
    
    
      
    
      
    } 
      
    }
      
    }
      
      
    }
      
      
     
    } 
  }
  
  
  //*****************************************************
  
  
  
  
  
  
  
   val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==2)
  {
    val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==1)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==1)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
       val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    {
      
      val=pulseIn(7,LOW);
  val=(val/1000);
  if(val==0)
    { 
   
     
      
      digitalWrite(9,!digitalRead(9));
      delay(200);
      
    
    
      
    
      
    } 
      
    }
      
    }
      
      
    }
      
      
     
    } 
  }
  
  
  //********************************************************
  
  
  
  
  
 
}

 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Думаю дело вот в чем. Допустим ты нажал кнопку чтобы выполнился второй блок программы (который 13-м пином управляет). Пошел первый импульс (который 2000 или больше микродекунд), а перехватил его первый блок, строка 21 условие же верно выполняется, потом пошел второй импульс, строка 25 условие опять верно выполняется, третий импульс не прокатывает, программа перестает делать дальнейшую проверку и нужная комбинация импульсов не отработала. Дальше если кнопка нажата, пульт ДУ повторно посылает пачку импульсов, опять пошел импульс 2000 микросекунд, а перехватывает его, допустим, третий блок. И так будет до тех пор, пока не произойдет одновременное выполнение программы в строке 77 и приход первого (2000 микросекунд) импульса для второго блока.
 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

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

Попробовал две кнопки - вроде работает. 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Да можно проще сделать. Например вот так:

val=pulseIn(7,LOW);
val=(val/1000);
if(val==2) //пришел первый импульс 2000 мкс
{
val2=pulseIn(7,LOW); // записываем в val2 продолжительность второго импульса
val3=pulseIn(7,LOW); // записываем в val3 продолжительность третьего импульса
val4=pulseIn(7,LOW); // и т.д.
val5=pulseIn(7,LOW);
val6=pulseIn(7,LOW);
// здесь проверяем значения val2 - val6 и выполняем нужные действия
}
 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Не совсем понял. Каким образом проверить заначения  пяти переменных одновременно ? 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Извиняюсь за глупый вопрос.

Вот так действительно лучше . Спасибо.

unsigned long val=0;
unsigned long val2=0;
unsigned long val3=0;
unsigned long val4=0;
unsigned long val5=0;
unsigned long val6=0;

void setup()

{
  
  pinMode(7,INPUT);
   pinMode(13,OUTPUT);
   pinMode(10,OUTPUT);
  
}
void loop()

{
  




val=pulseIn(7,LOW);
 val=(val/1000);
 if(val==2)
 {
 val2=pulseIn(7,LOW); 
 val3=pulseIn(7,LOW); 
 val4=pulseIn(7,LOW); 
 val5=pulseIn(7,LOW);
 val6=pulseIn(7,LOW);
 
 if((val2/1000)==1&&(val3/1000)==0&&(val4/1000)==1&&(val5/1000)==0&&(val6/1000)==1)
 {
  digitalWrite(13,!digitalRead(13));
      delay(200); 
 }
 }
 
 
 
 
 
 
 
 
 
 val=pulseIn(7,LOW);
 val=(val/1000);
 if(val==2)
 {
 val2=pulseIn(7,LOW); 
 val3=pulseIn(7,LOW); 
 val4=pulseIn(7,LOW); 
 val5=pulseIn(7,LOW);
 val6=pulseIn(7,LOW);
 
 if((val2/1000)==1&&(val3/1000)==0&&(val4/1000)==0&&(val5/1000)==0&&(val6/1000)==0)
 {
  digitalWrite(10,!digitalRead(10));
      delay(200); 
 }
 }
 
 
 
 
 
 
 
 
 
 
 
 
 }

 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Нее, опять не правильно, опять два блока. Должен быть один блок. Например так:

...
val2=val2/1000;
val3=val3/1000;
val4=val4/1000; // в переменных val2 - val6 получаем 1 или 0
val5=val5/1000;
val6=val6/1000;
// дальше можно воспользоваться фуцкцией bitWrite()
//объявим переменную z
byte z = 0;
bitWrite(z, 0, val2); //установим нулевой бит переменной z в значение val2 (0 или 1)
bitWrite(z, 1, val3); //установим первый бит переменной z в значение val3 (0 или 1)
bitWrite(z, 2, val4); // и так далее
bitWrite(z, 3, val5);
bitWrite(z, 4, val6);
// теперь переменная z содержит число в зависимости от значений val2 - val6
// т.е. если val2 - val6 были равны еденицам то получам число B11111100 (вроде так) это в двоичном виде, а в десятичном 252
//если же, например, переменная val4 была равна 0 то z будет B1101100 в двоичном виде, а в десятичном 108
//ну а дальше в зависимомти от значения z выполняем нужные действия
}

 

pmaster
Offline
Зарегистрирован: 23.05.2011

 а не проще использовать уже готовое решение? IRemote http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html

 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Вот последний твой вариант программы почти правильно написан. Только после строки 39 надо вставить строки 60 - 64 (код же в переменных сохранен), а то что ниже убрать. И так для каждой кнопки на пульте.

igboris
Offline
Зарегистрирован: 14.04.2011

 Я вот тоже озадачился управлением по ИК. В частности, при достижении в комнате указанной температуры - включать кондиционер.

IRemote - библиотека классная, примеры расписаны хорошо. Но вот как реализовать добавление нового пульта? В библиотеке есть готовые обработчики для брендов Sony, NEC, RC5/6 и собственно всё.

При посылке команды с пульта (кондиционер, не "брендовый" Dantex), соответственно, получаю массив. При попытке отправить его Ардуиной в "кондей" - реакции ноль. При этом музыкальный центр Sony - реагирует на команды Ардуины чётко.

Где "собака порылась"? Никто не пробвал "клонировать" пульт с помощью этой библиотеки?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Клонировать пульт нужно не с помощью библиотеки , а просто читать импульсы и отправлять их в COM .

А потом програмировать МК на прием этих пакетов импульсов.

Я делал так . Все работало. 

igboris
Offline
Зарегистрирован: 14.04.2011

nestandart пишет:

Клонировать пульт нужно не с помощью библиотеки , а просто читать импульсы и отправлять их в COM .

А потом програмировать МК на прием этих пакетов импульсов.

Я делал так . Все работало. 

А можно какой-нибудь пример, в качестве how to? Руководство к действию так сказать?

Mogalkov
Offline
Зарегистрирован: 23.06.2011

 вот пример - хоуту: freeduino.ru/forum/viewtopic.php

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Проще некуда.

Естественно  эти импульсы считываются с TSOPа

unsigned long val=0;

void setup()

{
  
  pinMode(7,INPUT);
   Serial.begin(9600);
}
void loop()

{
  val=pulseIn(7,LOW);
  val=(val/1000);





  
  Serial.print(val);
}

 

igboris
Offline
Зарегистрирован: 14.04.2011

 Получается, что на выходе в serial (в переменной val) получаем длину импульса?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Да , если импульс один.

Получаем длины импульсов (пачка) , если это заводской пульт.

Аналогично можно мерить расстояние между импульсами. 

Меняем     pulseIn(7, LOW);

на pulseIn(7, HHIGH);