Ardumote

I’m proud to present what I’m currently working on: a Arduino home automation framework and a corresponding webservice. I call it Ardumote, because when I started working on this, all I wanted to have is a simple remote control app for my mobile phone.

the idea

The basic idea is to use a arduino only for operating actors, requesting sensor values and communicate all this stuff to another device. To make things flexible we have ActorModule-, SensorModule- and CommunicationModule classes with a common interface and thus said you simply attach actor objects, sensor objects and communication objects to your Ardumote instance which handles everything in this manner:

//pseudocode
loop {
  if (command available from any communication module) {
    process command / operate specified actor;
  }
  if (value available from any sensor module) {
      send value to all attached communication modules;
  }
}

The communication protocol is kept human readable and very simple. You can find more details at wiki.ardumote.com

The „other device“ could be a application on your computer/smartphone using the (bluetooth) serial communication module, a webapplication on your home or remote webserver or – what I personally focus on – a webservice at dev.ardumote.com using the ethernet IRC module.

What is ready for now:

  • The basic ardumote library using plaintext (recommended for Duemilanove/Uno) or md5 (recommended for Mega) authentification
  • A analog and a digital sensor module -> just read a analog/digital pin in a defined interval, useful for LDR or LM35 temperature sensors for example
  • A analog (PWM) and digital actor module -> just write a analog/digital pin, useful for switching LEDs for example
  • A RCSwitch actor module -> just a wrapper for the RCSwitch library to operate RC power sockets, only works on Arduino Mega
  • A serial communication module -> test & debug in serial monitor, useful for eventually processing or android apps via bluetooth
  • A ethernet IRC communication module -> connects to dev.ardumote.com
  • A ugly basic web interface at dev.ardumote.com giving the ability to register a Ardumote controller, operate actors and log sensor values.
    This is what it looks like:

What I want to have in near future is:

  • Refactoring to minimize the RAM consumption (hope to get the RCSwitch module running on a Duemilanove/Uno)
  • A RCSwitch sensor module -> use a simple remote control
  • Set event based actions at the webservice -> if (LDR < threshold) { switch on lights; }
  • A fancy web interface with the possibility to compose customized fancy remote control interfaces
  • A Android app to use the fancy remote control interfaces 🙂

Quickstart if you want to try the pre alpha (ethernet shield needed):

  • Get yourself the RCSwitch and Time libraries
  • Sign up at dev.ardumote.com, login and add a new Ardumote controller.
  • Get the library
  • Take the example sketch which comes along with the library, change the following lines according to the Ardumote controller you’ve created in step 1 and your local network settings:
    #define ARDUMOTE_CONTROLLER_ID 11
    #define ARDUMOTE_SHARED_SECRET "2d520b8f5ea2cf6113a578f57b45201c"
    
    byte mac[]     = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    byte ip[]      = { 192,168,0,11 };
    

    Btw: As the arduino connects via IRC and keeps being connected, there is no need to setup anything on your router 🙂

  • Plug in a ethernet shield, a LED to pin #5 and pin #6, plug in a analog sensor to analog pin #0
  • Upload and wait until the LED at pin #13 switchs on (which indicates that the Arduino is connected to the IRC server)
  • Now you should be able to control the LEDs at the dev.ardumote.com webinterface

Feel free to share your toughts in the project forum (no registration required)

Svn post-commit auto update hook ohne Rechteprobleme (mal etwas anders)

Ein typisches Szenario im Webdevelopement ist ein Subversion Repository und ein Entwicklungsserver der automatisch geupdated werden soll, sowie ein Entwickler etwas committed. Das hierfür notwendige post-commit hook läuft mit den Rechten des committenden Users, so dass alle neuen Dateien von den anderen nicht mehr geschrieben werden dürfen… Keine Ahnung, wieso es dafür keine elegante Lösung gibt. Im Netz findet man häufig als Workaround ein compiliertes C Programm, welches immer als gleicher User ausgeführt wird. Es geht aber auch anders, und zwar so:

Voraussetzung:
– SVN Repository (hier /var/svn/project/trunk), Zugriff mit svn+ssh://
– Webserver (hier mit DocumentRoot in /var/www/project/dev)
– Eine Gruppe für SVN, der alle Entwickler angehören (hier subversion)

Für das Update benötigen wir einen eigenen User mit SSH Schlüsselpaar und Berechtigungen für das entsprechende DocumentRoot, im post-commit hook loggen wir uns einfach per SSH als Update-User auf die lokale Maschine ein und führen das Update durch. Klingt irgendwie nach „von hinten durch’s Auge“, hat aber sogar den Vorteil, dass das ganze auch dann funktioniert, wenn Repository und Webserver tatsächlich auf unterschiedlichen physikalischen Maschinen laufen.

1. User anlegen und SSH Schlüsselpaar erzeugen (ohne Passphrase)

  adduser updater
  addgroup subversion updater
  su updater
  cd ~
  mkdir .ssh
  chmod 700 .ssh
  ssh-keygen -t rsa

2. Public Key zu den authorisierten SSH Schlüsseln hinzufügen

  cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys2
  chmod 600 ~/.ssh/authorized_keys2

3. Private Key für alle Entwickler (= alle User in der Gruppe subversion) zugänglich machen

  cp ~/.ssh/id_rsa /var/svn/hooks/id_rsa
  chmod 640 /var/svn/hooks/id_rsa_updater
  chown updater:subversion /var/svn/hooks/id_rsa_updater

4. Document Root anlegen und Projekt erstmalig auschecken

  su root
  mkdir /var/www/project/dev
  chown updater /var/www/project/dev

  su updater
  cd /var/www/project/dev
  svn checkout file:///var/svn/project/trunk/ ./

5. post-commit hook anlegen

   mv /var/svn/hooks/post-commit /var/svn/hooks/post-commit.bak
   echo '#!/bin/sh' > /var/svn/hooks/post-commit
   echo 'ssh -i /var/svn/hooks/id_rsa_updater updater@127.0.0.1 svn up /var/www/project/dev' >> /var/svn/hooks/post-commit
   chmod 755 /var/svn/hooks/post-commit

6. Da beim erstmaligen Ausführen der RSA key fingerprint in den known_hosts abgelegt werden muss, muss das post-commit Script zunächst einmalig von jedem Entwickler in der Konsole ausgeführt werden.

  su sui
  /svn/hooks/post-commit

  The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
  RSA key fingerprint is 81:7c:e0:bd:7a:c8:e5:56:0a:c8:7f:95:0c:b1:6a:d0.
  Are you sure you want to continue connecting (yes/no)? yes
  Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts.
  At revision 74.

Fertig 🙂

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

Radarwarner für Android

Leute die morgens mit 55 km/h durch die 30er Zone vor der Schule heizen sind Arschlöcher. Leute die 71km/h auf einer Landstraße fahren, welche ein paar hundert Meter durch eine Ortschaft mit einer Handvoll Einwohnern (was so fragwürdig ist wie die Existenz von Bielefeld, ich habe jedenfalls noch nie ein Lebewesen in Oetzfelde gesehen) führt, wahrscheinlich auch ein bischen. Vor dem Gesetz macht das aber keinen Unterschied, die Strafe beläuft sich auf 103,50 EUR und einen Punkt in Flensburg.

Hey, 16 Jahre unfallfrei (vom Außenspiegel und der Heckschürze beim Parken mal abgesehen) und zwei oder drei kleine Tickets wegen kleinerer Geschwindigkeitsüberschreitungen – ich bin definitiv kein Verkehrsrowdy. Darüber hinaus bin ich einsichtig und geständig – wobei ich ehrlich gesagt auch kurz überlegt habe, trotz eindeutiger Beweislage zunächst einmal alles in guter Guttenberg Manier zu bestreiten. Ich akzeptiere sogar anstandslos meinen ersten Punkt in Flensburg, aber gleich 100 Tacken? Zumal das mit einem km/h weniger gerade mal 35,- ohne Punkt gekostet hätte?! Fuck you!

Mein neuer, unentbehrlicher Begleiter auf langen Autofahrten ist jetzt jedenfalls Blitzer.de. Der warnt nicht nur vor festen Blitzern, sondern dank leichter Meldemöglichkeit und aktiver Community auch vor mobilen Radarfallen. Fazit: absolut empfehlenswert.


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