Samstag, 15. Februar 2014

nrf24l01+ mit Arduino und Raspberry Pi

Bei der Suche nach dem richtigen Funkstandard zur Kommunikation zwischen Arduinos, Raspberrys oder auch "nackten" Mikrocontrollern wie einem ATtiny trifft man auf viele Möglichkeiten. Vom mittlerweile überladenen 433 MHz-Band über das per Gesetz weniger vermüllte 868 MHz-Band bis hin zum etablierten, aber wegen Bluetooth und W-Lan auch schon stark belegten 2,4 GHz-Band ist alles möglich.

Ohne genauer auf die Vor- und Nachteile der einzelnen Standards einzugehen fasse ich hier meine Erfahrungen mit einem Modul für den 2,4 GHz-Funk zusammen: Dem Nordic nRF24L01+ Funkmodul.

Das in der Szene recht weit verbreitete Modul ist über diverse Auktionshäuser sehr kostengünstig zu erwerben (~1,50 € pro Stück). Wem das zu heikel ist, der findet es zu einem höheren Preis auch in deutschen Shops. Die genauen Einzelheiten dieses Moduls findet man zu genüge auf anderen Websiten gelistet, ich beschränke mich hier auf eine kurze Liste:
  • 2,4 GHz Basisfrequenz, 125 Kanäle zur "Feinjustierung" zur Auswahl
  • 3,3 V Betriebsspannung (hat allerdings scheinbar einen Spannungsregler, 5 V sollten also ebenfalls funktionieren)
  • Datenraten von 2 MBPS bis runter auf 250 KBPS. Dabei gilt: Geringere Datenrate bringt größere Reichweite.
  • Ansteuerung über SPI
  • Transceiver, d.h. ein Gerät für Senden und Empfangen
  • AutoAck-Funktion, Ack steht für Acknowledge, d.h. jede gesendete Nachricht wird auf Empfang geprüft. Somit kann sichergestellt werden, dass/ob der Empfänger die Nachricht wirklich empfangen hat. Sehr hilfreiche Funktion!
  • Nutzbar mit Arduino, Raspberry Pi und ATtiny
Vor allem die letzte Aussage ist interessant: Ich benutze zum testen und entwickeln von Projekten immer Arduinos, welche ich dann soweit möglich auf ATtinys, am liebsten den ATtiny 84A, runterschraube. Allgemein würde ich die RF24-Library empfehlen. Sie läuft mit Arduino, dem Raspberry unter Verwendung von C/C++ und vor allem auch in Verwendung mit Python. Weiterhin ist es möglich, sie mit dem ATtiny 84A zu nutzen. Bei diesem muss jedoch getrickst werden, um die SPI-Schnittstelle nutzen zu können.

1. RF24 über die Arduino IDE auf einem ATtiny 84A nutzen

Die RF24-Lib lässt sich eigentlich ohne Probleme mit einem ATtiny nutzen (natürlich in Verbindung mit der Arduino IDE und cores für die tinys), das einzige Problem stellt die original SPI-Library dar. Diese SPI-Library kommt nicht mit dem ATtiny-Core klar. Wer hätte das gedacht. Hier muss etwas korrigiert werden. Dazu sollte man die gesamte IDE schließen. 
Nun holt man sich aus dem Archiv https://github.com/jscrane/SPI die korrigierten Codes und ersetzt damit die originale SPI-Library. Dann sollte das Kompilieren ohne weiteres funktionieren.

2. RF24 auf dem Raspberry Pi mit C/C++

Hier nutze ich folgendes Archiv: https://github.com/ahuillet/RF24
Auffällig ist, dass in dem entscheidenden Ordner librf24-rpi zwei weitere Ordner lauern. Einer davon ist mit dem Zusatz -bcm benannt, was für den Baustein des Raspberry Pi steht, welcher unter anderem für die GPIO-Pins und damit für SPI verantworlich ist (Broadcom bcm2835). Darin steckt eine Lib, die eigentlich identisch ist zu der ohne bcm. Lediglich die Art und Weise wie die SPI-Schnittstelle angesprochen wird ist anders, genauer unterscheiden sich die libs nur im verwendeten Treiber. Man nennt die bcm-Variante auch Hardware-SPI. Ich empfehle hier für C/C++ erstmal die bcm-Variante zu testen, die hat bei mir super funktioniert.

Gleichzeitig kann man sich auch noch ans Software-SPI heran wagen (also die lib ohne bcm), insbesondere, wenn man später Python statt C/C++ nutzen möchte. Zuvor ist zur Einrichtung des Software-SPI's folgendes Tutorial hilfreich: 
http://www.brianhensley.net/2012/07/getting-spi-working-on-raspberry-pi.html

3. RF24 auf dem Raspberry Pi mit Python

Hier empfehle ich folgendes Archiv:
https://github.com/jonathongrigg/RF24/tree/master/raspberrypi/pyRF24


Hat man im vorherigen Schritt die Software-SPI-Variante von RF24 auf dem Pi zum laufen gebracht, lässt sich diese Python-lib direkt installieren. Sie wrappt dabei quasi "nur" die C++ Library. Wichtig ist dabei, dass es sich um eine Lib für Python-Versionen >= 3 handelt! 
Ist alles richtig installiert (gemäß der Anleitung auf der Website), lässt sich die lib direkt in Python einbinden und nutzen wie bereits mit dem Arduino.
 
Ich bin mit dem Autor in Kontakt, unter anderem um die lib auch für den bcm-Treiber fit zu machen und um kleinere Bugs zu fixen. So wird beispielsweise ein 0x00 beim python-seitigen Empfang durch den C-Wrapper fälschlicherweise als das C-typische Abbruchzeichen eines Strings interpretiert und der Rest der Nachricht verschwindet im Äther...Dumm nur, wenn man eigentlich keinen String sondern ein byte-array verschickt hatte und nach der 0x00 noch was kommen sollte...

 

Mittwoch, 7. August 2013

PIR Sensor die Zweite

Ein neuer PIR-Sensor ist soeben eingetroffen, genauer gesagt fünf davon. Er bietet bei weitem nicht so viele Funktionen wie der bereits vorgestellte ePIR-Sensor, aber allein schon der Preis von 2,50€ pro Stück (im 5er-Pack) macht ihn sehr interessant.
Der besagte Sensor. Deutlich zu erkennen sind die
zwei Potentiometer (orange) und der Jumper in
der oberen linken Ecke.
Zunächst einmal zu den Eigenschaften. Laut Platine heißt das Modul DYP-ME003. Laut einem inoffiziellen Datenblatt (der Sensor kommt as-it-is, also ohne alles), welches Google unter anderem ausspuckt, sind die Features überschaubar: Zwei Potentiometer zum Regeln von Empfindlichkeit und Haltedauer und ein Jumper. Die Empfindlichkeit wird hier offenbar mit Reichweite gleichgesetzt, welche maximal 7 Meter betragen soll. Die Haltedauer, also wie lange eine erkannte Bewegung signalisiert wird, lässt sich zwischen 5s und 300s angeben. Der Ausgang ist dabei active high, d.h. bei einer Haltedauer von 10s schaltet das Modul bei einer erkannten Bewegung den Ausgang für 10s auf high. Daneben gibt es dann noch die zwei Pins für VCC und GND.
Der Jumper setzt den Trigger-Modus (single trigger / repeatable trigger), welcher scheinbar wie folgt funktioniert: Nach einer erkannten Bewegung wechselt der Output für die eingestellte Haltedauer von low auf high. Im single trigger Modus fällt der Pegel danach wieder auf low und der Sesor wird für eine so genannte blocking time von 2.5s deaktiviert, innerhalb dieser Zeit kann er also keine erneute Bewegung erkennen. 
Im repeatable trigger Modus schaut der Sensor, ob nach Ablauf der Haltedauer weiterhin eine Bewegung erkannt wird. Ist dies der Fall, wird der Pegel auf high gehalten, bis die Bewegung nicht mehr erkannt wird. Danach greift wieder die blocking time.
Laut Spezifikation soll auch diese blocking time einstellbar sein. Jedoch befinden sich wie bereits gesagt nur zwei Potentiometer am Sensor. Weiter getestet habe ich diese Feature nicht.

In einem kleinen Vergleich läuft dieser Sensor wesentlich genauer als der ePIR-Sensor. Des weiteren ist er wesentlich einfacher zu konfigurieren, bietet dafür aber auch einfach weniger Features. Jedem, der die beim ePIR-Sensor genannten Features nicht benötigt, würde ich zu dieser preisgünstigen Variante raten!

Freitag, 19. Juli 2013

ePIR Bewegungsmelder

Der erste Sensor, den ich euch hier genauer vorstelle, ist folgender Bewegungsensor:
Zilog ePIR™  Motion Detection Zdots® SBC

Der Sensor wirbt mit einem integrierten Chip, welcher euch die Daten vorfiltert und so die Fehlalarmrate reduzieren soll. Außerdem könnt ihr den Sensor damit sehr individuell auf eure Bedürfnisse zuschneiden.

Es gibt zwei Möglichkeiten den Sensor mit seinen 8 Pins (davon 1x VCC, 2x GND) anzusteuern:
  • Hardware-Interface: Hier steuert ihr den direkt über Spannungen, die ihr an die GPIO Pins per Spannungsteiler anlegen müsst. Ein weiterer Pin dient als active-LOW Pin, welcher bei erkannter Bewegung auf HIGH wechselt.
  • Serial-Interface: Hier wird der Chip über eine serielle Verbindung angesprochen (UART (*)). Nur in diesem Modus können sämtliche Features des Sensors genutzt werden.
    Besonders erwähnenswert ist hierbei der Extended-Range-Modus, bei welchem der Empfindlichkeitsbereich auf einen 5m x 5m großen Bereich erweitert wird. Da dieser Modus über Hardware-Interface nicht konfigurierbar ist, spricht allein schon diese Reichweitensteigerung gegenüber dem normalen 3m x 3m Bereich für die Nutzung des seriellen Zugangs.
    In diesem Modus wird der aktuelle Status gepollt, d.h. ihr sendet ein Steuerzeichen, woraufhin der Sensor euch antwortet, ob er eine Bewegung registriert hat. Praktisch ist hierbei die Möglichkeit, eine Hold Duration zu setzen. Diese gibt dann an, wie lange der Sensor bei erkannter Bewegung den Alarmstatus aufrecht erhalten soll. Eine Möglichkeit wäre beispielsweise eine Hold Duration von 35s. Hier würde es dann ausreichen, den Sensorstatus nur alle 30s abzufragen.

    Weitere Features sind:
    • Frequency Response Setting, eine Art Unterscheidung zwischen vertikal-orientierten Objekten (Menschen) und horizontal-orientieren Objekten (Haustiere). Aktiviert man diese Option, werden horizontal-orientierte Objekte weniger stark beachtet um Fehlalarm zu vermeiden. Wie gut dieses Feature funktioniert kann ich nicht sagen, sicher ist dass man es für höchste Empfindlichkeit deaktiviert lassen sollte.
    • Pulse Count, kann auf 1 oder 2 gesetzt werden. Gibt die Anzahl der Ereignisse an, welche der Sensor erkennen muss, damit eine Bewegung gemeldet wird. Auch hier gilt, ein Wert von 1 führt zu einer höheren Empfindlichkeit, aber wohl auch zu einer höheren Wahrscheinlichkeit für einen Fehlalarm.
    • Motion Direction, hierbei soll der Sensor die Richtung der Bewegung erkennen (von links nach rechts oder umgekehrt) und eine Sorte von Bewegungen ignorieren können. Auch dieses Feature ist recht nett aber doch sehr speziell, sodass ich es nicht weiter getestet habe.
    • Sensitivity, die wohl wichtigste Einstellung ist die Empfindlichkeit selbst. Diese kann in einem Bereich von 0 (maximale Empfindlichkeit) bis 255 (minimale Empfindlichkeit) geregelt werden. Eine geringere Empfindlichkeit verringert laut Datenblatt auch den räumlichen Empfindlichkeitsbereich. 

Ich selbst teste den Sensor aktuell im Serial-Interface Modus mit einem Raspberry Pi unter Python als Alarmanlage. 


Weiterhin hat sich bereits jemand die Mühe gemacht, den Sensor intensiv zu testen und mit einem weiteren bekannten PIR-Sensor zu vergleichen. Auf jeden Fall einen Blick wert:
http://www.youtube.com/watch?v=xZGYn-oipQc

(*)Damit eure UART-Schnittstelle auch funktioniert, rate ich euch zu folgender Anleitung:
http://elinux.org/RPi_Serial_Connection#Preventing_Linux_using_the_serial_port

Mittwoch, 3. Juli 2013

Arduino Micro und der ISP Sketch

Ich persönlich verwende ja den Arduino Micro, allein schon wegen seinem praktischen Breadboard-Format.
Die meisten Beispiele und Howto's werden für den Arduino Uno konzipiert, in 99% der Fälle lassen sich diese aber auch 1:1 auf dem Micro ausführen.

Der ISP Sketch (ArduinoISP), welcher den Arduino in einen ISP verwandelt, zählt leider zu dem einen Prozent, bei welchem eine Anpassung notwendig ist.

Folgende Änderungen sind nötig, um den Sketch auf einem Micro so zum laufen zu bringen, um damit dann auch tatsächlich andere µC's flashen zu können:

  1. Setzen eines Parameters in der Preferences (ggf. neu anlegen):
    build.verbose=true
    upload.verbose=true

    Damit aktiviert ihr ein detailiertes Log!
    Edit: Diese Optionen bekommt ihr auch weniger umständlich über die IDE: Datei -> Einstellungen -> Ausführliche Ausgaben anzeigen während -> Beide Häkchen setzen.
  2. Beim Starten des Upload-Vorgangs wird der Sketch für den eingstellten µC kompiliert, danach per avrdude geflasht. Dank verbose=true wird der avrdude-Befehl in der Konsole geloggt, bei mir sieht das in etwa so aus:
    avrdude -CC:avrdude.conf -v -v -v -v -pattiny84 -carduino -P\\.\COM20 -b19200 -Uflash:w:[...].hex:i
    Hier muss der Programmer (Parameter c bei avrdude) auf arduino gestellt sein:
    -carduino
    Häufige Fehlerquelle ist ein -cstk500v1 o.Ä. an dieser Stelle. Diesen Fehler kann man abstellen, indem man in der boards.txt der Core-Dateien den Paramter upload.using des entsprechenden µC's ändert.
  3. ICSP nutzen! Die ersten paar Kommentarzeilen des ArduinoISP Sketch geben eine Anleitung, in welche man die Pins 10-13 nutzen sollt, um eine Verbindung mit dem µC herzustellen. Dies gilt nicht im Falle des Micro, hier habt ihr eigene Pins für MISO, MOSI und SCK. Diese verbindet man alle mit den entsprechenden Pins des µC. Den RESET-Pin des µC verbindet man mit Pin 10 des Micro und ändert den Sketch, indem man die Zeile
    #define RESET     SS
    ändert in
    #define RESET     10

Genaueres findet man in einem Thread des Arduino Forums:

Freitag, 28. Juni 2013

Grove Dust Sensor

In den letzten Tagen hatte ich Zeit, den Grove Dust Sensor zu testen. Dieser preisgünstige Staubsensor sollte zunächst dazu dienen, eine qualitative Aussage zur Staubbelastung in einem meiner Räume zu geben. 

Natürlich habe ich auch schon an eine quantitative Auswertung gedacht, jedoch ist bereits die qualitative Auswertung einem scheinbar defekten Sensor zum Opfer gefallen.

Zunächst zum Anschluss, dieser gestaltet sich eigentlich recht einfach. VCC (5V) und GND anschließen und den Datenanschluss an einen digitalen Pin des Arduino hängen (Von den fünf sichtbaren Anschlüssen sind nur drei relevant, die anderen zwei sind zunächst nebensächlich). Nach kurzer Aufwärmphase misst man nun einfach über eine Zeit von 30 Sekunden den Pegel, welcher am Pin anliegt. Die gemessene Staubkonzentration ist im LOW-Anteil des Signals kodiert, genauer im Verhältnis zwischen der Zeit, in welcher der Pegel von Sensor auf LOW gezogen wird zur gesamten Zeit, also zu den 30 Sekunden.

Laut Beispielsketch eignet sich dazu die Arduino-eigene pulseIn-Funktion.
Gesagt getan: Sensor angeschlossen, Sketch geflashed und siehe da, nach 30 Sekunden ein erster Wert in der seriellen Konsole. Als angehender Naturwissenschaftler warte ich natürlich den zweiten Wert und dritten Wert ab in der Hoffnung, dass diese den ersten Wert bestätigen.
Doch nun kommen scheinbar keine LOW-Phasen mehr an, das Verhältniss sinkt auf 0. Und das für die nächsten 10 Werte. Dazwischen kommt dann ab und an mal wieder ein nicht verschwindender Wert, welcher allerdings absolut nichts mit dem ersten Wert zu tun hat - ich vermute Störungen.
Ein angeschlossener Logikanalysator bestätigt mir, dass kein LOW-Pegel mehr ausgespuckt wird.

Ein Blick in den Sketch zeigt, dass der Sensor an Pin 8 des Arduino, genauer des Arduino Uno, angeschlossen werden sollte, da nur dieser "sampling" unterstützt (http://www.seeedstudio.com/wiki/Grove_-_Dust_Sensor). 
Pin 8 ist mit dem ICP1-Pin des ATMega verbunden. Dieser Input Capture Pin ist auch in der Tat perfekt für die notwendige Messmethode geeignet. Da ich standardmäßig mit einem Arduino Micro experimentiere, habe ich mir gleich einen Uno mit Grove Shield geschnappt und den Sensor angeschlossen. 
Und siehe da, es erscheinen hintereinander mehrere von 0 verschiedene Werte, zwar sehr schwankend, aber der Sensor hat ja auch eine gewisse Aufwärmphase. Doch die Freude hält nur kurz, auch hier ist nach einigen Werten Schluss, es kommen nur noch 0'en. 

Fazit: Der Sensor wird umgetauscht, eventuell war er einfach defekt. Gleichzeitig bestelle ich mir noch den Sharp's GP2Y1010AU0F. Ich werde natürlich wieder berichten! Sollte das mit dem Grove dann klappen, schaue ich mir auch mal noch die anderen zwei Pins an...

Freitag, 21. Juni 2013

Hallo, Welt!

Hallo,


dieser Blog richtet sich hauptsächlich an Leute, die Spaß daran haben, DIY-Projekte auf Basis von Arduino, Raspberry Pi und Co umzusetzen.

Da ich viele Sensoren und Aktoren einfach mal zum testen kaufe, dachte ich mir, dass es eventuell ganz sinnvoll ist, die damit gemachten Erfahrungen und Tricks zu veröffentlichen!