Codesnippet: php / Raspberry Pi => Fritzbox => Telefonanruf

Jaaaa, ich hab‘ endlich auch einen Raspberry Pi und bin total begeistert – obwohl ich nach wie vor keine Ahnung habe was ich damit jetzt konkret anstellen soll 🙂
Beim rumspielen ist jetzt ein Snippet entstanden, das sich per telnet an der Fritzbox anmeldet und per AT-Befehl kurz eine Nummer anruft.

!#/usr/bin/php5
<?php

$fritzIP  = '192.168.178.1';
$pass     = 'xxxxxxxxxx';
$number   = '0173xxxxxx';
$sleep    = 10;


if ($fp = fsockopen($fritzIP, 23)) {
  $buffer = '';
  while (!feof($fp) && !preg_match('/password/', $buffer)) {
    $buffer .= fread($fp, 1);
  }
  
  fputs($fp, $pass . "rn");
  sleep(1);
  fputs($fp, 'echo "ATDT' . $number . '" | nc 127.0.0.1 1011' . "rn");
  sleep($sleep);
  fputs($fp, 'echo "ATH" | nc 127.0.0.1 1011' . "rn");
  sleep(1);
  
  
} else {
  echo 'Telnet connection failed ' . $fritzIP;
}

RFM01 (RFM12) auf’s Breadboard

Dieses äußerst beliebte Funkmodul hat tragischerweise ein Rastermaß von 2mm und passt daher nicht auf ein Standardbreadboard mit 2.54mm. Auf eine Lochrasterplatine legen und verkabeln ist nichts für Grobmotoriker (boah, was hab‘ ich geflucht), deshalb hier mein – wie ich finde – eigentlich ganz guter Lösungsweg:

Beinchen von geopferten Widerständen ranlöten, in die Lochrasterplatine stecken und ganz konventionell festlöten.

Fail! Dummerweise ist das jetzt eine Spalte breiter als mein Breadboard und passt daher immer noch nicht rein. Hab‘ echt die Lust dran verloren, aber der Lösungsansatz war an sich schon ganz gut, oder? 🙂

ISP lohnt sich

Mein neustes Spielzeug ist ein AVR ISP und nach den ersten Versuchen kann ich nur begeistert sagen: die Anschaffung lohnt sich auch für normale Aruino User!

Hintergrundwissen:
Normalerweise programmiert man einen nackten Atmel Mikrocontroller – wie er sich auf jedem Arduino befindet – über die SPI Schnittstelle mit Hilfe eines In-System Programmers. Das man einen Arduino im Normalfall dagegen über die serielle Schnittstelle programmiert liegt daran, dass auf dem Mikrocontroller bereits ein Bootloader installiert ist, der nach einem Reset erstmal kurz schaut ob da erst ein neues Programm über die serielle Schnittstelle hochgeladen werden soll. Ich habe lange darüber nachgegrübelt, wieso die nicht gleich einen ISP mit auf das Board gepackt haben und vermute es liegt daran, dass man die serielle Schnittstelle zum Computer beim Prototyping ohnehin fast immer benötigt und das ganze mit dieser Methode anfängerfreundlicher und kostengünstiger ist.

Wozu ein ISP beim Arduino?
Da ein Arduino ohne Bootloader nicht über die serielle Schnittstelle programmiert werden kann, braucht man einen ISP zwingend um zunächst einmalig den Bootloader zu installieren (bei fertigen gekauften Arduinos ist der bereits vorinstalliert).
Man kann den ISP aber auch dazu verwenden, einen Sketch direkt hochzuladen. Das hat folgende Vorteile:

  • Der Bootloader fällt weg, man spart also Speicherplatz auf dem Controller
  • Der Upload geht spürbar schneller (Getestet mit einem Atmega8 auf einem Duemilanove Board mit Diamex ISP – ca. 3 Sekunden statt ca. 9 Sekunden)
  • Die serielle Schnittstelle bleibt frei, man kann sich also das lästige Serial Monitor öffnen/schließen Spielchen bei jedem Upload sparen

Konfiguration ISP
Wenn der eigene ISP nicht in der Liste unter „Tools->Burn Bootloader“ auftaucht, muss man den zunächst einmal in der Datei /arduino-0022/hardware/programmers.txt anlegen. Bei mir habe ich folgenden Eintrag oben hinzugefügt:

diamexisp.name=Diamex ISP
diamexisp.communication=serial
diamexisp.protocol=stk500v2
diamexisp.speed=19200

Wenn man die Arduino IDE anschließend neu startet, findet man den neuen ISP auch wie folgt im Menü:

Konfiguration Board
In der Datei /arduino-022/hardware/boards.txt muss man angeben, bei welchen Boards der Upload von Sketchen über den ISP laufen soll. Das geht mit der Konfigurationsvariable [board].upload.using=[programmer]. Am besten kopiert man dazu einen bestehenden Eintrag, entfernt die [board].bootloader Einträge, fügt die [board].upload.using Angabe hinzu und gibt dem ganzen einen neuen Namen. Wie zum Beispiel hier aus meiner Config:

atmega8isp.name=ATmega8 & ISP
atmega8isp.upload.protocol=stk500v2
atmega8isp.upload.maximum_size=30720
atmega8isp.upload.speed=57600
atmega8isp.upload.using=diamexisp
atmega8isp.build.mcu=atmega8
atmega8isp.build.f_cpu=16000000L
atmega8isp.build.core=arduino

Alternative zum Serial Monitor
Jetzt können wir Sketche über den Com Port des ISP hochladen und serielle Daten über den Com Port des Arduino USB Anschlusses verarbeiten. Dummerweise gibt es in der Arduino IDE nur einen Com Port für beide Zwecke zur Auswahl. Wenn man den eingebauten Serial Monitor verwendet, müsste man also vor und nach jedem Upload den Port ändern, was ziemlich lästig wäre. Die Rettung ist ein alternatives Terminalprogramm wie zum Beispiel dieses hier. Einfach die Arduino IDE auf den Com Port des ISP stellen und im alternativen Terminalprogramm auf den USB Anschluss.

Use any Arduino pin for transmission with the IRremote libary by soft PWM

I really love Ken Shiriffs IRremote libary for Arduino but it had a dealbreaking limitation for my current project: it makes use of the PWM functionality and is therefore bound to pin 3. As I really needed all PWM pins for other stuff and didn’t want to upgrade to a Mega board, I worked out this hack.

A IR signal consists of on- and off states and that is literally switching the IR LED on and off in special periods. While a off state is actually switching the LED off at all, a on state is more like blinking with a really high frequency of 38kHz. This is a typical task for PWM but after all it is again nothing else than just switching it on and off.

First at all we have to find out how fast we have to switch on/off with this frequency.

36000 / 1s = 1 / n * s
n = 1/36000s =  27,7 μs

So we have to switch it on and off every 27,7μs (fortunately the delayMicroseconds function works accurately for values above 3μs) and it’s simple as this:

while (OnStateDuration) {
  digitalWrite( sendPin, HIGH);
  delayMicroseconds(14);
  digitalWrite( sendPin, LOW);
  delayMicroseconds(14);
}

=== Instruction ===
You can download the modified libary here or go through these steps:

Replace the following methods in IRremote.cpp:

void IRsend::mark(int time) {
  unsigned long n = micros();
  while (micros()-n < time) {
    digitalWrite(irparams.sendpin, HIGH);
    delayMicroseconds(irparams.pulselength);
    digitalWrite(irparams.sendpin, LOW);
    delayMicroseconds(irparams.pulselength);
  }
}

void IRsend::space(int time) {
  digitalWrite(irparams.sendpin, LOW);
  delayMicroseconds(time);
}

void IRsend::enableIROut(unsigned int khz) {
  irparams.pulselength = 500 / khz;
  pinMode(irparams.sendpin, OUTPUT);
  digitalWrite(irparams.sendpin, LOW); // When not sending PWM, we want it low
}

IRrecv::IRrecv(int recvpin)
{
  irparams.recvpin = recvpin;
  irparams.blinkflag = 0;
}

Add the sendpin parameter to the constructor signature in IRremote.h:

class IRsend
{
public:
  IRsend(int sendpin);

Define the sendpin and period variables in IRremoteInt.h:

typedef struct {
  uint8_t sendpin;
  unsigned int pulselength;


When using in a sketch, you have to specify the pin for transmission:

IRsend irsend;  // deprecated
IRsend irsend(10);  // send on pin 10


Flattr this

======

PS: If you’re experimenting with IR you might find this useful. You can use an ordinary red LED instead of a IR LED on short a short distance of let’s say about 2 or 3 cm. I accident found this and I’m very happy about not needing to use my mobile phones camera to check the IR light any more.

Oszilloskop für Arme

Ja, ich bin immer noch bei meinen Fernbedienungen.

Die grundsätzliche Funktionsweise war ja folgende: das Signal besteht aus An/Aus-Zuständen in einer bestimmten zeitlichen Abfolge. Das kann man wunderbar in einem Koordinatensystem (X-Achse Zeit, Y-Achse Zustand) visualisieren – nichts anderes macht ja auch ein Oszilloskop oder Logic Analyzer. Da normalsterbliche Bastler wie ich sowas aber nicht besitzen (Hallo Familie, das ist ein Wink mit dem Weihnachtszaunpfahl), habe ich dafür ein php-Script geschrieben.

Die RCSwitch Libary misst die Zeitabstände zwischen den An- und Aus-Zuständen und speichert diese in einem Array. Das Array wird an die Callback Methode übergeben und kann dort ausgegeben werden.

Arduino Sketch:

#include 

RCSwitch mySwitch = RCSwitch(3);

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0, output);
}

void loop() {

}

void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw) {
    for (int i=0; i< length*2; i++) {
      Serial.print(raw[i]);
      Serial.print(",");
    }
}

Im Serial Monitor bekomme ich nach Drücken einer Fernbedienung also eine kommaseparierte Liste mit Mikrosekunden die ein An-/Aus-Zustand jeweils dauert. Copy&Paste unter: http://test.sui.li/oszi.php und schwupps hat man das ganze hübsch aufbereitet 🙂

Hier ein paar Beispiele:

Signal eines Pollin Steckdosensets:


Signal eines Pollin Funkdimmers:


Signal zum öffnen des Kofferraumes einer billigen Nachrüst-Zentralverriegelung für’s Auto:


Signale zum aufschließen meines MG mit der Original Lucas 17TN Fernbedienung (Rolling Code, der ändert sich jedes mal):


Flattr this

Funkfernbedienungen: neue Erkentnisse und decodieren

Kennst du eine, kennst du alle. Wie ich inzwischen festgestellt habe, basieren die meisten billigen Funkfernbedienungen auf dem gleichen Protokoll. Neben den bei Funksteckdosen beliebten SC2262, HX2262, PT2262 wären da noch die EV1527, RT1527, FP1527, HS1527 (alle untereinander kompatibel, gefunden in den Funkdimmern von Pollin oder erschreckenderweise auch in der Fernbedienung für die Zentralverriegelung meines Autos… ich glaube zu dem Thema werde ich nochmal einen eigenen Artikel schreiben) zu erwähnen.

Die 2262er senden vom Nutzer konfigurierte 8 oder 10Bit lange Adressen gefolgt von 4 oder 2Bit langen Befehlen und einem Sync-Bit. Die 1527er senden einen Sync-Bit, eine fest im Chip verdratete, „einmalige“ 20Bit Adresse und einen 4Bit langen Befehl. Da man die Three-State Bits „1“, „0“, „F“ bei den 2262ern auch zu je zwei Two-State Bits „1“, „0“ substituieren kann (1=11, 0=00, F=01), senden also eigentlich beide letzendlich immer nur einen 24Bit Wert und eine Pause an deren Länge man das Timing ermitteln kann.

Hier ist mein erstes zusammengehacktes Arduino Sketch zum decodieren aller 433MHz Fernbedienungen die nach diesem Prinzip funktionieren (433MHz AM Empfänger oder falls nicht zur Hand einfach den im vorletzten Blogeintrag beschriebenen Dout der Fernbedienung an Pin#2):

#define maxChanges 500

unsigned int duration;
unsigned int changeCount;
unsigned int timings[maxChanges];
unsigned long lastTime;
unsigned int repeatCount;

void setup() {
  Serial.begin(9600);
  
  lastTime = micros();
  repeatCount = 0;
  changeCount = 0;
  
  attachInterrupt(0, r, CHANGE); 
}

void loop() {

}

void output() {
  unsigned long code = 0;
  unsigned long delay = timings[1] / 31;
  unsigned long delayTolerance = delay*0.2;
  Serial.print("Delay: ");
  Serial.println(delay);
  for (int i = 2; i+1<changeCount ; i=i+2) {
    if (timings[i] > delay-delayTolerance && timings[i] < delay+delayTolerance && timings[i+1] > delay*3-delayTolerance && timings[i+1] < delay*3+delayTolerance) {
      Serial.print("0");
      code = code << 1;
    } else if (timings[i] > delay*3-delayTolerance && timings[i] < delay*+delayTolerance && timings[i+1] > delay-delayTolerance && timings[i+1] < delay+delayTolerance) {
      Serial.print("1");
      code+=1;
      code = code << 1;
    } else {
      Serial.println("");
      Serial.print("Failed: ");
      Serial.print(i);
      Serial.print("/");
      Serial.print(timings[i]);
      Serial.print("/");
      Serial.println(timings[i+1]);
    }
  }
  code = code >> 1;
  Serial.println();
  Serial.print("Code: ");
  Serial.println(code);
    Serial.println();
}

void r() {
  long time = micros();
  duration = time - lastTime;
  
  if (duration > 5000 && duration > timings[1] - 200 && duration < timings[1] + 200) {
    repeatCount++;
    if (repeatCount == 2) {
      output();
      repeatCount = 0;
    }
    changeCount = 0;
  } else if (duration > 6000) {
    changeCount = 0;
  }
  
  if (changeCount >= maxChanges) {
    changeCount = 0;
    repeatCount = 0;
  } else {
    changeCount++;
  }
  timings[changeCount] = duration;
  lastTime = time;
}

Update: Eine Empfangs- und Decodierfuntion findet sich inzwischen auch in der RCSwitch Libary


Flattr this

Funksteckdosen mit dem Handy steuern

Nachdem die Arduino Libary für die 433MHz Steckdosen fertig ist, ist die Ansteuerung über eine serielle Bluetooth Schnittstelle fast schon ein no brainer.

Hardware
1.) Die RC Fernbedienung mit Strom versorgen (Arduino: Vin + GND), Datenleitung beim Arduino an Pin #10

2.) Den Bluetooth Mate mit Strom versorgen (BTMate VCC => Arduino 5V, BTMate GND => Arduino GND), serielle Schnittstelle verbinden (BTMate RX-1 => Arduino TX, BTMate TX-0 => RX) und beim BTMate noch CTS1 + RTS0 kurzschließen.

3.) Android Handy bereithalten 🙂

Android App
qrcodeFür den Anfang tut es eine fertige App. Im Market gibt es z.B. Blue Control, welches einfach auf Knopfdruck einzelne Bytes an das verbundene Gerät sendet. Die mit A..H beschrifteten Knöpfe senden jeweils den entsprechenden (Klein)Buchstaben (nicht wundern, in Version 1.0 sind außerdem b und c vertauscht), Die Pfeiltasten sind U (up), D (down), L (left), R (right) und C (center).

Arduino Sketch
Schaltet die erste Steckdose aus der ersten Gruppe bei „a“ an und bei „e“ aus.

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch(10);  // Sender is connected to Pin #10

void setup() {
  Serial.begin(115200);
}

void loop() {
  
  if (Serial.available()) {
    byte inBT = Serial.read();
    if (inBT == 'a') {
        mySwitch.switchOn(1, 1);
    }
    if (inBT == 'e') {
        mySwitch.switchOff(1, 1);
    }
  }
  
}


Flattr this

Low cost RC power sockets (radio outlets) + Arduino

[Deutsche Version]

For cheap home automation purposes I’d like to present you my new Arduino libary for operating up to 16 low cost 433MHz RC power sockets. I’ve bought this RC switch set for about 10 EUR.

There is a SC5262 chip (datasheet) built in the hand set which – depending on which key is pressed – generates a data telegram and relays it to the actual RC sender. After studying the datasheet and some other resources (1, 2, 3 – sorry, all in german) on similar projects I was able to control the switches using only one I/O pin at the Arduino.

Theory
If you know how the data telegrams look like, you can generate them with the microcontroller and therefore resign the encoder chip from the hand set.

A code bit consists of two on/off states. The important thing are the cronological lengths of these states. You can think of it like morse. There are thre possible code bits at all, that is „0“, „1“ and „F“. Furthermore there is another sync. bit (I’ll call it „S“).

"0" Bit => 1/8 cycles on, 3/8 cycles off, 1/8 cycles An, 3/8 cycles off   -...-...
"1" Bit => 3/8 cycles on, 1/8 cycles off, 3/8 cycles An, 1/8 cycles off   ---.---.
"F" Bit => 1/8 cycles on, 3/8 cycles off, 3/8 cycles An, 1/8 cycles off   -...---.
"S" Bit => 1/8 cycles on, 31/8 cycles off -...............................

A code word consists of 9 address bits, 3 data code bits and one sync. bit. It represents the command (data bits) to a specific switch (address bits).

A code frame consists of 4 code words. Basically every command is repeated 4 times.

The conrad power switches are coded as follows:
4 bits group address + 4 bits switch address + 1 unused adress bit + 1 unused data bit + 2 data/command bits + 1 sync. bit


group address I = "0FFF"
group address II = "F0FF"
group address III = "FF0F"
group address IV = "FFF0"

switch 1 = "0FFF"
switch 2 = "F0FF"
switch 3 = "FF0F"
switch 4 = "FFF0"

unused databits = never mind, could be either "F" or "0"

command on = "FF"
command off = "F0"

So if you want to switch the 3rd switch from the 4th group off, you’ll have to send „FF0FFFF0FFF0S“.

Hardware / Hacking the hand set

Open your hand-held transmitter and solder a wire to the positive pole (+), one to the negative pole (-) of the battery holder and another one to the DOUT Pin of the SC5262S chip.
Altough my transmitter was operated with a 12V battery it also worked with 5V, so I think it’s fine to power it directly from the Arduino (5V and GND). Connect DOUT to any available I/O pin from the Arduino.

Software
Download RCSwitch.zip and extract it to your /Arduino/Libaries directory. The following sketch should be self explaining 🙂

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch(11);  // Sender is connected to Pin #11

void setup() {
}

void loop() {
    mySwitch.switchOn(1, 1);         // Switch 1st socket from 1st group on
    delay(1000);
    mySwitch.switchOff(1, 1);        // Switch 1st socket from 1st group off
    delay(1000);
}

Updates

  • The libary is hosted at google code now (here).
  • New sending methods (other outlet types than described here or raw codes)
  • New functionality to receive and decode signals from your remote hand set


Flattr this

Low cost Funksteckdosen + Arduino

[English version]

Für die billige Haus-Automatisierung möchte ich hier heute meine frisch geschriebene Arduino Libary für „433MHz Baumarkt Funksteckdosen“ vorstellen. Weil Conrad aber näher als Max Bahr ist und ich auch lieber bei Conrad shoppe, habe ich für knapp 10 EUR die hier gekauft.

In der Fernbedienung schlummert ein SC5262 Chip (Datenblatt), welcher je nach gedrücktem Knopf ein digitales Datentelegram erzeugt und an den eigentlichen Funksender weitergibt. Nach intensivem Studium des Datenblatts und verschiedenen anderen Quellen (1) (2) (3) mit ähnlichen Projekten habe ich es auch tatsächlich auch wie folgt geschafft, die Steckdose mit einem einzigen Datenkabel am Arduino zu steuern.

Theorie
Wenn man weiss wie die Datentelegramme aussehen müssen, kann man die auch selbst mit dem Mikrocontroller erzeugen und somit auf den Encoderchip aus der Fernbedienung verzichten. Im Datenblatt steht folgendes:

Ein Code Bit besteht aus zwei An/Aus-Zuständen, wichtig ist hierbei die zeitliche Länge dieser Zustände, kann man sich so ähnlich vorstellen wie Morsezeichen. Es gibt insgesamt drei mögliche Code Bits, nämlich „0“, „1“ und „F“. Darüber hinaus gibt es noch ein Sync. Bit (ich nenn‘ es mal „S“).

"0" Bit => 1/8 Taktlänge An, 3/8 Taktlängen Aus, 1/8 Taktlänge An, 3/8 Taktlängen Aus   -...-...
"1" Bit => 3/8 Taktlängen An, 1/8 Taktlänge Aus, 3/8 Taktlängen An, 1/8 Taktlänge Aus   ---.---.
"F" Bit => 1/8 Taktlänge An, 3/8 Taktlängen Aus, 3/8 Taktlängen An, 1/8 Taktlänge Aus   -...---.
"S" Bit => 1/8 Taktlänge An, 31/8 Taktlängen Aus -...............................

Ein Code Word besteht aus 9 Adress Code Bits, 3 Data Code Bits und einem Sync Bit und repräsentiert quasi den Befehl welche Steckdose (Adress Bits) was machen soll (Daten Bits).

Ein Code Frame besteht aus 4 Code Words, also im Grunde genommen wird jeder Befehl 4x wiederholt.

Die Conrad Steckdosen sind dabei folgendermaßen Codiert:
4 Bits Gruppenadresse + 4 Bits Steckdosenadresse + 1 ungenutzter Adress Bit + 1 ungenutzer Daten Bit + 2 Daten/Befehls Bits + 1 Sync Bit


Gruppenadresse I = "0FFF"
Gruppenadresse II = "F0FF"
Gruppenadresse III = "FF0F"
Gruppenadresse IV = "FFF0"

Steckdose 1 = „0FFF“
Steckdose 2 = „F0FF“
Steckdose 3 = „FF0F“
Steckdose 4 = „FFF0“

Ungenutze Datenbits = egal, also „F“ oder „0“

Befehl An = „FF“
Befehl Aus = „F0“

Wenn ich also die 3. Steckdose aus der 4. Gruppe ausschalten möchte, muss ich ein „FF0FFFF0FFF0S“ senden.

Hardware / Fernbedienung anzapfen

Fernbedienung öffnen, am DOUT Pin ein Kabel und zwei weitere für die Stromversorgung anlöten. DOUT kann an jeden beliebigen I/O Pin vom Arduino, den Strom kann man auch vom Arduino abzapfen (5V und GND), denn obwohl da eigentlich eine 12V Batterie drin war funktioniert das ganze auch wunderbar mit 5V.

Software
RCSwitch.zip runterladen und im Arduino/Libaries Verzeichnis entpacken. Der folgende Sketch ist eigentlich selbsterklärend 🙂

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch(11);  // Sender is connected to Pin #11

void setup() {
}

void loop() {
    mySwitch.switchOn(1, 1);         // Switch 1st socket on
    delay(1000);
    mySwitch.switchOff(1, 1);        // Switch 1st socket off
    delay(1000);
}

Updates

  • Die Libary liegt jetzt bei Google Code
  • Steckdosen mit DIP-Switches (in der Regel mt HX2262 oder PT2262 Encoder in der Original Fernbedienung) können auch angesteuert werden (Anleitung).
  • Billiger: Bei Praktiker gibt es 3er Sets mit etwas Glück für 6,99 EUR im Sonderangebot (thx @ Reinhard); ich persönlich habe inzwischen zur Erweiterung die Steckdosen von Pollin (9,99 EUR 3er Set)genommen.
  • Version 0.7 kann jetzt auch Codes einer Fernbedienung empfangen und decodieren
  • Einfacher: Wer nicht löten möchte, sollte sich ein fertiges Modul kaufen. Gibt es ab 5 EUR. Am billigsten inclusive Versand von Händlern aus Hong Kong/China bei eBay (Suche nach „433 Arduino“ oder „RF Link“). Ansonsten hier eine Liste mit Bezugsquellen.
  • Unterstützung von Intertechno Steckdosen (thx @ Holger)


Flattr this