Apr 01

Ein wenig herumgespielt mit dem Arduino habe ich ja schon bei dem Rauchmelder und dem BetaBrite-Display. Nicht gebloggt wurde bisher über die Funksteckdosen, die derweil per Webserver an- und ausgeschaltet werden können (Dank dieser Library).

Das müsste doch ansich auch mit dem Garagentoröffner funktionieren. Der tut doch auch auf 433,92MhZ. Letztes Jahr hatte ich mir bei Watterod einen 433er Sender und einen Empfänger, der bisher noch nicht zum Einsatz kam, geordert. Den Empfänger also fix mal startklar gemacht und an den Arduino angeflanscht. Allerdings ist das auslesen eines Senders, bei dem man keinen Schimmer hat welche Codierung genutzt wird, alles andere als trivial. Habe es dann ersteinmal mit der 433MhZ-Wetterstation von Tchibo probiert. Nach diversen Bitfriemeleien purzelte da dann auch tatsächlich die Temperatur heraus. Nungut – wir wollen ja einen Garagentoröffner simulieren, nicht Funkthemometer auslesen.

Aus dem ollen Code bin ich allerdings nicht schlau geworden. Hier mal ein oszillografierter Ausschnitt (due to security reasons :-) ) des Senders:

Man erkennt insgesamt 3 Arten von Pulsen – kurze, lange und mittlere (WTF ?). Habe erst auf einen Manchester-Code getippt. War mir dann aber irgendwie zu doof den zu analysieren. Also fix mit gtkwave die Pulslängen in ein Array gepackt, und fertig ist der Garagentoröffner per Arduino. Hier der (Draft !) des Sourcecodes mit dem Pulslängenarray (Negativ = LOW, Positiv = HIGH):

int garage[45]={  // Block 1 (21 x das gepulse)
               -16382,-16382, // Blocktrenner (2)
               // Block 2 (22 x das gepulse)
};


void setup() {
  pinMode(8,OUTPUT);
  pinMode(13,OUTPUT);
  digitalWrite(8,LOW);
}

void loop() {
  fire(garage,0);          // Garage Toggeln
  digitalWrite(8,LOW);
  digitalWrite(13,HIGH);
  delay(10000);
  digitalWrite(13,LOW);
}

void fire(int what[],int corr) {  // what: PositiverWert: Dauer des HIGHPulses, NegativerWert: Dauer des LowPulses; corr = Korrekturzeit pro Puls
    for (int i=0;i<26;i++) {
      int del=what[i]+corr;
      if (del>0) {
        digitalWrite(8,HIGH);
        delayMicroseconds(del);
      } else {
        del=del*(-1);
        digitalWrite(8,LOW);
        delayMicroseconds(del);
    }
  }
}
									

Fazit: Funktioniert perfekt. Wenn allerdings jemand ‘ne Ahnung hat welches Protokoll (bzw. Leitungscode) das sein könnte – immer her damit :-)

Update 22.08.2012 – Hier, auf Nachfrage, der Sourcecode für den Wetterstationsempfang. Das Ding ist echt nur ein “Proof of concept” – also alles andere als schön. Vom Aufbau her:

  • 433MhZ-Empfänger Serial-Out hängt an PIN2

-----------------------------------------------------------------------------
/*
  Liest dieses komische Tchibo-Wetterdingens per 433MhZ aus.
*/

boolean cnt=false;
int reader=0;
int cnter=0;
char reading[28];
void setup() {
  Serial.begin(9600);
  Serial.println("go!");
  pinMode(2, INPUT);
 // pinMode(13,OUTPUT);
}

void loop() {
    int LowVal=pulseIn(2,LOW);
    if (LowVal < 11000) {  // Kuezer als 1100ms Low ? Koennte unserer Sensor sein
      if (decodeTime(LowVal) == 'S') {  // Startsequenz ?
        cnt=true;                       // Dann go fuer die Sammlung
        cnter=0;                        // BitCounter auf 0
      }
      if ( (cnter<=27) && cnt && ((decodeTime(LowVal) == '0') || (decodeTime(LowVal)=='1'))) { // Stream noch nicht voll und ein Bit erkannt ?
//       Serial.print(decodeTime(LowVal)); 
       reading[cnter]=decodeTime(LowVal);  // Ab ins Array damit
       cnter=cnter+1;                      // Arraycounter fuers naechste Bit inkrementieren
      }
    } else {
      cnt=false;                           // Zurueck auf Anfang - nix fuer uns.
    }

      if ((cnter==28)) {                   // Arrray Voll ?
        Serial.print('/');
        Serial.print(reading);
        Serial.print('/');
        Serial.println(decodeTemp(reading));
        cnter=0;
        cnt=false; 
      }
  
}

float decodeTemp(String bitstream) {  // Versucht aus dem Bitstrom die Temp. zu berechnen
  int x=0;
  int chk=0;
  for (int i=16;i<24;i++) {      // Extrahiert das Byte zwischen Bit 16 und 24 und packt es als integer in "x"
    if (bitstream[i] == '1') {
      bitSet(x,(23-i));
    }
  }
  for (int i=4;i<15;i++) {      // Kenner aus den 3 Nibbles zwischen Bit 4 und 15 holen (koennte auch der Kanal sein ?)
    if (bitstream[i] == '1') {
      bitSet(chk,(14-i));
    }
  }
  if (chk != 136) {            // Kenner = 136 ? Dann ist es unserer Sensor !
    return(-999);              // Wenn nicht, dann -999 zurueck
  } else {
    return ((float)x/10);
  }
}

char decodeTime(int time){  // Wandelt die Pulse in Bits um.
  if (time > 1500 && time < 11000) { // passendes Signal (zwischen 150ms und 11000ms) ?
        if (time < 2500) {           // kleiner 250ms ? Dann LOW
          return '0';
        } 
        if (time < 5000 && time >3000) {  // Zwischen 500ms und 1000ms dann HIGH
          return '1';
        }
        if (time >8000) {                // Groesser 800ms dann Startsequenz !
          return 'S';
        }
  } else {
    return 'X';
  }  
}
									

m4s0n501

4 Responses to “Garagentoröffner mit dem Arduino”

  1. Marc sagt:

    Servus!

    Du schreibst hier, dass Du mit Hilfe eines 433Receivers eine Tchibo Wetterstation ausgelesen hast. Leider finde ich von Dir keine weiteren Infos dazu. Ich würde gerne das selbe hier machen, meine Versuche scheitern aber.
    Der 433 Receiver von Conrad scheint zwar was zu empfangen, aber ich kann nichts auswerten.

    Kannst du mir evtl. Deinen Aufbau und den Code von Deinem Versuch zukommen lassen?

    Danke!

    GRuß, Marc

  2. Joerg sagt:

    Hallo Marc, habe den Source mal angehängt. Der Aufbau ist nicht der Rede wert. Epmfänger (“RF Link 2400bps Empfänger – 434MHz” von Watterott-Elektronik) mit Strom versorgen, Serial-Out des Empfängers an PIN2, ‘nen kleines Stück “draht” als Antenne und gut ist.

  3. ursm sagt:

    wenn ich das programm unter 1.0.5 starte bekomme ich nach ziemlichem warten einen launch4j error und der java-prozess bleibt hängen.
    hinweis: alle andern ino’s laufen

    mit arduino.exe –l4j-debug erhalte ich folgendes (wenig aussagendes) log (winXP/32)
    CmdLine: C:\Program Files\Arduino\arduino.exe –l4j-debug
    WOW64: no
    Working dir: C:\Program Files\Arduino\.
    Bundled JRE: java
    Check launcher: C:\Program Files\Arduino\java\bin\javaw.exe (OK)
    Add classpath: lib\pde.jar
    Add classpath: lib\core.jar
    Add classpath: lib\jna.jar
    Add classpath: lib\ecj.jar
    Add classpath: lib\RXTXcomm.jar
    Launcher: C:\Program Files\Arduino\java\bin\javaw.exe
    Launcher args: -Xms128m -Xmx128m -classpath “lib;C:\Program Files\Arduino\java\lib\tools.jar;lib\pde.jar;lib\core.jar;lib\jna.jar;lib\ecj.jar;lib\RXTXcomm.jar” processing.app.Base
    Args length: 164/32768 chars
    Exit code: 259

    die ide startet und wenn ich das program aus dem forum reinpaste und kompilliere erhalte ich bei
    if (bitstream == ‘1’) {
    folgende fehlermeldungen.
    sketch_jun30a.ino: In function ‘float decodeTemp(String)':
    sketch_jun30a:48: error: invalid conversion from ‘char’ to ‘const char*’
    sketch_jun30a:48: error: initializing argument 1 of ‘unsigned char String::operator==(const char*) const’
    sketch_jun30a:53: error: invalid conversion from ‘char’ to ‘const char*’
    sketch_jun30a:53: error: initializing argument 1 of ‘unsigned char String::operator==(const char*) const’

    ich wäre froh, wenn ihr mir bei diesen 2 problemen (startup-error & kompile-fehler) weiterhelfen könntet. vielen dank!

    p.s. hintergrund der ganzen aktion: ich möchte die EUROCHRON aussensensoren (Conrad) via arduino lesen und weiterverarbeiten können

  4. Domi sagt:

    Hallo Joerg,

    Welchen Oszi hast DU benutzt? Hast Du einen Tipp für ein Gerät?

    Gruss

Leave a Reply

*

preload preload preload