Transcodificador IR no Arduino

Os dispositivos controlados por um controle remoto infravermelho estão intimamente integrados em nossas vidas. Às vezes, o controle remoto da TV ou de um sistema de áudio antigo é perdido e já é impossível comprar um novo a partir da velhice. Nem sempre é possível solicitar um novo controle remoto, fazer um clone também, mas com um doador ou informações sobre ele, você pode fazer um conversor. Esse transcodificador receberá comandos de um console e os converterá no formato de outro.

Para o Arduino, existe uma maravilhosa biblioteca IRemote , que facilita a construção de uma variedade de sistemas de controle de IR. Mas, ao resolver uma tarefa tão simples como um transcodificador, sempre há problemas interessantes para resolver.
Portanto, para iniciantes, precisamos de um receptor de IR integrado como o TSOP312 ou o escudo correspondente para o Arduino. Não esqueça que existem muitos receptores de infravermelho e a pinagem deles varia aleatoriamente. Por exemplo, usei um certo elemento sem nome correspondente ao TSOP382, mas em um caso reduzido e sem uma chave de divisão.

Precisamos do circuito montado para receber códigos de comando de ambos os consoles, infelizmente a remoção de comandos de um dispositivo para o qual o console foi perdido é um pouco mais complicada. Ainda é possível encontrar o controle remoto do doador, use o controle remoto universal para selecionar um código (por que você precisa de um transcodificador, pois o controle remoto foi ativado?) Ou tente usar dados de bancos de dados da Internet usando códigos de infravermelho. A coisa mais fácil para mim foi usar um aplicativo para android emulando o controle remoto que eu precisava.
Para ler os dados, usamos o exemplo IRrecvDumpV2 da entrega IRremote, se o seu controle remoto pertencer a uma biblioteca reconhecível, você não precisará de um resultado bruto de varredura, embora, por exemplo, o controle remoto da LG tenha sido falsamente reconhecido como Samsung e não funcionou quando tentei enviar comandos via sendLG.
Um exemplo dos dados obtidos no spoiler:
Encoding: SAMSUNG
Code: 34346897 (32 bits)
Timing[67]:
+4450, -4350 + 600, — 500 + 600, — 500 + 600, -1600
+ 600, -1600 + 600, — 500 + 600, -1600 + 600, — 500
+ 600, — 500 + 600, — 500 + 600, — 500 + 600, -1600
+ 600, -1600 + 600, — 500 + 600, -1600 + 600, — 500
+ 600, — 500 + 600, — 500 + 600, -1600 + 600, -1600
+ 600, — 500 + 600, -1600 + 600, — 500 + 600, — 500
+ 600, — 500 + 550, -1650 + 550, — 550 + 550, — 550
+ 550, -1650 + 550, — 550 + 550, -1650 + 550, -1600
+ 600, -1600 + 600
unsigned int rawData[67] = {4450,4350, 600,500, 600,500, 600,1600, 600,1600, 600,500, 600,1600, 600,500, 600,500, 600,500, 600,500, 600,1600, 600,1600, 600,500, 600,1600, 600,500, 600,500, 600,500, 600,1600, 600,1600, 600,500, 600,1600, 600,500, 600,500, 600,500, 550,1650, 550,550, 550,550, 550,1650, 550,550, 550,1650, 550,1600, 600,1600, 600}; // SAMSUNG 34346897
unsigned int data = 0x34346897;

Se a captura exibir a mensagem “Código IR muito longo. Edite IRremoteInt.h e aumente RAWLEN ”, a biblioteca precisará ser corrigida um pouco - aumentando o tamanho do buffer dos comandos. Para o console que você planeja controlar, basta conhecer o código de comando de 32 bits, vale a pena prestar atenção, pois em alguns controles remotos o código da tecla pressionada difere do mesmo botão no modo pressionado e liberado. Esses botões exigirão dois valores. Reduzimos os códigos recebidos para uma tabela conveniente para você. Na mesma tabela, salvamos os códigos para o controle remoto do doador em formato bruto.
Conectamos um LED infravermelho ao Arduino e escrevemos um programa simples que recebe um sinal infravermelho com um determinado código e envia outro código através do LED. O resistor 82 é selecionado para o que está disponível. Para um dispositivo incorporado, ele pode ser aumentado com segurança para 200 Ohms e, se o transmissor for de longo alcance, você precisará complementá-lo com uma simples cascata de transistor, caso contrário, a corrente do Arduino não será suficiente.

Se houver códigos de comando dos dois controles remotos, o código do transcodificador assumirá a seguinte forma

void loop() {
if (irrecv.decode(&results)) {
    switch(results.value){
      case(0x845E5420):{
	irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
      }break;
    }
  }
  irrecv.resume();
  irrecv.enableIRIn();
}

Começamos o esboço, preenchemos no Arduino. Curiosamente, após o início de um comando, após o qual todos os dispositivos subseqüentes são ignorados. Para não mexer na depuração, adicionamos uma luz intermitente no 13º pino ao ciclo e vemos que após a primeira tentativa de enviar um comando, a placa congela. Bem, isso significa que nem tudo é tão suave no uso simultâneo de transmissão e recebimento de um sinal de infravermelho em um projeto. Depois de vasculhar um pouco os cronômetros usados, verifica-se que, como o envio e o recebimento usam um cronômetro comum, após o início do envio, o código deve esperar até o término do envio. Você pode adicionar empiricamente um atraso de meio segundo (atraso (500)) e tudo funcionará, mas sabendo que os dados brutos em nosso país são amostras de tempo em milissegundos, você pode simplesmente adicionar uma função de atraso. Existe até uma função custom_delay_usec adequada no módulo Irsend,que inicialmente usei incorretamente, esquecendo de multiplicar o atraso pelo fator USECPERTICK da biblioteca (50 ms).

void sendDelayed(unsigned int array[]){
  irsend.sendRaw(array, sizeof(array) / sizeof(array[0]), khz);
    int array_size = sizeof(array) / sizeof(array[0]);
    for(int i=0;i<array_size;i++){
      // Using usec, so multiply raw to usec
      irsend.custom_delay_usec(array[i]*USECPERTICK);
    }
}

Esse código funciona bem. Em troca, basta inserir o número necessário de maiúsculas e minúsculas para os botões e tudo funcionará. Mas não estava lá. Os códigos RawData são escritos como uma matriz int e temos uma plataforma em um microcontrolador. A memória para as variáveis ​​já será consumida por cinco comandos com um comprimento de 100 elementos. Mas no controle remoto existem 25 botões.
Não há problema se você não usar a representação bruta de dados; para isso, a biblioteca pode enviar comandos para protocolos conhecidos, por exemplo, para controles remotos compatíveis com a Sony, é sendSony. A biblioteca já implementou controles remotos de fabricantes conhecidos, mas não consegui lidar com meu controle remoto imediatamente. Portanto, passamos a maneiras mais primitivas de economizar memória que ajudarão aqueles que possuem controles remotos completamente fora do padrão.
A primeira coisa que vem à mente é definir rawData não como int, mas ir para o byte. Todos os valores nessa matriz são o resultado da leitura do sinal IR com um timer com um período de 50 milissegundos e, como esses dados são múltiplos de 50, dividi-los por 50 não perderá nada. O limite superior será limitado a 50 * 255 = 12750, e são 12 segundos, o que será suficiente para decodificar um código Morse de lazer - se essa necessidade surgir.
Um método que aceita bytes para entrada foi adicionado à biblioteca, reduzindo pela metade o consumo de memória

IRsend::sendRaw (byte buf[],  unsigned int len,  unsigned int hz)

Somente o Arduino possui apenas dois kilobytes de memória para variáveis, que são no máximo 40 comandos de 50 bytes cada. Precisamos de mais memória. E extrairemos essa memória do segmento de comando. É suficiente reservar uma matriz de tamanho suficiente e preenchê-la antes de enviar uma série de atribuições. No total, do segmento de código, cerca de 100 bytes serão gastos em um comando, mas temos pelo menos dez kilobytes de espaço de código. Portanto, para o controle remoto médio com cem botões, já temos o suficiente.
Para não encher as atribuições com as mãos, um exemplo IRrecvDumpRawByte foi adicionado à biblioteca que exibe dados brutos não apenas na forma de bytes, mas também na forma de um bloco de atribuição
Exemplo sob o spoiler
rawData[0]=87;rawData[1]=87;rawData[2]=10;rawData[3]=9;rawData[4]=10;rawData[5]=9;rawData[6]=10;rawData[7]=10;rawData[8]=10;rawData[9]=9;rawData[10]=10;rawData[11]=9;rawData[12]=10;rawData[13]=29;rawData[14]=10;rawData[15]=9;rawData[16]=10;rawData[17]=9;rawData[18]=10;rawData[19]=10;rawData[20]=10;rawData[21]=9;rawData[22]=10;rawData[23]=9;rawData[24]=10;rawData[25]=10;rawData[26]=10;rawData[27]=9;rawData[28]=10;rawData[29]=9;rawData[30]=10;rawData[31]=10;rawData[32]=10;rawData[33]=9;rawData[34]=10;rawData[35]=86;rawData[36]=10;rawData[37]=9;rawData[38]=11;rawData[39]=9;rawData[40]=10;rawData[41]=9;rawData[42]=10;rawData[43]=9;rawData[44]=10;rawData[45]=28;rawData[46]=10;rawData[47]=29;rawData[48]=10;rawData[49]=28;rawData[50]=10;rawData[51]=9;rawData[52]=10;rawData[53]=28;rawData[54]=10;rawData[55]=10;rawData[56]=10;rawData[57]=9;rawData[58]=10;rawData[59]=28;rawData[60]=10;rawData[61]=10;rawData[62]=10;rawData[63]=9;rawData[64]=10;rawData[65]=9;rawData[66]=10;rawData[67]=28;rawData[68]=10;rawData[69]=9;rawData[70]=11;rawData[71]=27;rawData[72]=10;rawData[73]=29;rawData[74]=10;rawData[75]=9;rawData[76]=10;

Um exemplo de um esboço já escrito que permite controlar o Samsung DVD HR-755 usando o controle remoto Daewoo R40A01 está nos exemplos sob o nome DaewooR40A01toDVDHR755Transcoder. Ninguém aceitou uma solicitação Pull para adicionar exemplos à ramificação geral, para que você possa baixar a biblioteca modificada da bifurcação .
Muitas fotos com um gravador refeito











Sob o gato, há fotos da integração do Arduino Nano dentro deste gravador de DVD, o Arduino Mini certamente ocupa muito menos espaço, mas apenas o Nano estava à mão. Peguei energia no painel de controle. O sinal do receptor embutido foi conectado ao Arduino e outro receptor infravermelho localizado no lado oposto do primeiro foi soldado a ele em paralelo. Com a mesma instalação montada, um LED IR foi soldado a ele. Em princípio, essa repetição poderia ter sido evitada - mas o sinal do receptor IR é invertido - portanto, não consigo transmitir o sinal TTL diretamente para o dispositivo - e não comecei a disparar o inversor na lógica ou no transistor.

Apesar do fato de que, no meu caso, os dados brutos funcionaram bem, experimentos com o restante do equipamento doméstico mostraram que nem todos os sinais capturados funcionavam corretamente ao tentar controlar um dispositivo específico. O comando para ligar o ar condicionado não funcionou, embora, se já estivesse ligado, a mudança de modos funcionou corretamente. A coluna da LG também se recusou a aceitar comandos brutos, mas respondeu bem ao envio de códigos via sendSamsung. Ao mesmo tempo, cinco TVs coletadas de conhecidos reagiram muito bem aos dados brutos. Eu tentei a opção com diferentes frequências de sinal - não ajudou. Talvez o problema esteja na taxa de amostragem do sinal em 50 ms. A julgar pela operacionalidade das equipes no formato Samsung usando a tecnologia LG, o protocolo deve ser formalizado como um módulo separado por analogia com ir_LG.cpp ir_JVC.cpp ir_Dish.cpp,selecionando para um dispositivo específico o cabeçalho e os parâmetros de codificação de zeros e uns. Provavelmente, analisar a redação desse protocolo servirá como um bom tópico para o artigo.

Além disso, a segunda grande biblioteca de IR do Arduino é o IRLib . Possui funcionalidade semelhante, e ainda possui um módulo pronto para analisar protocolos de IR para a área de trabalho. Foi realizado um teste comparativo rápido da leitura dos dados brutos, que não revelou diferença nas amostras em comparação ao IRemote. Das vantagens, o IRLib já tem um exemplo de determinação com que frequência o transmissor IR funciona. Exemplo Samsung36 realmente implementa um protocolo de análise de dados da Internet. Além disso, a documentação descreve perfeitamente como conectar receptores de infravermelho com cascata e muito mais. Embora, na minha opinião, o IRemote seja muito mais fácil de entender e usar.

Source: https://habr.com/ru/post/pt391001/


All Articles