Cómo obtener códigos consistentes desde el módulo receptor de IR TSOP1738

5

Estoy realizando algunos experimentos con un TSOP1738 módulo receptor. Tomé un pequeño 'control remoto' (también conocido como un transmisor de infrarrojos) del sistema de audio de mi auto y estoy intentando enviar un comando a un robot. No tengo idea de qué está utilizando la codificación de este control remoto en particular. Conecté el módulo TSOP a un osciloscopio y descubrí las señales que salían de él. Lo descifre como el siguiente.

  • La ráfaga inicial es de alrededor de 4000 + uS.
  • Logical 1 es para alrededor de 2000 + uS
  • El 0 lógico es para alrededor de 600 + uS

A partir de esta información, decodifiqué los comandos enviados por el control remoto y me pareció bastante razonable. Conecté el módulo TSOP a un Arduino y utilicé un poco de trabajo bit a bit en los datos provenientes del módulo receptor IR. Últimamente descubrí que todos los primeros 16 bits provenientes de ella eran exactamente iguales para todos los botones que presiono en el control remoto. Así que lo quité y usé los últimos 16 bits para hacer un valor clave unsigned int para cada botón del control remoto. Lo encontré funcionando como se esperaba. ¡Pero el problema que enfrento ahora es que obtengo diferentes valores clave para la misma presión de botón! Es decir, si presiono el botón de encendido en el control remoto dos veces, ambas prensas me dan datos diferentes. ¿Cómo puedo hacer esto consistente? ¿Es este un tipo de ruido que causa el problema?

Aquí está el bosquejo arduino que uso.

int irPin = 2;          //Sensor pin 1 wired to Arduino's pin 2
int statLED = 13;       //Toggle the status LED every time Power is pressed
int start_bit = 2200;   //Start bit threshold (Microseconds)
int bin_1 = 2000;       //Binary 1 threshold (Microseconds)
int bin_0 = 600;        //Binary 0 threshold (Microseconds)

void setup() {
    pinMode(statLED, OUTPUT);
    digitalWrite(statLED, LOW);
    pinMode(irPin, INPUT);
    Serial.begin(9600);
    Serial.println("Waiting: ");
}

void loop() {
    unsigned int key = getIRKey();
    Serial.print(" > ");
    Serial.println(key);
}

int getIRKey() {
    int data[32];
    int i;

    while(pulseIn(irPin, LOW) < start_bit);//Wait for a start bit

    for(i = 0 ; i < 32 ; i++)
        data[i] = pulseIn(irPin, HIGH);    //Start measuring bits, only high    pulses needed.

    int key_data[16];                      //First 16 bits arw the same for all keys.
    for(i = 16 ; i < 32 ; i++)  {          //Parse them
        Serial.print(data[i]);
        Serial.print(" ");
        if(data[i] > bin_1)                //is it a 1?
            key_data[i-16] = 1;
        else if(data[i] > bin_0)           //is it a 0?
            key_data[i-16] = 0;
        else
            return -1;                     //Flag the data as invalid;
    }

    Serial.print(" = ");
    unsigned int result = 0;
    for(i = 0 ; i < 16 ; i++)  {           //Convert key_data bits to integer
        Serial.print(key_data[i]);
        if(key_data[i] == 1)
            result |= (1 << i);
    }
    return result;
}

Y esta es la salida del boceto anterior, cuando presiono el mismo botón en el control remoto un par de veces.

2162 725 682 695 694 694 658 730 652 2094 2165 2167 2171 2164 2167 2128  = 1000000001111111 > 65025
2095 721 658 692 696 627 659 650 650 2090 2053 2173 2139 2093 2098 2129  = 1000000001111111 > 65025
2124 2128 2127 654 619 691 620 654 649 648 610 2131 2132 2131 2127 2091  = 1110000000011111 > 63495
2133 2103 2089 613 610 682 619 654 655 654 617 2127 2124 2124 2137 2132  = 1110000000011111 > 63495
2125 2127 2133 654 619 649 612 645 649 648 619 2136 2133 2123 2094 2124  = 1110000000011111 > 63495
2093 2089 2098 657 655 610 649 612 646 648 654 2098 2098 2093 2089 2090  = 1110000000011111 > 63495
2099 2123 2091 684 655 654 657 621 620 683 612 2124 2128 2136 2133 2091  = 1110000000011111 > 63495
2104 2095 2128 657 649 611 688 627 657 665 658 2056 2094 2060 2169 2132  = 1110000000011111 > 63495
2127 1952 2099 692 620 620 657 648 610 682 611 2098 2132 2136 2127 2125  = 1010000000011111 > 63493
2091 649 648 611 683 621 655 655 621 2090 2090 2094 2102 2099 2102 2090  = 1000000001111111 > 65025
2127 649 620 654 655 657 620 683 612 2125 2090 2135 2135 2123 2091 2125  = 1000000001111111 > 65025
2093 649 655 619 691 620 654 684 646 2091 2090 2102 2098 2125 2094 2091  = 1000000001111111 > 65025
2098 655 648 612 682 611 646 658 655 2099 2090 2094 2089 2098 2101 2099  = 1000000001111111 > 65025
2161 694 658 691 697 646 612 686 615 2127 2133 2136 2124 2125 2131 2135  = 1000000001111111 > 65025
2101 2167 2090 683 646 623 655 621 694 691 648 2166 2094 2064 2173 2161  = 1110000000011111 > 63495
2090 2097 2128 658 695 655 658 688 684 615 649 2095 2099 2101 2095 2090  = 1110000000011111 > 63495
2162 729 661 623 697 617 649 722 650 2095 2173 2066 2164 2059 2131 2170  = 1000000001111111 > 65025
    
pregunta Subin Sebastian

1 respuesta

2

En mi experiencia al decodificar señales IR, casi siempre es mejor ser muy pedante con respecto a los tiempos de las señales. Por ejemplo, solo acumular los ALTOS tiempos en una matriz funcionará la mayor parte del tiempo, pero no podrá hacer frente a la ráfaga de ruido ocasional. Debe validar cada período ALTO y BAJO.

Como otro ejemplo de la necesidad de tener cuidado con los tiempos, para la señal de "inicio", solo se detecta que el período LOW inicial (es decir, la ráfaga IR de 38 kHz) es más largo que el mínimo (2200) ... pero que Si es mucho más largo debido a una explosión de ruido? ¿Y qué pasa si el tiempo completo inmediatamente después de eso es demasiado largo o demasiado corto? Se disparará de forma falsa y luego continuará intentando dar sentido a la posible señal de ruido que sigue y obtener un resultado poco confiable.

Lo que sugeriría es que utilice su alcance y las cifras de tiempo para tener una idea de los tiempos correctos (que ha hecho en gran parte), y escriba su código para detectar si cada bit individual es válido (es decir, ambos BAJO y los tiempos ALTOS están dentro de la tolerancia) y, si se encuentra un bit no válido, ignore todas las transiciones posteriores, por ejemplo, 100 ms antes de volver a escuchar una secuencia de "inicio". El objetivo es nunca intentar procesar un comando a menos que se sepa que se haya analizado por completo.

También (probablemente menos importantes) los 16 bits que parecen ser siempre los mismos pueden no ser siempre así. Es posible que no hayas visto los casos en que son significativos. Tal vez sean para una dirección de dispositivo y / o banderas (como "tecla presionada y mantenida"). En algunos protocolos, la secuencia de la señal cambia significativamente cuando se presiona y mantiene presionada una tecla remota, y otros alternan un poco en el campo "comando" a medida que se emite cada comando.

Creo que una buena manera de analizar rigurosamente una señal IR es usar una máquina de estados finitos (FSM). Para ver un ejemplo, puede ver mi proyecto de código abierto en enlace ... no es para arduino, pero debería ser útil sin embargo.

    
respondido por el aja

Lea otras preguntas en las etiquetas