Включите и выключите инфракрасный светодиод, чтобы имитировать инфракрасный сигнал

Примечание. Я могу отправлять и получать ИК-сигналы. Этот вопрос предназначен только для обучения.

При использовании существующей библиотеки #include <IRremote.h> очень просто считывать и передавать инфракрасные сигналы. Однако я хотел бы сам отправлять сигналы с помощью digitalWrite(pin, HIGH);

1) Получите инфракрасный сигнал от пульта дистанционного управления, чтобы клонировать его и отправить позже с помощью Arduino.

Для этого я купил инфракрасный светодиод.

Я подключаю левую ногу ИК-светодиода к контакту 11, среднюю ногу к земле и правую ногу к 5 вольтам.

Затем я загружаю в arduino следующий скетч:

#include <IRremote.h>

int receiverpin = 11; // к этому контакту подключена левая ножка ИК-приемника

IRrecv irrecv(receiverpin);
decode_results results;


void setup() {
  pinMode(receiverpin, INPUT);
  Serial.begin(9600);
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results))
  {
    Serial.println(results.value, HEX);
    irrecv.resume();
    delay(150);
  }
}

Когда я запускаю это и нажимаю кнопку питания на моем пульте дистанционного управления Samsung, это то, что я фиксирую через последовательный порт:

Encoding  : SAMSUNG
Code      : E0E040BF (32 bits)
Timing[67]: 
 +4500, -4500     + 550, -1650     + 550, -1700     + 550, -1700
 + 550, - 600     + 500, - 550     + 550, - 550     + 550, - 600
 + 550, - 550     + 550, -1700     + 550, -1650     + 550, -1700
 + 550, - 550     + 550, - 550     + 550, - 600     + 550, - 550
 + 550, - 550     + 550, - 600     + 550, -1650     + 550, - 600
 + 550, - 550     + 550, - 550     + 550, - 550     + 550, - 600
 + 550, - 550     + 550, -1700     + 550, - 550     + 550, -1700
 + 500, -1700     + 550, -1700     + 550, -1650     + 550, -1750
 + 500, -1650     + 550
unsigned int  rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550};  // САМСУНГ E0E040BF
unsigned int  data = 0xE0E040BF;

Что это должно означать. Как я могу преобразовать это в 0 и 1?

2) Отправка клонированного сигнала от arduino.

Теперь, если я хочу включить телевизор с помощью Arduino, мне понадобится инфракрасный светодиод. Я подключу контакт 3 к длинной ножке моего светодиода и заземлю к короткой ножке. Как только я выйду из этого соединения, я запущу этот скетч:

#include <IRremote.h>

IRsend irsend;

void setup() {}

void loop() {

  irsend.sendSAMSUNG(0xE0E040BF, 32); //Код питания
  delay(1000); // повторить попытку через 1 секунду

}

Обратите внимание, что этот код работает, и мой телевизор включается с моим Arduino!

3) Теперь мой вопрос

Читать и передавать инфракрасные сигналы с помощью заголовка IRremote.h было очень просто. часть 2. Из чтения в Интернете я выяснил, что отправка ИК-сигнала — это просто включение и выключение ИК-светодиода очень быстро (38 кГц). Как мне перевести то, что я прочитал:

 rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550}; 

В 0 и 1, а затем отправьте это жестко закодированное для целей обучения.

По этой ссылке: http://www.remotecentral.com/cgi-bin/codes /samsung/tv_functions/

Инфракрасный код для включения телевизора Samsung:

0000 006d 0022 0003 00a9 00a8 0015 003f 0015 003f 0015 003f 0015 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 003f 0015 003f 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 0015 0015 0015 003f 
0015 003f 0015 003f 0015 003f 0015 003f 0015 003f 0015 0702 00a9 00a8 0015 
0015 0015 0e6e

Я преобразовал это в двоичный файл, и получилось:

000000000000000000000000011011010000000000100010000000000000001100000000101010010000000010101000000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000010000000000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000011100000010000000001010100100000000101010000000000000010101000000000001010100000000000101010000111001101110

Теперь каждый раз, когда я вижу 0, я отключаю светодиод, и каждый раз, когда я вижу 1, я включаю светодиод, ожидая около 10 микросекунд, чтобы иметь частоту 38 кГц Это как выглядит мой скетч:

int pinSend=3;
char data[1248] = "000000000000000000000000011011010000000000100010000000000000001100000000101010010000000010101000000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000010000000000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000011100000010000000001010100100000000101010000000000000010101000000000001010100000000000101010000111001101110"; 
int waitTimeInMicroseconds = 5; // счетчик, чтобы попробовать с разным временем ожидания, чтобы увидеть, какая частота работает лучше всего

void setup() {
  Serial.begin(9600);
  pinMode(pinSend,OUTPUT);
}

void loop() {

  Serial.print("Starting sending IR signal waiting ");
  Serial.print(waitTimeInMicroseconds);
  Serial.println(" microseconds");


  int len = sizeof(data);

  for(int i=0; i<len; i++)
  {
    if( data[i] == '0') // если 0 выключаем светодиод
    {
      digitalWrite(pinSend,LOW);
    }
    else // иначе включить светодиод
    {
      digitalWrite(pinSend,HIGH);
    }

    delayMicroseconds(waitTimeInMicroseconds); // ожидание в микросекундах
  }

  Serial.println("Done! Is TV on??????");
  delay(1000); // ждем 1 секунду до следующей попытки

  waitTimeInMicroseconds++; // в следующий раз попробуйте с другим временем ожидания

}

Когда я запускаю этот код, почему телевизор не включается? Как я могу жестко закодировать 0 и 1 в целях обучения?

, 👍0

Обсуждение

Честно говоря, я почти всегда захожу в Интернет, чтобы найти точные коды для различных пультов дистанционного управления и устройств, которые у меня есть. Получение приблизительного кода — это нормально. Но если это граничит с правдой — кто знает — возможно, это создаст моменты, когда Ardunio будет работать не так хорошо, как оригинальный пульт дистанционного управления., @st2000

Встроенная задержка в вашем коде ожидает 150 мс на каждой итерации. Но вы также выполняете код, который требует своего времени. Ошибка будет накапливаться со временем. Любая попытка воссоздать сигнал тем более неверна, чем длиннее сигнал. Было бы лучше выполнить выборку на основе прерывания аппаратного таймера., @st2000

Приемник — это больше, чем просто фотодиод. Приемник демодулирует сигнал 38 кГц. Чтобы воссоздать сигнал, вам нужно включать и выключать ИК-светодиод на частоте 38 кГц, а также включать и выключать этот сигнал, используя шаблон, который вы записали на выходе приемника., @st2000

Чтобы воссоздать сигнал 38 кГц, вам нужно будет завершить цикл вашего кода каждые 13,158 мкс. Это должно включать время, необходимое для выполнения кода. Скорее всего настоящий водитель этим не заморачивается. Вместо этого код может настроить оборудование ШИМ для непрерывной генерации 38 кГц. Тогда код будет выполнять только модуляцию кода 38 кГц., @st2000

Рад, что наткнулся на ваш пост. Вы можете мне помочь: как шестнадцатеричные «данные» (0xE0E040BF) соответствуют «rawData»? Является ли необработанное время данных высоким и низким? вернее разница? У вас есть способ преобразовать hex в rawData? Спасибо, @Pixelowsky

@Pixelowsky, не задавайте вопросов в комментариях. Вы не получите ответов. [Задайте новый вопрос](https://arduinoprosto.ru/q/ask)., @StarCat


1 ответ


Лучший ответ:

0

Наконец удалось разобраться без использования какой-либо библиотеки. Вот как я включаю телевизор:

int pinSend=3;
int waitTimeInMicroseconds = 33; // счетчик, чтобы попробовать с разным временем ожидания, чтобы увидеть, какая частота работает лучше всего
unsigned int  rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550};

int isOn =1;


void setup() {
     Serial.begin(9600);
     pinMode(pinSend,OUTPUT);
}

void loop() {

    Serial.print("starting with ");
    Serial.println(waitTimeInMicroseconds);


    for(int jj=0; jj<16; jj++)
    {
    for(int i=0; i<67; i++)
    {
        if(isOn==0)    {
          isOn=1;

          int x=0;

          while(true)
          {
            digitalWrite(pinSend,HIGH);
            delayMicroseconds(waitTimeInMicroseconds); // ожидание в микросекундах
            digitalWrite(pinSend,LOW);
            delayMicroseconds(waitTimeInMicroseconds); // ожидание в микросекундах

            x=x+waitTimeInMicroseconds+waitTimeInMicroseconds;

            if(x > rawData[i])
            {
              break;
            }
          }

        }
        else{
          isOn=0;
          delayMicroseconds(rawData[i]);
        }

    }
    }

    delay(2500);
    //waitTimeInMicroseconds++;

}
,