"Novo" código para processamento de sinal infra-vermelho

Olá a todos,


Antes de chegar ao conteúdo de fato, preciso fazer uma breve apresentação para que todos entendam o contexto do meu código: sou professor de Matemática e estou oferecendo em um colégio de Ensino Médio aulas semanais de "introdução à linguagem C e Arduino". Tenho um público relativamente fixo de cerca de 15 alunos. Fiquei umas 6 semanas discutindo C com eles, visando dar ferramental básico  e faz umas 4 semanas que comecei com Arduino de fato.

Semana que vem vamos ao Lab de Garagem físico para eles comprarem suas peças e começarem a desenvolver seus próprios projetos (que serão apresentados na feira de ciências do colégio no final do ano).

Duas semana trás mostrei como usar infra-vermelho com a bibloteca IRremote.h, como sugerido no tutorial daqui mesmo.

Acontece que não estava satisfeito com ele, pois a biblioteca tem um funcionamento meio obscuro a té complexo pra quem não está acostumado com programação.

Depois de um pouco mais de pesquisa, descobri o comando pulseIN (pois é, eu não conhecia ainda) e com ele escrevi o código abaixo.

// código para leitura de sinal infravermelho sem biblioteca

//usando apenas pulseIn

//autor: Leonardo Barichello

//pino com o sensor
#define sensor 12

void setup() {
  //pino do sensor IR
  pinMode(sensor, INPUT);
  //monitor serial
  Serial.begin(9600);
}

void loop() {
  unsigned int duracao, menor;
  unsigned int sinal[32]; //tamanho arbitrário que parece ser suficiente
  int sinalbits[256]; //tamanho arbitrário que parece ser suficiente
  int j,i,pos,v,t1,t2;
 
  v=1; //variável para alternar entre leitura de sinal HIGH e LOW
  duracao = pulseIn(sensor, v, 100000);
 
  if(duracao!=0) {
    
    //zerando vetor de duracoes
    for(i=0;i<32;i=i+1) {
      sinal[i]=0;
    }
    
    //zerando vetor de bits
    for(i=0;i<32;i=i+1) {
      sinalbits[i]=0;
    }
    
    i=0;
    sinal[i]=duracao; //guardando a primeira duração já lida
    
    //lendo sinal
    while (duracao!=0) {
      v=(v+1)%2;
      duracao = pulseIn(sensor, v, 100000);
      i=i+1;
      sinal[i] = duracao;
    }
    
    t1=i; //comprimento real do vetor de durações

    //mostrando o vetor de duracoes
    Serial.print("Vetor de duracoes: ");
    for(i=0;i<t1;i=i+1) {
      Serial.print(sinal[i]);
      Serial.print(", ");
    }
    Serial.println(".");
    
    //achando o menor pulso
    Serial.print("Duracao do menor pulso: ");
    menor=100000;
    for(i=0;i<t1;i=i+1) {
      if ( (sinal[i]<menor) && (sinal[i]!=0) ) {
        menor = sinal[i];
      }
    }
    Serial.println(menor);
    
    //transformando o vetor de duracao em microseg para numero de intervalos
    for(i=0;i<t1;i=i+1) {
      sinal[i] = round(sinal[i]/menor);
    }

    //mostrando o vetor de duracoes convertido
    Serial.print("Vetor de duracoes em pulsos: ");
    for(i=0;i<t1;i=i+1) {
      Serial.print(sinal[i]);
      Serial.print(", ");
    }
   Serial.println(".");

    //gerando vetor de bits
    v = 1;
    pos = 0;
    for(i=0;i<32;i=i+1) {
      for(j=0;j<sinal[i];j=j+1) {
        sinalbits[pos]=v;
        pos=pos+1;
      }
      v=(v+1)%2;
    }
    
    t2=pos; //tamanho real do vetor de bits
    
    //mostrando o vetor de bits
    Serial.print("Vetor de bits: ");
    for(j=0;j<t2;j=j+1) {
      Serial.print(sinalbits[j]);
    }
    Serial.println(".");
    
  }
 
}

Esse código lê uma sequência de variações em pulsos de infravermelho. Depois, detecta a duração do menor pulso e (considerando que ele seja a "unidade básica de tempo") converte o vetor de durações em microssegundos em um vetor de durações em unidades inteiras. Por fim, com esse vetor "normalizado", ele gera um novo vetor de bits que reflete o estado HIGH e LOW do receptor por unidade de tempo.

Apesar da programação adicional necessária, achei esse código muito mais compreensível, mas gostaria de saber a opinião de mais pessoas pra saber se fiz algo errado, por exemplo.

O ideal seria testar com um outro arduino emitindo o pulso, mas ainda não tenho acesso a outra placa para isso.

Vantagens nesse código que eu detectei:

- a biblioteca IRremote.h vira e mexe interpretava o sinal de um mesmo botão de duas maneiras diferentes. Achei que fosse algum problema esporádico com o meu controle de TV, mas o código acima sempre interpreta do mesmo jeito

- a biblioteca não detecta o sinal do meu controle de DVD, por exemplo,e  o código acima detecta de tudo que testei até agora

Uma desvantagem:

- por detectar tudo, ela detecta demais e dependendo do lugar em que você está a entrada fica poluída demais

Uma característica:

- como ela não interpreta sabendo o padrão de comunicação dos dispositivos, ela dá o sinal completo, o que às vezes é até meio sujo, com sequencias longas de 1's ou 0's que a biblioteca IRremmte limpa por saber que o sinal será assim. Apesar de ter uma leitura mais limpa ser bom no geral, saber exatamente o que o dispositivo está mandando pode ser bem útil.

Bem, pessoal, era isso.

Se vocês puderam dar a opinião sobre o código ou até mesmo fazer algum teste, ficarei muito grato!

Obrigado

Exibições: 721

Responder esta

Respostas a este tópico

Leonardo. Primeiramente parabens pelo esforço de complementar o conhecimento de seus alunos com este nível de trabalho (levando a eles gratuitamente, pelo que entendi, conhecimento que vale; e muito). Eu não tenho como testar o código que vc. postou, mas pretendo quando for fazer testes com infravermelho usa-lo para testes. Creio não ser muito difícil entender os protocolos de infravermelho e implementar sobre este código os controles necessários para "limpar o lixo" que por ventura ele esteja recebendo. Eu sempre prefiro ter acesso ao nível mínimo de controle sobre cada detalhe e nisso este esforço seu parece-me ter sido muito bem feito. Continue a "exponenciar" desta forma e serás inesquecível para as jovens mentes que estão a seus cuidados. Abracadabra"sô"!!!

Euclides, obrigado pela força!

E se fizer algum teste, por favor, mande aqui pra mim.

Assim que meus alunos tiverem alguns arduinos, pretendo escrever um código similar para emissão de sinal seguindo esse padrão que usei. Também postarei aqui assim que tiver algo.

Até mais!

Leonadro, Parabens pelo seu programa e por sua iniciativa.

Baseado em seu programa para identificar os codigos de varios tipos de controle, gostaria de saber se vc conseguiu realizar a transmissao desses dados?!.

 

Obrigado ate o momento.

Leandro, bem lembrado de retornar a este tópico.

Leonardo, se ainda não conseguiu solução para este problema, responda. Achei uma solução de "cópia" de sinal IR na internet e se precisar coloco aqui (não coloquei porque estou correndo de saída, e não dará tempo de procurar agora).

Até breve.

Euclides, realmente ainda nao achei nada funcional, se poder dar uma força agradeço.

 

Att,

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço