Senden von Daten über stabile Funkverbindung (433MHz o.ä.)

mwyraz:
Gibt es sinnvolle (und nicht zu teure) Alternativen?

Google mal nach NRF24L01, die gibts als Fertigmodule für kleine Geld, alternativ auch mit "richtigen" Antennen. Die kommen im Netz gut weg. Selbst testen konnte ich die noch nicht, meine schippern gerade noch nach Europa.

Alternativen wären RFM12.

Durch wie viele Wände sowas geht hängt natürlich nicht nur von deren Anzahl, sondern eher von der Beschaffenheit ab. Ne gute alte Ziegelwand dämpft da deutlich weniger als ne Stahlbeton-Wand mit reichlich Armierung.

Derzeit habe ich für die Thermometer und Funksteckdosen diese da im Einsatz:

http://www.watterott.com/de/RF-Link-Sender-434MHz
http://www.watterott.com/de/RF-Link-2400bps-Empfaenger-434MHz

Der Sender schafft es, alle Steckdosen im und außer Haus zu erreichen. Der Empfäger empfängt vom Funkthermometer kaum was, sobald es etwas weiter weg ist (weniger als das original Thermometer). Ich muss mal testen, ob das an der Hardware oder der Modulation liegt.

Hab mal nach dem NRF24L01 geschaut, der liegt bei Watterot bei ~17€ + Antenne. Wäre sicher noch im Rahmen, ist aber vielleicht ein wenig überdimmensioniert für den Einsatzzweck?

Einen RFM12 könnte ich ja mal mit bestellen. Wie bekommt man sowas auf ein Breadboard? Wie sind da die zu erwartenden Reichweiten?

mwyraz:
Hab mal nach dem NRF24L01 geschaut, der liegt bei Watterot bei ~17€ + Antenne. Wäre sicher noch im Rahmen, ist aber vielleicht ein wenig überdimmensioniert für den Einsatzzweck?

Guck mal in der eBucht beim freundlichen Chinamann, 2 Stück mit Print-Antenne 4 Dollar incl. Versand. Optional im Zehnerpack für 10 Euro. Ok, dauert dann halt 3 Wochen...

Bei nem deutschen eBay-Händler gibts den Doppelpack immerhin für fünf fuffzich incl. Porto.

mwyraz:
Einen RFM12 könnte ich ja mal mit bestellen. Wie bekommt man sowas auf ein Breadboard? Wie sind da die zu erwartenden Reichweiten?

http://blog.sui.li/2011/06/28/rfm01-rfm12-aufs-breadboard/

Alternativ hat JeeLabs fertige Adapterboards.

Ich habe heute meinen 2. Arduino bekommen und mal mit den einfachen 433MHz Modulen von Watterott getestet. Als Lib habe ich VirtualWire genommen, dort gibt es eine Fehlererkennung und die Baud-Rate lässt sich einstellen.
Den einen Arduino habe ich im Schuppen platziert, dieser sendet alle eingehenden 1-Wire-Messwerte raus mit 1200 Baud.

Den anderen habe ich im Haus aufgebaut, der empfängt die Date und sendet sie via UDP-Broadcast ins Netz.

Trotz geringer Entfernung (~10m) und nur 2 Wänden (1x Holz, 1x Stein) kommt recht wenig an. Könnte es an meinem Empfänger liegen (kaputt, schlecht eingestellt)? Ich habe an Sender und Empfänger passende Drähte (ich glaube 13 oder 17 cm, hatte ich mal nachgelesen) als Antenne.

Im Zweifelsfall immer erst die Antenne optimieren. Und zwar auf beiden Seiten, also Empfänger und Sender. List of Antennas (Antenna Types)

Im Moment benutzt Du l/4 Antennen. Was spricht gegen l/2 Antennen order l Antennen? Wenn das fest montiert wird ist die Antennengröße doch nicht so schlimm, oder?

Ansonsten: RIchtantennen sind immer gut :wink: Richtantenne für 433MHz Ersatzteilversand - Reparatur

Das habe ich eben noch gefunden: http://www.dj5am.de/ant70cm/70cmant.html. Rothammels Antennenbuch wird immer wieder gerne zitiert: http://www.amazon.de/gp/product/388692033X/ref=as_li_ss_tl?ie=UTF8&camp=1638&creative=19454&creativeASIN=388692033X&linkCode=as2&tag=wwwblinkenlig-21.

Wenn Du Geld sparen willst: es gibt nicht nur Amazon, es gibt auch - immer noch - Bibliotheken :wink:

Was mich stutzig macht: ich habe mit dem Empfänger schon experimentiert, um die Daten von Funkthermometern einzufangen. Das original (Billig-) Thermometer hatte immer deutlich besseren Empfang, da ist auch nur ein kurzer gewickelter Draht (l/4?) drin.
Meine Tests, an den Empfänger eine L/4 oder L/2 zu hängen, hat den Empfang nicht merklich verbessert.

Da ich nun den eigenen Sender verwende, hat sich erstmal der Sender verbessert, so dass ich im Haus überhaupt Empfang habe. Insofern habe ich sehr den Empfänger im verdacht (dieser hat übrigens von Haus aus schon eine kurze gewickelte Antenne drauf).

mwyraz:
Ich habe heute meinen 2. Arduino bekommen und mal mit den einfachen 433MHz Modulen von Watterott getestet. Als Lib habe ich VirtualWire genommen, dort gibt es eine Fehlererkennung und die Baud-Rate lässt sich einstellen.
Den einen Arduino habe ich im Schuppen platziert, dieser sendet alle eingehenden 1-Wire-Messwerte raus mit 1200 Baud.

Den anderen habe ich im Haus aufgebaut, der empfängt die Date und sendet sie via UDP-Broadcast ins Netz.

Trotz geringer Entfernung (~10m) und nur 2 Wänden (1x Holz, 1x Stein) kommt recht wenig an. Könnte es an meinem Empfänger liegen (kaputt, schlecht eingestellt)? Ich habe an Sender und Empfänger passende Drähte (ich glaube 13 oder 17 cm, hatte ich mal nachgelesen) als Antenne.

Die Funkausbreitung unterliegt vielfältigen Faktoren, die sich per Inaugenscheinnahme gar nicht alle beurteilen lassen.

Ich selbst erziele mit billigen 433-MHz Sender/Empfänger Pärchen der 2-Euro-Klasse vom Chinaversender mit der VirtualWire-Library und je einem 17,5cm Draht als Antenne eine stabile Reichweite von 22m durch eine Hauswand (Kalksandstein/Klinker) und eine Zimmerwand (Kalksandstein). Batteriebetrieb des Senders, also Betriebsspannung im Bereich 4,5 V (volle Batterien 3xAA) bis runter zu ca. 3,6 V.

Generell ist es so, dass es schlecht ist, das Signal schon am Ort der Aussendung stark zu dämpfen ("im" Schuppen). Warum den Sender nicht außen mit Regenschutz an der Schuppenwand angebracht?

Weiterhin ist es vorteilhaft, die Antenne des Senders und auch des Empfängers möglichst hoch anzubringen. Bei Aussendung von einem 5-Meter-Mast zum Balkon in 5m Höhe ist die Reichweite größer als beim bodennahen Sender, der ins Erdgeschoss funkt.

Weiterhin ist es vorteilhaft, die ausgesendeten Funkprotokolle kurz zu halten. Wenn die Sendung nur insgesamt 5ms lang dauert ist die Wahrscheinlichkeit, dass die Sendung von einem anderen Sender gestört wird, nur ein Zehntel dessen als wenn die Aussendung 50ms lang dauert.

Kurz werden die Funkprotokolle auf zwei Arten:

  1. Höhere Baudraten verwenden (im Rahmen der technischen Möglichkeiten)
  2. Datenpakete komprimiert senden

Die Baudrate würde ich an Deiner Stelle mal auf 2000 oder 4000 setzen.

Und was sendest Du in 20 Bytes?
Das reicht ja für das Senden von mindestens 20 Temperaturen auf einmal!

Naja, wenn man es ganz besonders gut machen will, dann macht man es entsprechend der Theorie.

Schau mal in meinem Artikel DCF77 | Blinkenlight im Abschnitt "noise" nach. Die dort angegebenen Bücher nehmen das Problem vollständig auseinander.

Insbesondere das "Digital Signal Processing" Buch. Die Lösung ist eigentlich immer geeignete Faltungscodes zu verwenden. Das reduziert zwar die mögliche Übertragungsrate, man kann damit aber die Störsicherheit praktisch beliebig hoch drehen. Allerdings alles nur solange wie man überhaupt noch einen Träger empfängt. Wenn der Träger nicht mehr durchkommt, dann kannst Du so gut wie alles vergessen.

Die Originalarbeiten von Shannon habe ich hier Happy New Year DCF77 Project – Get ready for the real thing! | Blinkenlight verlinkt. Die sind aber ohne fortgeschrittene Mathematikkenntnisse eher unverständlich.

Und was sendest Du in 20 Bytes?

6 Byte - ein fester String, der angibt, was ich überhaupt sende (ds1820)
1 Byte trennzeichen
4 Byte Sensor-ID
4 Byte Temperatur (float)
3 oder 4 Byte hängt Virtual Wire für Paketlänge und Checksumme dran.

könnte man sicher halbieren...

Derzeit kommen recht regelmäßig Daten an (ich hab einfach mal ein längeres, nicht abgestimmtes Stück draht,was rumlag an den Empfänger gehängt). Trotzdem gehen zwischen 10 und 80% der Signale verloren. Ich sende alle 5 Sekunden, da habe ich zumindest keine Lücken (meiner Software reicht es, wenn alle 5 Minuten eine Temperatur eingeht).

Die Lösung ist eigentlich immer geeignete Faltungscodes zu verwenden.

Das dürfte in diese Richtung gehen: Codierte Übertragung – Mikrocontroller.net ?
Leider habe ich dazu keine fertige Arduino-Implementierung gefunden. Am liebsten wäre mir hier etwas, was Codierung, Fehlererkennung und -korrektur vereint und sich ähnlich VirtualWire einbinden lässt - für Tipps dahingehend bin ich sehr dankbar.

mwyraz:

Und was sendest Du in 20 Bytes?

6 Byte - ein fester String, der angibt, was ich überhaupt sende (ds1820)
1 Byte trennzeichen
4 Byte Sensor-ID
4 Byte Temperatur (float)
3 oder 4 Byte hängt Virtual Wire für Paketlänge und Checksumme dran.

könnte man sicher halbieren...

Du sendest ja die reinsten Romane!

Die Bytes, die Virtualwire als Startcode, Länge und Prüfsumme sendet mal aussen vor: Du sendest 15 Bytes und tatsächlich benötigt werden nur 3, d.h. Du sendest das fünffache an Daten wie es notwendig ist!

Tatsächlich notwendig wären:

  • ID = 1 Byte
  • Temperatur 2 Byte

Und den Rest packst Du als Tabelle/Programmlogik in den Empfänger, der dann Bescheid weiß.

Mit einer Byte-ID kodierst Du 256 verschiedene Werte. Die 8-Bit könntest Du also verwenden, um 256 verschiedene Sensoren eindeutig zu unterscheiden. Oder wenn Du je 4 Bit für die Codierung der Sensorart und 4 Bit für die Sensornummer verwendest, könntest Du Daten von 16 Arten verschiedener Sensoren senden, mit 16 möglichen Sensoren von jeder Art.

Dass der Sensor mit der Funk-ID 47 ein ds1820 ist und welche Chip-ID er hat, das kannst Du doch in einer Tabelle im Empfänger ablegen, das muß doch nicht jedesmal gesendet werden, weil es sich überhaupt niemals ändert?

Und die Temperatur als float? Wird die Temperatur genauer als auf 0.1°C übertragen? Im Normalfall würdest Du Temperaturen als Integer (2 Bytes) in Zehntel-Grad senden, das wären von -200.0°C bis +200.0°C die Werte -2000 bis +2000 als Integer gesendet. Oder wenn es auf hundertstel Grad genau sein soll, dann Werte zwischen -20000 bis +20000. Und der Empfänger weiß, dass es Zehntelgrade oder Hundertstelgrade sind, die er in den zwei Bytes empfängt und verarbeitet die Werte entsprechend weiter.

Ich finde, Dein Funkprotokoll ist viel zu lang.

Wenn Du Befürchtungen hast, dass in der Nähe Deiner Sensoren andere Sensoren senden, die mit der VirtualWire-Library senden, dann ändere die CRC-Berechnung in Virtualwire leicht ab, z.B. per XOR mit einer individuellen Konstante, so dass Dein Empfänger nur Funkpakete mit gepatchten CRC-Prüfsummenberechnung akzeptiert.

Wie gesagt: das könnte man sicher etwas kürzen :slight_smile:

4 Byte ID ist die interne ID der DS1820 Sensoren. Da der Code generisch ist und ich jederzeit beliebige Sensoren hinzufügen will, bleibt's wohl dabei. Könnte ich sicher auf 2 Byte reduzieren, da ist die Wahrscheinlichkeit einer Kollision nicht sehr hoch. Ansonsten würde jeder neue Sensor eine Anpassung im Programm nötig machen.

4 Byte float durch int ersetzen gehe ich mit. Der Sensor misst mit 9 Bit Auflösung. Byte würde also nicht mehr reichen.

Ein Byte als Kennung, um welchen Message-Type es sich handelt, würde ich noch vornean stellen.

Ich käme also auf 5 Byte zu übertragende Nutzdaten.

Die entscheidende Frage ist: Steigt die Fehlerquote linear (oder stärker) mit der Länge der Nachricht?

mwyraz:
Die entscheidende Frage ist: Steigt die Fehlerquote linear (oder stärker) mit der Länge der Nachricht?

Das hängt konkret von den tatsächlichen Störungen auf der Frequenz ab.
Bei starken Störungen auf der Frequenz sind lange Übertragungen mehr von Nachteil.

Rein zur mathematischen Wahrscheinlichkeit bei verschiedenen Störraten auf der Leitung mal zwei Beispiele:

Beispiel 1 (wenig Funkstörungen):
Die Wahrscheinlichkeit, dass ein einzelnes gesendetes Byte während der Übertragung fehlerhaft empfangen wird, sei 0,1%. Das bedeutet, es wird mit 99,9% Wahrscheinlichkeit fehlerfrei übertragen, oder als mathematische Wahrscheinlichkeit 0,999.

Wenn nun 30 Bytes übertragen werden, ist die Wahrscheinlichkeit, dass alle 30 Bytes in Folge fehlerfrei übertragen werden:
W= (0,999)30 = 0,9704 (zu 97% fehlerfreie 30-Byte Übertragungen)
Oder die Wahrscheinlichkeit, dass ein Fehler auftritt 0,03 bzw. 3%.

Bei nur 15 übertragenen Bytes sähe es so aus:
W= (0,999)15 = 0,9851 (zu 98,5% fehlerfreie 30-Byte Übertragungen)
Oder die Wahrscheinlichkeit, dass ein Fehler auftritt 1,5%.

Hier liegt eine Linearität vor, bei halber Übertragungslänge hat man auch nur die halbe Fehlerrate bei Übertragungen.

Beispiel 2 (starke Funkstörungen):
Die Wahrscheinlichkeit, dass ein einzelnes gesendetes Byte während der Übertragung fehlerhaft empfangen wird, sei 10%. Das bedeutet, es wird mit 90% Wahrscheinlichkeit fehlerfrei übertragen, oder als mathematische Wahrscheinlichkeit 0,9.

Wenn nun 30 Bytes übertragen werden, ist die Wahrscheinlichkeit, dass alle 30 Bytes in Folge fehlerfrei übertragen werden:
W= (0,9)30 = 0,0424 (zu 4,2% fehlerfreie 30-Byte Übertragungen)
Oder die Wahrscheinlichkeit, dass ein Fehler in der Übertragung auftritt, liegt bei 95,8%.

Bei nur 15 übertragenen Bytes sähe es so aus:
W= (0,9)15 = 0,2058 (zu 20,6% fehlerfreie 15-Byte Übertragungen)
Oder die Wahrscheinlichkeit, dass ein Fehler in der Übertragung auftritt, liegt bei 79,4%.

Bei stark gestörter Frequenz bekommt man also bei halber Übertragungslänge fast viermal so viele fehlerfreie Datenpakete übermittelt.

Fazit: Je stärker die Funkstörungen sind, desto vorteilhafter ist ein möglichst kurzes Übertragungsprotokoll.

Ich hab mal ne Frage zu diesem Thema: hat einer von euch schon mit dem "nRF24L01 2.4GHz Radio/Wireless Transceivers" gearbeitet ? Hat der funktechnisch evtl. bessere Eigenschaften als die hier diskutierten 433MHz Transceiver ?

Hier ist ein Einstieg in dieses Thema zu finden: http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

Ich suche für ein Projekte gerade Argumente fuer oder gegen eine bestimmte Technik und bin daher auch an Erfahrungen interessiert.

MfG
Jürgen

Über den nRF24L01 habe ich auch schon nachgedacht, bin aber aus 2 Gründen davon abgekommen:

  • die Platine kann nicht ohne weiteres aufs Breadborad. Lässt sich aber lösen: http://blog.sui.li/2011/06/28/rfm01-rfm12-aufs-breadboard/ Anstatt das Teil wie im Beispiel auf eine Lochraster-Platine zu löten, kann man die Draht-Enden ja direkt ins Breadboard stecken.
  • Anschluss über SPI und 3,3V. Das verkompliziert den Aufbau, vor allem in einer späteren Standalone-Lösung mit evtl. sogar einem kleineren µC.

Die Reichweite wird oft mit 200ft angegeben, also ca. 60m. Bei den 433MHz Geräten wird als Reichweite zwischen 30 und 200m angegeben.

Das Bild, was Du verlinkst ist ein RFM12-Modul, der nRF24L01 ist erst mal ein Chip, den es auf verschiedenen Modulen gibt. Und da gibts auch welche die sich problemlos stecken lassen.

Oh, da hatte ich mich wohl vertan... Den nRF24L01 hatte ich abgewählt, da er bei Watterott ~20€ kostet und ich nicht beim Chinesen bestellen will (hab keine Lust, mich mit irgendwelchem Zoll-Kram rumzuärgern).

Inzwischen habe ich noch ein wenig auf 433 MHz rumgetestet:

  • Mit 2000 Bit/s kommt fast garnichts mehr an. Mit 1000 geht es wieder.
  • Ich habe die Datenmenge auf 6 Byte Nutzdate reduziert (vorher 17 Byte): 1 Byte Kennung, 2 Byte Sensor-ID, 2 Byte Temperatur, 1 Byte laufende Nummer. Mehr ist ohne Funktions- oder Komfortverlust nicht möglich. Dies hat den Paketverlust um ca. 50% reduziert.
  • Ich sende nun alle Nachrichten 2x direkt hintereinander.

Damit kommen auf Dauer ca. 90% der Pakete durch (wenn mind. 1 der 2x Pakete durchkommt, reicht es). Wiederhole ich 5x, kommen ~95% durch.

Es fällt auf, dass meistens größere Blöcke nicht durchkommen (also gleich 5 Pakete hintereinander). Daraus folgere ich, dass die Probleme aufgrund der starken Belegung des 433MHz Bandes entstehen. Um es nicht noch mehr zu belasten, habe ich wieder auf 2 Wiederholungen reduziert. Damit belege ich das Band ca. 4% (0,2s/5s). Wenn alles fertig ist, reduziere ich auf 20s Sendeimpuls oder größer.

Vielleicht mache ich noch einen Test auf 868 MHz. Dort sollte weniger los sein und die maximalen Sendelängen sind gesetzlich festgelegt.

mwyraz:
Es fällt auf, dass meistens größere Blöcke nicht durchkommen (also gleich 5 Pakete hintereinander).

Was heißt "größere Blöcke"?

Du packst doch wohl hoffentlich nicht die Message in ein größeres char-Array und sendest dann auf einmal mit einer einzigen vw_send Anweisung in einem Rutsch? Dann würde natürlich das zutreffen, was ich in diesem Thread vorgerechnet habe: Je größer die Blöcke, desto weniger kommt an.

Sondern Du sendest hoffentlich immer dieselbe kleine Message mit eigenem vw_send fünfmal getrennt hintereinander mit zusätzlichem delay:

for (int i=0;i<5;i++)
{
  vw_send((uint8_t*)msg, strlen(msg));
  vw_wait_tx(); 
  delay(30);
}

Wobei das zusätzlich eingefügte delay nach dem vw_wait_tx() mindestens so lange dauern sollte, wie Du zum Abholen und Verarbeiten einer empfangenen Nachricht beim Empfänger benötigst.

BTW China-Bestellungen und Zoll: Mit Zoll hast Du bis zu einem Warenwert von 22,50 EUR pro Sendung nichts zu tun. Außer dass die Sendung bei Dir gelegentlich mal mit einem kleinen grünen Aufkleber ankommt, auf dem entweder sowas steht wie "zollamtlich geprüft" oder "von der Zollbehandlung befreit", weil der Zoll geprüft hat, ob der zoll- und einfuhrumsatzsteuerfreie Warenwert vielleicht überschritten wurde.

Was heißt "größere Blöcke"?

Hier meine ich schon, mehrere Messages in direkter Folge (ähnlich dem Beispiel unten).

vw_wait_tx() kann man weglassen, das passiert implizit bei jedem send().
Ein Delay habe ich auch nicht drin. Das sollte kein Problem sein. Das Empfangen läuft innerhalb von VirtualWire asynchron via Interrupt, d.h. solange ich nicht länger zum Verarbeiten der Message benötige, als die nächste Message übertragen wird, ist's wohl kein Problem. In meinem Fall leite ich die Message 1:1 als UDP-Broadcast weiter.

Ohne Störung kommen alle 5 Messages sauber an. Wenn es eine Störung gibt, fallen aber gleich mal 4 oder alle 5 Messages weg. Dass nur 1 oder 2 durchkommen, passiert fast nie - daher die Vermutung, dass andere Sender die Übertragung gleich für längere Zeit stören.