Login
Register
Forum
Kontakt
Bitmania
2014-09-13 18:01
by bitman
RFM12 Mehrzweck Funknetz - Generation 2
RFM12 Network

Dies ist die neue Version meines Mehrzweck-Funksystem auf Basis des RFM12-Funkmoduls.





Ich habe einige Fehler aus der Software-Version 1 auf dem ATMega328P behoben und einige Erweiterungen im Funktionsumfang vorgenommen.
Eine wichtige Änderung ist das für periodische Aktionen nicht mehr die RFM12 wake-up Funktion verwedet wird, sondern der AVR-Watchdog Interrupt.
Der RFM12-Wake-Up hat sich jeweils immer nach einigen Tagen als unzuverlässig erwiesen.


Die Ausgangssituation
Ich habe bereits verschiedene Funksysteme im Einsatz, die aber alle nicht recht zusammenpassen.
Dabei gibt es einige Probleme die mir nicht gefallen, die ich damit aber nicht abstellen kann:

- Funk-Wetterstation mit ihren Innen- und Aussensensoren (868MHz) mit einem eigenen Empfänger.
CON: Die Anbindung ist ineffizient, ich weis nie warum ich einen Sensor nicht empfange (Akku leer oder schlechte Funkverbindung)
- Stromzählersensor mit einem 868MHz CUL als Empfänger, Auswertung per FHEM
CON: einzig für diesen Sensor habe ich hier ein FHEM am start, das hätte ich gerne weg.
- ein paar Funksteckdosen mit einem 434MHz CUL als Empfänger, Steuerung per FHEM
Con: In jedem Baumarkt gibts es die Fernsteuerungen um bei mir Funksteckdosen ein-ausschalten


Es muß also etwas neues her:

Mein neues Konzept soll es ermöglichen selber Funk-Nodes zu bauen, damit man nicht auf fertiges angewiesen ist.
Eine Funk-Node kann z.B. ein Temperatur-Sensor, ein Schalter, Funksteckdose oder was auch immer sein.
Die Nodes sollen sich untereinander verbinden können.
Eine oder mehrere beliebige Nodes sollen als Zugang zum Netz per seriellem Interface genutzt werden können.
Das Protokoll soll flexibel und für Erweiterungen offen sein.
Auch Kombinationen sollen möglich sein (z.B. temperaturmessender-Fenster-Offen-Bewegunsmelder-Sensor)



Eigenschaften:
+ Bidirektionale (jede Node kann senden und empfangen)
+ Verschlüsselte Datenübertragung (XTEA 128 Bit Verschlüsselung)
+ Schlüsseländerungen per Funk
+ Receiver-Parameter anpassung per Funk (Node fällt auf Default RX Config zurück wenn sie durch Fehlkonfiguration nichts mehr empfängt)
+ Gateway-Funktion (Relaisstation, für abgelegene Nodes)
+ Sleep-Mode für Batteriebetrieb
+ Batteriestand-Überwachung
+ Gegensteuern bei Batterieüberladung durch Solarzelle
+ Jeder Node kann eine eigene 16-bit-ID zugewiesen werden (bis zu 65534 IDs im Netz)
+ Konfiguration der Node per Funk (keine DIP-Schalter in der Node hinter der Schrankwand)


Anwendungsbeispiele:
+ Wetterstation Sensor Temperatur (DHT22 AM2302 RHT03)
+ Wetterstation Sensor Luftfeuchte (DHT22 AM2302 RHT03)
+ Fensterkontakt / Türkontakt: Externer Schalter dessen Betätigung (Öffnen und Schließen) jeweils signalisiert wird
~ 3 weitere I-O-Ports die aus der Ferne als Ausgang oder Eingang, An/Aus geschaltet werden bzw. deren Zustand ausgelesen werden kann.
~ Funksteckdose
- Wetterstation Sensor Luftdruck (GY-65 BMP085)
+ Bewegungsmelder
- geplant: Rückbestätigung von Funkpaketen
- geplant: Stromzähler-Sensor
- geplant: Wasserzähler-Sensor
- geplant: Gaszähler-Sensor
- geplant: Wassermelder (z.B. im Keller bei Überschwemmungen)

+ implementiert
~ halbwegs
- noch nicht implementiert


Hier ein Beipiel einer Node die u.a. den Füllstand der Wassertonne erfasst:








Jede Node kann man mit einem USB-Serial-Adapter an einen Rechner anschließen und dann z.B. mit einem Terminalprogramm mit dem Funknetz interagieren.
Also z.B. Commands in das Funk-Netz an andere Nodes senden oder Informationen aus dem Netz herauslesen.
Die Stromversorgung einer Node läuft entweder über USB-Verbindung, ein Netzteil, Batterie oder Batterie mit Solarzellen-Unterstützung.
In meinem Anwendungsfall werde ich eine Node an einen Server anschließen der z.B. Wetterdaten auswertet und andere Aktionen auslösen kann.





Hardware und Software:

Zum Einsatz kommt ein Atmega328P







Eagle-Layoutfiles: file
Die Firmware Stand heute: file



Die Standard-Stromversorgung besteht aus drei AA Zellen. ich verwende Eneloop Zellen.
Einige Sensoren habe ich noch mit Solarzellen versehen, die den Akku nachladen.
Die Schaltung dazu ist eine einfache Schottky Diode, welche das Entladen des Akkus über die Solarzelle bei Dunkelheit verhindert





Damit bei vollen Akku die 3 AA Zellen nicht überladen werden habe ich die vBattLimit-Funktion eingebaut.
Man kann einen Spannungs-Schwellwert einstellen ab dem eine Node trotz Sleep Mode nicht in den Power-Down Mode geht.
Oder anders ausgedrückt: wenn dieser Schwellwert überschritten ist verbraucht die Node die überschüssige Energie direkt durch höheren Stromverbrauch.

Eine Langzeit-Messung zeigt hier ein Bespiel mit der Ziel-Akku-Spannung 4000 mV







Netz-Beispiel:

Node-A ist in diesem Beispiel mit einem Computer über ein serielles Interface verbunden
Node-B ein Sensor (und Gateway für die abgelegene Node-D)
Node-C ein Sensor
Node-D ein weiter entfernter Sensor, erreicht Node-A nur über Gateway-Node-B (und umgekehrt)




Eine Node kann (sofern sie nicht im Sleep-Mode ist) angefunkt, konfiguriert oder von einer anderen Node als Relaisstation verwendet werden.

Die Relais-Funktion verlängert die Reichweite einer anderen Node die ihr Ziel nicht direkt aufgrund ungünstiger Lage oder Entfernung nicht direkt erreichen kann.


Jeder Node kann eine 16 bit Node-ID zugewiesen werden, damit sind 65536 IDs im Netz möglich
Nach dem Zusammenbauen und Flashen reagiert eine Node auf die ID ffff.


0x0000	das gesamte Netz, nicht einer Node zu zuweisen
::
0xffff default ID nach dem Firmware flashen



Serielles Interface

Man kann einen PC mit einem Terminalprogramm über einen USB-Seriell-Wandler mit einer Node verbinden.
Die so verbundene Node gibt dann Informationen und Meldungen aus dem Funknetz an den Rechenr weiter.

Hier sieht man Meldungen
2001_0000_0000_210d_01001100_02: 01fd 0058 0000 549 213 3965 4000 0000 0000 01a4 04a2 2001
aaaa_0000_0000_171f_01001000_02: 6bc1 02bd 0000 600 201 0828 4000 0000 0000 01a4 04a2 2001
ffff_0000_0000_0093_01001000_ff: 06c0 0022 0000 999 999 3187 4000 0000 0000 01a4 04a2 2001
2000_0000_0000_1ff6_01000100_02: 1b6f 0186 0000 210 291 4003 4000 0007 0000 01a4 04a2 2001
1000_0000_0000_1dcc_01000100_02: 09d7 00f1 0000 601 203 3815 3500 0000 0000 01a4 04a2 2001
1010_0000_0000_269f_01000100_02: 1ccb 0235 0000 546 225 3576 3500 0000 0000 01a4 04a2 2001



Interpretation der Meldungen:

1010_0000_0000_269f_01000100_02: 1ccb 0235 0000 546 225 3576 3500 0000 0000 01a4 04a2 2001


1010             Node ID
0000 Destination of the messege (0000 is no particular destination)
0000 Gateway to be used (0000 if no gateway required)
269f TX Paket-Sequence-Nr
01000100 Statusinformationen der Node
00000000
||||||||
|||||||0 =
|||||||1 =
||||||0 = debug mode off
||||||1 = debug mode on
|||||0 = sleep mode off
|||||1 = sleep mode on
||||1 = node would go to power down mode if sleep was set
||||0 = node won't go to power down mode, even if sleep was set, because vbatt is higher than eeVBattLimit
|||0 =
|||1 =
||0 =
||1 =
|0 =
|1 = periodic trigger
0 =
1 = PCINT trigger
02 message type

1ccb RX Paket-Sequence-Nr
0235 Checksum Error Counter
0000 RX busy counter (number of times the node probed for 868MHz to be idle)
546 54.6 % humidity (Luftfeuchte)
225 22.5°C temperature
3576 vbatt (Spannungsversorgung der Node)
3500 vbl (Spannungs Limit in mV, wenn vbl > vbatt geht die Node trotz Sleep Mode nicht in Power Down Mode)
0000 PCInt Counter 1
0000 PCInt Counter 2
01a4 remaining free SRAM of Node
04a2 current RX configuration
2001 software version



Gateway-Funktion:
Jede Node kann in einem gesendeten Paket angeben ob das Paket von einer anderen Node als Gateway wiederholt werden soll (Relaisstation)
Dazu kann man in jeder Node eine Gateway-Liste definieren.

Beispiel:

Die Node 1000 soll alle Pakete an Ziel Node 2000 mit der Info Gateway 3000 senden.
Wenn eine Node mit ID 3000 diese Pakete empfängt, wird sie diese erneut versenden.

set node 1000 gwlist 2000 3000



Eine Erklärung der Commands findet sich weiter unten.



Sleep-Funktion:
Damit man Nodes mit Batterien betreiben kann habe ich eine Sleep-Funktion eingebaut.
Das heisst man kann eine Node in den Schlaf versetzen, woraufhin sie nur noch alle x Sekunden aufwacht, einen Status an ID 0000 (das Netz) versendet und sich wieder schlafen legt.
Die Zeitspanne ist konfigurierbar. Im 868MHz Band gilt es die Belegungsvorschriften zu beachten!

Wenn man nun eine Node erreichen möchte muß man sie zuvor wieder aufwecken.
Dazu kann man einer Master-Node sagen welche Sattelit-Node sich nach Versenden der Statusmeldung nicht wieder schlafen legen soll:

Beispiel: wenn sich Node 2000 meldet, soll sie wach bleiben

set awake 2000



MML-Commands:

Über eine serielle Verbindung können Commands an eine direkt angeschlossene Node geschickt werden.
Die Node prüft weder die Syntax noch gibt sie Fehlermeldungen bei falscher Syntax zurück.
Den Platz im Microcontroller für diese Checks habe ich mir gespart.

Die Commands unterliegen der Struktur: Verb Object Component Attribute

Verb [Object] Component Attribute
set id ____
set node ____ id ____
set node ____ gwlist ____ ____


Das 'Object' ist optional, wenn weggelassen dann wirkt sich das Command auf die Node selber aus an die man per Serial-Interface angeschlossen ist.
NodeIDs (____) sind immer 4stellig hexadezimal anzugeben.


Bisher Implementierte Commands:

Lokal ('diese Node' bedeutet: die per USB angeschlossene Node):


reset
set id ____
set key ________________
set int ____ (result is interval times 8sec)
set rxc ____ (RX control setting)
set vbl ____ (vbatt limit, if vbatt is larger than vbl the node won't fall into power save)
set gwlist ____ ____
set master
set sleep
set debug
set awake ____


Konfiguration von entfernten Nodes per Funk:
set node ____ id ____
set node ____ gwlist ____ ____
set node ____ sleep
set node ____ key ________________
set node ____ int ____
set node ____ rxc ____
set node ____ vbl ____
set node ____ reset

get key
get gwlist
get awake
get node ____ gwlist
get node ____ stat

del awake ____
del gwlist ____
del node ____ gwlist ____



Funk-Protokoll:

Die Daten werden mit einem 128bit Schlüssel XTEA chiffriert.
Es gibte verschiedene Message Types:
orig	dest	gateway	txseq	node	msg	purpose
id id id nr status type
| | | | | | | | | |
0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
0000 0000 0000 0000 00 00 RF : get node ____ stat
0000 0000 0000 0000 00 02 SendStatus()
0000 0000 0000 0000 00 03
0000 0000 0000 0000 00 04 RF : set node ____ id ____
0000 0000 0000 0000 00 05
0000 0000 0000 0000 00 06 RF : set node ____ gwlist ____ ____
0000 0000 0000 0000 00 07
0000 0000 0000 0000 00 0a RF : set node ____ pc_ off
0000 0000 0000 0000 00 0a RF : set node ____ pc_ on
0000 0000 0000 0000 00 0b RF : stay awake to ____
0000 0000 0000 0000 00
0000 0000 0000 0000 00 0c RF : set node ____ sleep
0000 0000 0000 0000 00 0d
0000 0000 0000 0000 00 0e RF : get node ____ gwlist
0000 0000 0000 0000 00 0f
0000 0000 0000 0000 00 10 RF : PIN change trigger
0000 0000 0000 0000 00
0000 0000 0000 0000 00 12 response for command get node ____ gwlist
0000 0000 0000 0000 00
0000 0000 0000 0000 00 14 RF : del node ____ gwlist ____
0000 0000 0000 0000 00
0000 0000 0000 0000 00 20 RF : set node ____ key ________________
0000 0000 0000 0000 00
0000 0000 0000 0000 00 22 RF : set node ____ int ____
0000 0000 0000 0000 00
0000 0000 0000 0000 00 24 RF : set node ____ reset
0000 0000 0000 0000 00
0000 0000 0000 0000 00 26 multi purpose info message
0000 0000 0000 0000 00
0000 0000 0000 0000 00 30 RF : set node ____ vbl ____
0000 0000 0000 0000 00
0000 0000 0000 0000 00 32 RF : set node ____ rxc ____
0000 0000 0000 0000 00
: : : : :
: : : : :
: : : : :
0000 0000 0000 0000 00 ff local serial message