Browse Month: Mai 2022

IR Empfänger

Infrarote Strahlung lassen sich mittels IR-sensitiver Fotodioden detektieren. Diese Dioden sehen im wesentlichen aus wie schwarze LED´s. Mit solchen Fotodioden fängt man jedoch die gesamte IR Strahlung ein, egal ob gepulst oder ungepulst. Wenn man nur die gepulste Strahlung einer Fernsteuerung verarbeiten möchte, gibt es spezielle Dioden, mit einem komplexeren Aufbau:

Auszug aus dem Datenblatt der IR Empfänger Diode OS-1838 IR-Empfänger

Dabei handelt es sich um einen Photodetektor mit Vorverstärker der sich in einem dreipoligen Gehäuse mit IR-Filter integriert ist. Der Baustein besitzt eine hohe Störfestigkeit gegenüber Umgebungslicht, hat einen niedrigen Stromverbrauch und ist TTL- und CMOS-kompatibel.

Dieser Empfänger lässt sich ohne großen Schaltungsaufwand an einen Arduino anschliessen und über eine in der Arduino-Entwicklungsumgebung enthaltene Bibliothek mit dem Namen IRremote.h einfach verwenden. Die entsprechende Schaltung ist ebenfalls im Datenblatt enthalten:

Anschluss des Empfängers an einen Microcontroller

Schliesst man den Empfänger nach dieser Methode an einen Arduino an, kann man mit folgendem kurzen Testprogramm und einer IR-Fernsteuerung aus dem Fundus des Makers schnell testen, welche Signale von der Fernsteuerung ausgesendet werden.

#include <IRremote.h>
int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;
 
void setup() {
    Serial.begin(9600);
    irrecv.enableIRIn(); 
  } // end setup
  
void loop() {
    if (irrecv.decode(&results)) {          // Wenn ein IR-Signal erkannt wurde,
        Serial.println(results.value, HEX); // wird der Wert im seriellen Monitor ausgegeben
        irrecv.resume();
      }
    delay(100);
} // end loop

In meinem Beispiel mit einer alten DVD-Player Fernsteuerung habe ich folgende Ausgabe erhalten:

Wie man erkennt, kommen etwas eigenwillige Werte an. Beim drücken der Taste A kommen immer wieder Werte wie [66593 und 1057] und bei der Taste B [1056 und 66592]. Da stellt man sich die Frage, welche Werte sind nun die richtigen? Da immer wieder die selben Werte kommen, lässt sich damit natürlich schon mittel if oder case Abfrage eine Steuerungslogik entwickeln, dennoch bleibt die Frage bestehen.

#include <IRremote.h>
int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;

int led1 = 11;                                       //Definiere der LEDs
int led2 = 12;                                                         

void setup()
  {
    Serial.begin(9600);
    pinMode (led1, OUTPUT);               //Die LEDs werden als Output initialisiert
    pinMode (led2, OUTPUT);  
    digitalWrite(led1, LOW); 
    digitalWrite(led2, LOW);                       
    irrecv.enableIRIn();
  }

void loop() {
    if (irrecv.decode(&results))            //Wenn ein IR-Signal empfangen wurde,
      {
        Serial.println(results.value);
        
        switch(results.value)  {  //wird überprüft, ob es eine Aktion für die Taste gibt
          
            case (66593) : {                  //Wenn PREV gedrückt wurde,                    
                digitalWrite(led1, HIGH);}   //an        
            break;
            
            case (1068) : {                  //Wenn PAUSE gedrückt wurde,                    
                digitalWrite(led1, LOW);
                digitalWrite(led2, LOW); }           
            break;

            case (1056) : {                  //Wenn NEXT gedrückt wurde,                    
                digitalWrite(led2, HIGH); }  
            break;
            
            delay(10); break;
            
            default: delay(100);             
          } // end switch
          
        irrecv.resume();
      } // end if
  } // end loop

Eine Antwort findet man auf den Seiten von Wolfgang Ewald. Er beschreibt sehr anschaulich, dass Fernsteuerungen gepulste Signale aussenden und wie diese Signale aufgebaut sind.

Auf diesen Seiten erfährt man, dass …

Signale von IR Fernbedienungen sozusagen zweifach gepulst sind. Ein Signal besteht aus einer Folge von Pulsen, wobei jeder Puls eine Breite von mehreren hundert Mikrosekunden bis einigen Millisekunden aufweist. Diese Pulse nenne ich mal Hauptpulse, da mir nichts Besseres einfiel. Das ist also kein Fachbegriff. Zwischen den Hauptpulsen gibt es unterschiedlich lange Pausen. Die Hauptpulse bestehen wiederum aus vielen 38 kHz Pulsen.

Auf der Empfängerseite werden die 38 kHz Pulse demoduliert. Außerdem wird das Signal aufgrund des oben beschriebenen Aufbaus der Empfänger umgekehrt. Das heißt, LOW wird HIGH und umgekehrt.

Bei der Auswertung geht es nun darum die Puls- und „Pausenbreiten“ zu vermessen. Das macht man am besten, indem man zunächst eine geeignete Zeiteinheit (timeSegment) definiert, die die Auflösung darstellt. Im nachfolgenden Sketch prüft der Arduino nach jedem Ablauf einer Zeiteinheit, ob der Datenpin am IR Empfänger HIGH oder LOW ist. Die Zeiteinheiten werden addiert bis ein HIGH/LOW bzw. LOW/HIGH Wechsel stattfindet. So hangelt man sich Stück für Stück durch das Signal.

Ist ein Signal vollständig übertragen, dann wird es auf dem seriellen Monitor einmal übersichtlich paarweise und einmal als Array ausgegeben. Letzteres könnt ihr direkt in den Sendesketch, den wir gleich besprechen, hineinkopieren. Der letzte gemessene Wert entspricht maxCount. Diesen brauchen wir nicht, da er nicht mehr zum Signal gehört. Entsprechend lasse ich ihn in der Array-Ausgabe weg.

Auszug aus dem Text von Wolfgang Ewald

Steuerung eines Motors

Das oben vorgestellte Programm lässt sich leicht erweitern…mittels eines 2N 2905 Schalttransistors kann man höhere Lasten wie beispielsweise einen Elektromotor schalten.

Die Grundschaltungen wie man mittels Arduino und Transistor Lasten ansteuern kann sehen wie folgt aus:

Wenn andere Gehäuseformen der Transistoren verwendet werden, muss im Datenblatt nachgeschaut werden, wo sich die erforderlichen Anschlüsse im jeweiligen Gehäuse befinden. In meinem Beispiel verwende ich einen 2N 2219 in einem TO-39 Gehäuse.

Die Schaltung basiert auf dem Datenblatt der IR Diode, der Kondensator ist als Entkopplungs-Kondensator zu dimensionieren. Im Anschluss das Arduino Programm zum Schalten des Motors:

// Ansteuerung einer IR Diode mittels alter Fernsteuerung
// und schalten eines Motors via Leistungstransistor
// PHOF Mai 2022

#define TRANSISTOR 7
#include <IRremote.h>
int RECV_PIN = 8;
int led1 = 11;                         // Definiere der LEDs
int led2 = 12;     

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
    Serial.begin(9600);
    pinMode (led1, OUTPUT);            // Die PINs werden als Output initialisiert
    pinMode (led2, OUTPUT);  
    pinMode(TRANSISTOR, OUTPUT);
    
    digitalWrite(led1, LOW);          // Ausgänge auf LOW gesetzt
    digitalWrite(led2, LOW); 
    digitalWrite(TRANSISTOR, HIGH);                      
    irrecv.enableIRIn();
   
}
void loop() {
if (irrecv.decode(&results))            //Wenn ein IR-Signal empfangen wurde,
      {
        Serial.println(results.value);  // Signal wird protokolliert über Monitor

        // Signale einer alten Fernsteuerung wurden im Vorfeld ausgelesen
        // PEV Schaltet Motor an  PAUSE aus  NEXT auch aus (für weitere Steuerungen vorgesehen)
        
        switch(results.value)  {         //wird überprüft, ob es eine Aktion für die Taste gibt
          
            case (66593) : {                  //Wenn PREV gedrückt wurde                   
                digitalWrite(led1, HIGH);     // LED 1 an und LED2 aus
                digitalWrite(led2, LOW);
                digitalWrite(TRANSISTOR, HIGH);}   // Motor EIN      
            break;
            
            case (1057) : {                  // Wenn PREV gedrückt wurde                              
                digitalWrite(led1, HIGH);    // alternativer Code
                digitalWrite(led2, LOW);
                digitalWrite(TRANSISTOR, HIGH);  
              }       
                    
            case (1068) : {                  // Wenn PAUSE gedrückt wurde,                    
                digitalWrite(led1, LOW);     // alles ausschalten
                digitalWrite(led2, LOW);
                digitalWrite(TRANSISTOR, LOW);}    // Motor aus        
            break;

            case (1056) : {                  // Wenn NEXT gedrückt wurde,                    
                digitalWrite(led2, HIGH);    // LED 1 aus und LED 2 an
                digitalWrite(led1, LOW);
                digitalWrite(TRANSISTOR, LOW); // Motor aus
                }   //an        
            break;
                       
            delay(10); break;
            
            default: delay(100);             
          } // end switch
          
        irrecv.resume();
      } // end if
}

Die dritte Tastenabfrage ist natürlich obsolet, kann aber für weitere Aktivitäten zum Beispiel die Richtungsänderung des Motors weiter verwendet werden. Ich denke aber damit sollte das Prinzip deutlich geworden sein, wie man mittels IR Fernsteuerung und einer entsprechenden Empfänger-Diode eigene Steuerungen entwickeln kann.