433 Mhz / IR Board

Arduino 433Mhz / IR Board

 433_ir_board_1 433_ir_board_2
Das 433Mhz / IR Board habe ich mir zusammengebaut, um für die Versuche mit den Funksteckdosen und IR-Fernbedienungen nicht ständig alles auf dem Steckbrett zusammenstecken zu müssen. Das Modul ist komplett fertig mit 433Mhz Empfänger und Sender, sowie IR-Sender und -Empfänger. Der passende Quelltext dazu ermöglicht das Auslesen oder Senden bestimmter Codes.

Lochraster Layout

433_ir_board_lr
R1 = 33 Ohm
R2 = 1 kOhm
T1 = 2N2222

Quelltext

    /*
     * Torsten Amshove <torsten@amshove.net>
     *
     * IR_433_Board - Selbstgelötetes Board mir IR Sender/Empfänger und 433Mhz Sender/Empfänger
     *
     * Pin 2 - 433 Mhz Empfänger - Ist vorgegeben, kann nicht geändert werden
     * Pin 3 - IR Sender         - Ist vorgegeben, kann nicht geändert werden
     * Pin 4 - IR Empfänger
     * Pin 5 - 433 Mhz Sender
     *
     * Alle anderen sind unbenutzt. 
     * Spannungsversorgung über die beiden Kabel:
     *  links  - GND
     *  rechts - VCC (5V)
     *
     * Ausgabe über Seriell: 9600 baud 8N1
     *
     * Zum Senden des letzten Empfangenen Befehls gibt es zwei Möglichkeiten:
     *  Seriell  - Eingabe eines beliebiegen Zeichens in der seriellen Konsole
     *  Schalter - Durch Drücken eines angeschlossenen Schalters (schaltet auf GND)
     *
     * Code auf Basis der Beispiele aus der IRLibrary von Ken Shirriff und der RemoteSwitch-Library von Randy Simons
     *  IRLibrary:    http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
     *  RemoteSwitch: http://randysimons.com/overige/browsable/433MHz/
     */
     
    #include <IRremote.h>
    #include <RemoteReceiver.h>
    #include <RemoteSwitch.h>
     
    const int RECV_PIN_IR  =  4;
    const int SEND_PIN_433 =  5;
    const int BUTTON_PIN   = 12;
    const int DEBUG_LED    = 13;
     
    // IR Initialisierung
    IRrecv irrecv(RECV_PIN_IR);
    IRsend irsend;
    decode_results results;
     
    // Welches Signal wurde zuletzt empfagen? 1 = IR, 2 = 433 Mhz
    int last_method = 0;
     
    void setup()
    {
      Serial.begin(9600);
      irrecv.enableIRIn(); // Startet den IR-receiver
     
      RemoteReceiver::init(0, 3, showCode_433); // Startet den 433 Mhz Empfänger - showCode_433 wird bei Empfang eines Signals automatisch aufgerufen
     
      pinMode(BUTTON_PIN,INPUT);
      digitalWrite(BUTTON_PIN,HIGH);
      pinMode(DEBUG_LED,OUTPUT);
    }
     
    // Storage for the recorded code (IR)
    int codeType = -1; // The type of code
    unsigned long codeValue; // The code value if not raw
    unsigned int rawCodes[RAWBUF]; // The durations if raw
    int codeLen; // The length of the code
    int toggle = 0; // The RC5/6 toggle state
     
    void loop() {
      // IR Signal empfangen
      if(irrecv.decode(&results)){
        digitalWrite(DEBUG_LED,HIGH);
     
        // Zeile zum automatischen Auslesen: - und speichern der Werte
        storeCode_ir(&results);
        last_method = 1;
     
        // Zeilen mit mehr Details:
        Serial.println("#### IR ####");
        dump_ir(&results);
     
        Serial.println("");
     
        irrecv.resume(); // Receive the next value
        digitalWrite(DEBUG_LED,LOW);
      }
     
      // Button gedrückt / Zeichen eingegeben -> Signal senden
      if(digitalRead(BUTTON_PIN) == LOW || Serial.read() != -1){
        digitalWrite(DEBUG_LED,HIGH);
     
        Serial.println("#### Senden ####");
     
        if(last_method == 0){
          Serial.println("# FEHLER: Noch kein Signal empfangen");
        }else if(last_method == 1){
          Serial.println("## IR");
          sendCode_ir(0);
        }else if(last_method == 2){
          Serial.println("## 433");
          sendCode_433();
        }
     
        Serial.println("");
     
        digitalWrite(DEBUG_LED,LOW);
      }
    }
     
    // ######## 433 Mhz ########
    unsigned long savedCode;
     
    void showCode_433(unsigned long receivedCode, unsigned int period) {  
      digitalWrite(DEBUG_LED,HIGH);
     
      RemoteReceiver::disable();
     
      //Need interrupts for delay
      interrupts();
     
      unsigned long code;
      unsigned long code1;
      unsigned long code2;
      unsigned long periode2;
     
      //Copy the received code.
      code = receivedCode;
      code1 = code;
      code = code  & 0xFFFFF; //truncate to 20 bits for show; receivedCode is never more than 20 bits..
      code2 = code;
      //Add the period duration to the code. Range: [0..511] (9 bit)
      code |= (unsigned long)period << 23;
      //Add the number of repeats to the code. Range: [0..7] (3 bit). The actual number of repeats will be 2^(repeats), 
      //in this case 8
      code |= 3L << 20;
     
      // Zeile zum automatischen Auslesen:
      Serial.print("433Mhz: ");
      Serial.println(code);
     
      // Zeilen mit mehr Details:  
      Serial.println("#### 433Mhz ####");
      Serial.print("# Code ohne shift:  ");
      Serial.println(code1);
      Serial.print("# Code mit Shift 0xFFFFF:  ");
      Serial.println(code2);
      Serial.print("# Periode:  ");
      Serial.println(period);
      periode2 |= (unsigned long)period << 23;
      Serial.print("# Periodee mit <<23:  ");
      Serial.println(periode2);
      Serial.print("# Code mit Anzahl Wiederholungen, also komplett:  ");
      Serial.println(code);
     
      // Code speichern
      savedCode = code;
      last_method = 2;
     
      Serial.println("");
     
      RemoteReceiver::enable();
     
      digitalWrite(DEBUG_LED,LOW);
    }
     
    void sendCode_433(){
      //Disable the receiver; otherwise it might pick up the retransmit as well.
      RemoteReceiver::disable();
     
      //Need interrupts for delay
      interrupts();
     
      Serial.print("# Code: ");
      Serial.println(savedCode);
     
      RemoteSwitch::sendTelegram(savedCode,SEND_PIN_433);
     
      RemoteReceiver::enable();
    }
     
     
    // ######## IR ########
     
    // Dumps out the decode_results structure.
    // Call this after IRrecv::decode()
    // void * to work around compiler issue
    //void dump(void *v) {
    //  decode_results *results = (decode_results *)v
    void dump_ir(decode_results *results) {
      int count = results->rawlen;
      if (results->decode_type == UNKNOWN) {
        Serial.println("# Could not decode message");
      } 
      else {
        if (results->decode_type == NEC) {
          Serial.print("# Decoded NEC: ");
        } 
        else if (results->decode_type == SONY) {
          Serial.print("# Decoded SONY: ");
        } 
        else if (results->decode_type == RC5) {
          Serial.print("# Decoded RC5: ");
        } 
        else if (results->decode_type == RC6) {
          Serial.print("# Decoded RC6: ");
        }
        Serial.print(results->value, HEX);
        Serial.print(" (");
        Serial.print(results->bits, DEC);
        Serial.println(" bits)");
      }
      Serial.print("# Raw (");
      Serial.print(count, DEC);
      Serial.print("): ");
     
      for (int i = 0; i < count; i++) {
        if ((i % 2) == 1) {
          Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
        } 
        else {
          Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
        }
        Serial.print(" ");
      }
      Serial.println("");
    }
     
    // Stores the code for later playback
    // Most of this code is just logging
    void storeCode_ir(decode_results *results) {
      Serial.print("IR: ");
      codeType = results->decode_type;
      Serial.print("codeType: ");
      Serial.print(codeType);
      Serial.print(" (");
      if (codeType == NEC) {
        Serial.print("NEC");
      } else if (codeType == SONY) {
        Serial.print("SONY");
      } else if (codeType == RC5) {
        Serial.print("RC5");
      } else if (codeType == RC6) {
        Serial.print("RC6");
      } else if (codeType == UNKNOWN) {
        Serial.print("UNKNOWN");
      }  
      Serial.print(")");
     
      int count = results->rawlen;
      if (codeType == UNKNOWN) {
        codeLen = results->rawlen - 1;
        Serial.print(" rawCodes: ");
        // To store raw codes:
        // Drop first value (gap)
        // Convert from ticks to microseconds
        // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
        for (int i = 1; i <= codeLen; i++) {
          if (i % 2) {
            // Mark
            rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
          } else {
            // Space
            rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
          }
    //        Serial.print(rawCodes[i - 1], DEC);
          Serial.print(rawCodes[i - 1]);
          Serial.print(",");
        }
      } else {
        if (results->value != REPEAT) {
    //      Serial.println(results->value, HEX);
          codeValue = results->value;
          Serial.print(" codeValue: ");
          Serial.print(codeValue);
          codeLen = results->bits;
        }
      }
      Serial.print(" codeLen: ");
      Serial.print(codeLen);
      Serial.println("");
    }
    /*
      codeType = results->decode_type;
      int count = results->rawlen;
      if (codeType == UNKNOWN) {
        Serial.println("# Received unknown code, saving as raw");
        codeLen = results->rawlen - 1;
        // To store raw codes:
        // Drop first value (gap)
        // Convert from ticks to microseconds
        // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
        Serial.print("#");
        for (int i = 1; i <= codeLen; i++) {
          if (i % 2) {
            // Mark
            rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
            Serial.print(" m");
          } 
          else {
            // Space
            rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
            Serial.print(" s");
          }
          Serial.print(rawCodes[i - 1], DEC);
        }
        Serial.println("");
      }
      else {
        if (codeType == NEC) {
          Serial.print("# Received NEC: ");
          if (results->value == REPEAT) {
            // Don't record a NEC repeat value as that's useless.
            Serial.println("repeat; ignoring.");
            return;
          }
        } 
        else if (codeType == SONY) {
          Serial.print("# Received SONY: ");
        } 
        else if (codeType == RC5) {
          Serial.print("# Received RC5: ");
        } 
        else if (codeType == RC6) {
          Serial.print("# Received RC6: ");
        } 
        else {
          Serial.print("# Unexpected codeType ");
          Serial.print(codeType, DEC);
          Serial.println("");
        }
        Serial.println(results->value, HEX);
        codeValue = results->value;
        codeLen = results->bits;
      }
    }
    */
     
    void sendCode_ir(int repeat) {
      if (codeType == NEC) {
        if (repeat) {
          irsend.sendNEC(REPEAT, codeLen);
          Serial.println("# Sent NEC repeat");
        } 
        else {
          irsend.sendNEC(codeValue, codeLen);
          Serial.print("# Sent NEC ");
          Serial.println(codeValue, HEX);
        }
      } 
      else if (codeType == SONY) {
        irsend.sendSony(codeValue, codeLen);
        Serial.print("# Sent Sony ");
        Serial.println(codeValue, HEX);
      } 
      else if (codeType == RC5 || codeType == RC6) {
        if (!repeat) {
          // Flip the toggle bit for a new button press
          toggle = 1 - toggle;
        }
        // Put the toggle bit into the code to send
        codeValue = codeValue & ~(1 << (codeLen - 1));
        codeValue = codeValue | (toggle << (codeLen - 1));
        if (codeType == RC5) {
          Serial.print("# Sent RC5 ");
          Serial.println(codeValue, HEX);
          irsend.sendRC5(codeValue, codeLen);
        } 
        else {
          irsend.sendRC6(codeValue, codeLen);
          Serial.print("# Sent RC6 ");
          Serial.println(codeValue, HEX);
        }
      } 
      else if (codeType == UNKNOWN /* i.e. raw */) {
        // Assume 38 KHz
        irsend.sendRaw(rawCodes, codeLen, 38);
        Serial.println("# Sent raw");
      }
    }