Ich plane gerade mehrere RFM12 zu verbinden, so dass sich jeder mit jedem unterhalten kann. Jedes Modul hat dazu eine feste ID und eine bestimmte Aufgabe. Einerseits werden periodisch Werte einfach nur gesendet (z.B. Uhrzeit einer Funkuhr, Außentemperatur usw.), andererseits gibt es aber auch Steuerbefehle, deren Erhalt vom Empfänger bestätigt wird. Sollte die Bestätigung ausbleiben, sendet der Sender die Daten erneut. Soweit funktioniert das schon. Das Problem ist aber: Woran erkennt ein Empfänger ob die Daten neu sind, oder schonmal empfangen wurden ? Bei meiner RS232 Funkbrücke habe ich das dadurch gelöst, dass einfach bei jedem neuen Paket ein Wert erhöht wird. So erkennt der Empfänger ob er ein Paket mit dieser Nummer schonmal empfangen hat oder nicht. Bei mehreren Sendern kann es aber sein, dass unterschiedliche Module die gleiche Nummer senden. Ich müsste also für jedes Modul einen eigenen Zähler einbauen. Ebenso beim Senden. Allerdings bin ich (bei theoretisch 256 Modulen) schon bei 512Byte die dafür benötigt werden. Auf einem kleinen AVR (mega48 oder mega8) sicherlich nicht die beste Lösung. Hat jemand eine bessere Idee, wie man sowas lösen kann ?
Ev. kannst du ja sowieso die Uhrzeit in dem Projekt gebrauchen, verknüpfe es mit der Zeit und ev. Datum, mein Vorschlag.
@RFM12-nein danke schmunzel schmunzel schmutzel Aber Recht hast du, aber wenn's schlau macht :-) @Benedikt stellst du dein Projekt mal vor?
Du müßtest entweder mit einer Semaphore arbeiten, oder wenn's kreuz und quer gehen muß/soll jedem Sender/Empfänger bei jedem Paket seine eineindeutige ID mitgeben. Z.B. indem Du eine Art Hamming CRC bzw. besser Public-Key Verschlüsselung für jeden Knoten implementierst. Allerdings dürfte das wohl in die selbe Problematik laufen die Du schon hast :-P Wenn die Daten bei jedem Knoten intern zwischengespeichert sind, einfach den gesamten Datensatz senden, dann kann lokal entschieden werden ob sich was geändert hat oder einfach alles übernommen werden. Also statt "Erhöhe Temperaturauflösung um vier Schritte" als Befehl zu senden einfach den kompletten Status senden "Temperaturschritte 200, Windgeschwindigkeitsschritte 300, usw." ... Oder via Master/Slaves und einen PC als Master nehmen, der hat genug Speicher :-P Meine spontane Idee dazu ;-)
Hallo Benedikt, ich schliesse mich meinem Vorredner an. Anbei mal ein Auszug wie das in Packet in Afu gehändelt wird. Dort herrscht ja auch unter den Stationen "Ordnung" Wigbert
und hier noch die Netzknoteneinwahl. Viellecht bring das ein paar Ideen. Wigbert
@Benedikt: Ich würd als Vorlage TCP benutzen. Da gibts sogenannte Sockets mit Acknowledge und Sequence Numbers, die sich gegenseitig die empfangenen Bytes bestätigen (Hast du ja in ungefähr auch schon in deinem Code gehabt). Daran würd ich mich mal orientieren. Vorteil: Du kannst zum Beispiel den uIP Stack von Adam benutzen (oder andere einfache TCP Stacks). Quasi TCP/IP over RFM12 :-)
@wigbert Könntest du mal sagen welches Buch als Quelle gedient hat da ich mich für das Thema interresiere.
Interessantes Thema über das ich so neben meiner Arbeit auch schon einige Zeit nachdenke. Benedikt mich würde interessieren wie du Kollisionen im Äther vermeiden willst. Dh. schon der Verbindungsaufbau innerhalb eines solchen Funknetzes ist ein komplexes Problem, besonderst dann wenn einige Teilnehmer Master andere nur Slaves ander wiederrum Multi.Master bzw. Multi-Slaves sind. Ich grüble nämlich auch schon einige Zeit (und lese einiges über Bluetooth/WLAN usw.) wie man ein Kommunikationsprotokoll baut das folgednes kann 1.) Geräte haben eine ID, 8 Bits dürfte erstmal reichen 2.) Geräte können eine Peer to Peer Verbindung aufbauen, dazu benutzen sie einen freien Kanal, exklusiv für hohe Datenraten 3.) es gibt Geräte die Artspezifisch sind, zb. Fernbedienung und mehrere Empfänger 4.) es gibt Geräte die mehrere Sender empfangen sollen, zb. USB-RFM12 Stick und Wetterstationen, oder RS232 über Funk Also schon ziemlich komplex und es geht auch nicht um eine EierWollMilchSau sondern um eine möglichst flexible Grundlage für die RFM12 Module die man nach obigen Kriterien erweitern kann. Dazu muß aber denoch dieses Software Grundmodul die wichtigsten Funktionen schon enthalten. Also: - Kollisionserkennung - Allokation des Frequenzbandes - Handshake, sprich Empfangsbestätigung - Identifizierung der RFM12 Module samt der Art des Modules, also ob passiver/aktiver Slave usw. Bisher bin ich zu folgenden Voraussetzung an das Protokoll gekommen 1.) eindeutige ID pro Modul 2.) Packetorientiert 3.) eindeutige Numerierung der Packete 4.) Prüfsumme ist notwendig 5.) Allokation des Frequenzbandes ähnlich WLAN mit CTS und RTS Packeten 6.) Session orientiert, also so wie beim Packet Radio Ein weiterer Punkt auf meiner Liste ist die Sicherheit. Es muß eine einfach Athentifikation zwischen den Modulen her. Es wäre schon blöde wenn der Nachbar mein Haus fernsteuern kann. Wenn du sowas ähnliches wie die CTS/RTS Kommando Packete zu Allokation eines Funkkanales benutzt dann speichert man ja in diese fixed Lenght Packete die Anzhal der Datenbytes des nachfolgenden Datenpacketes. Mit dieser Information und der gemeinsammen Baudrate aller beteiligten Module können diese dann ausrechnen wan zeitlich gesehen der Funkkanal wieder frei wird. Man bräuchte nun den Packettyp für Daten und einen Packettyp für die bestätigung das man diese Daten korrekt empfangen hat. D.h. für jedes Datenpacket wird erstmal ein RTS an den Empfänger gesendet der muß mit CTS antworten und danach kommt ein Datenpacket mit der Länge die im RTS Packet vorgegeben wurde. Am Ende quittiert der Empfänger mit einem extra Packettyp und gibt so auch den Funkkanal wieder frei. Sollte nun beim Aussenden des RTS Packetes eine Kollision entstanden sein, weil auch ein anderes Modul ein RTS gesendet hat, dann wird per Zufall eine gewisse zeit inerhalb eines vorgegeben Zeitfensters gewartet, auf andere RTS/CTS Packete gelauscht und nach Ablauf der Frist erneut ein RTS gesendet. Nach diesem Connect entsteht auf beiden Seiten eine Session. Alle Datenpackete werden nun Sessionbezogen durchnummeriert. Solange eine solche Session lebendig ist kann der Funkkanal nicht durch andere Module benutzt werden. Ind den RTS/CTS packeten könnte also auch kodieert sein das man einen anderen freien Funkkanal benutzen möchte. Da diese RTS/CTS Packate auf einem fixen Kanal ausgesendet werden würden auch die passiven RFM12 Module davon was mitbekommen und intern eine Liste der freien Kanäle und verfügbaren Module mitführen. Gruß Hagen
Erstmal danke für Antworten. Es sind mehr geworden als ich erwartet hatte. Anscheinend bin ich nicht der einzige der sowas vor hat... Wenn das ganze fertig ist, wird das ganze natürlich wieder in der Codesammlung landen, aber das kann noch dauern. Bisher ist das ganze nicht viel mehr als die RS232 Funkbrücke um IDs erweitert und Paketorientiert aufgebaut. Momentan habe ich folgendes eingebaut: Jedes Modul sendet wann immer es möchte, folgende Daten: - Syncword - Empfänger ID - Sender ID - Message Type - Message Flags (Empfangsbestätigung erwünscht usw.) - fortlaufende Nachrichtennummer - Anzahl an Nutzdatenbytes - Nutzdaten - Prüfsumme (CRC16) Da im Normalfall nie viele Daten übertragen werden müssen, sollte die fehlende Busarbitrierung kein Problem sein. Bei den RFM12 wäre diese auch nicht ganz einfach, da die Module nie gleichzeitig senden und empfangen können. Bei den Neuübertragungen von verlorenen Paketen wird eine zufällige Pause eingebaut um zuz verhindern, dass diese mehrmals gleichzeitig senden. Bisher sind die Nutzdaten auf 64Bytes beschränkt, was im Normalfall reichen sollte. Notfalls muss man halt mehrere Pakete senden. Der Empfänger erkennt ob die Nachricht an ihn gerichtet ist, oder eine globale Empfänger ID hat (255, z.B. bei Temperaturen, Uhrzeit usw. der Fall). Alle anderen Nachrichten verwirft er sofort, diese landen garnicht erst im Puffer. Einen Frequenzwechseln habe ich nicht vorgesehen, alle Module senden und empfangen auf einer einmalig eingestellten Frequenz. Das wäre dann quasi die Ausbaustufe von dem hier, aber das überlasse ich denjenigen die Nachrichtentechnik oder sowas in der Art studiert haben... Das mit der Mehrfach Übertragung scheint schwieriger zu sein, als ich dachte. Mit TCP/IP kenne ich mich eigentlich so gut wie garnicht aus, aber sind die Implementierungen nicht relativ aufwendig, vor allem was das SRAM und Flash angeht ? Ich hatte als Obergrenze einen mega8 vorgesehen. Mehr als 256Byte SRAM und mehr als 2kByte Flash sollte die Mehrfachübertragung Erkennung als nicht brauchen. Momentan bin ich bei etwa 3kByte für eine noch nicht optimierten RFM12 Routinen. Falls es nicht machbar ist, muss ich es leider weglassen. Momentan ist es auch nicht notwendig, denn wie einige schon angemerkt haben, kann man Absolutwerte als Steuerdaten senden, ob dann 1 oder 2x der Befehl kommt: "Licht an", ist dabei dann auch egal. Allerdings wollte ich das ganze eben schon etwas universell machen, so dass sich die eigentliche Software gar keine Gedanken mehr über die Pakete zu machen braucht, sondern diese nur senden und empfangen kann, über eine einfache Schnittstelle: send_packet(&data, header); und get_packet(&data, &header);
Moin Benedikt, Ich würde es einfach so machen, dann kommst du mit 256byte RAM aus: du hast eine Tabelle mit 256 Einträgen, der Index=die ID des devices. Jedes Device hat einen Internen Zähler, der bei jeder Übertragung hochgezählt wird und diesen Wert überträgst du einfach mit... fertig :) TCP/IP würd ich hier nicht empfehlen, der Overhead ist 5x32bit = 20 Byte nur für den TCP Header! Mal abgesehen davon das du da ne ganze Menge RAM brauchst wenn du mehr als eine Connection unterstützen willst.
Läubi Mail@laeubi.de wrote: > du hast eine Tabelle mit 256 Einträgen, der Index=die ID des devices. > Jedes Device hat einen Internen Zähler, der bei jeder Übertragung > hochgezählt wird und diesen Wert überträgst du einfach mit... fertig :) So habe ich das momentan, allerdings reichen eben 256 Bytes nicht: Ich muss nämlich für jedes Modul die Nummer speichern die gesendet wird, und die Nummer speichern die empfangen wird. Nur so bleiben Sender und Empfänger synchronisiert.
> Momentan habe ich folgendes eingebaut: > Jedes Modul sendet wann immer es möchte, folgende Daten: > - Syncword > - Empfänger ID > - Sender ID > - Message Type > - Message Flags (Empfangsbestätigung erwünscht usw.) > - fortlaufende Nachrichtennummer > - Anzahl an Nutzdatenbytes > - Nutzdaten > - Prüfsumme (CRC16) > Entspricht also so ziemlich dem S.N.A.P Protokoll. Also evtl auf etwas bestehendes aufsetzen??? http://www.hth.com/snap/ Gruss, Henning
Nene Benedikt! Der Sender hat nur EINE Nummer! Sequenznummer würd ich nur pro Übertragung neu machen (ist ja auch nur nötig wenn man nen ACK anfordert). So kannst du doppelte Pakete erkennen, und wenn ein Empfänger nen ACK erwartet muß er nur für diese Übertragung die Sequenznummer halten bis es zu einem ACK kam.
@Marco
>Buch als Quelle
"Packet Radio-G.Grünfeld,DL6YCL"
im Funkamateur-Leserservice
Wigbert
Schon mal an diese IDwarf-Module gedacht? Die Firmware ist IMHO frei und im source verfügbar: http://www.chip45.com/index.pl?page=iDwaRF-Net&lang=de
Läubi Mail@laeubi.de wrote: > Nene Benedikt! > Der Sender hat nur EINE Nummer! Sequenznummer würd ich nur pro > Übertragung neu machen (ist ja auch nur nötig wenn man nen ACK > anfordert). Irgendwie verstehe ich nicht ganz wie du das meinst: Ich habe eine Nummer (eine oder für jedes Device eine, also eine Tabelle mit 256 Nummern) beim senden ? > So kannst du doppelte Pakete erkennen, und wenn ein Empfänger nen ACK > erwartet muß er nur für diese Übertragung die Sequenznummer halten bis > es zu einem ACK kam. Das ist soweit klar, aber in dem moment wo ich eine Nummer für jede einzelne ID habe, brauche ich sowohl beim Senden als auch beim Empfangen diese ID.
Ja aber du kannst nicht 256 Werte gleichzeitig senden. Also fürs senden machst du es dann so, das du bspw die Sequenznummer 0 vorgibst, welche du nach jedem Senden erhöhst. Der Empfänger merkt sich diese und sendet dir ggf nen ACK. Wenn die übertragun+ACKS fertig ist, kannst du eine neue Übertragung zu einem neuen Modul aufbauen.
Sagen wir mal ich sende die Nummer 0 an ein anderes Modul. Dieses merkt sich die 0. Jetzt sendet das Modul Werte an andere Module, und nach (zufällig) genau 256 Werten sendet es wieder an das Modul das sich die 0 gemerkt hat. Da es ein 8bit Zähler ist, wird aus der 256 eine 0, das Modul bekommt die 0 als Nummer und denkt sich, dass es diese Nachricht schon hat und verwirft diese. Ich gebe zu, die Warscheinlichkeit dass genau 255 Nachrichten dazwischen liegen ist nicht allzuhoch, aber es kann durchaus vorkommen. Wenn ich schon eine Bestätigung verwende, dann möchte ich auch, dass eine bestätigte Nachricht angekommen ist.
Ich denke Läubi meint das anders. Du gehst davon aus das ein Modul A chronologisch nacheinander die Module B und C mit Datenpacketen versorgt immer im Wechsel und durcheinander, also Frame-los. Wenn aber das Modul A nur mit Modul B kommunizieren kann dann ist das eine Session. Erst nachdem diese Session geschlossen wurde kann Modul A mit Modul C kommunizieren. Innerhalb einer solchen Session=Connection können mehrere Datenpackete ausgetauscht werden, aber eben zb. nur zwischen Modul A und B und erst später Modul A und C. Innerhalb einer solchen Session sind die Absender und Empfänger ID der Datenpackete eindeutig im kompletten Äther. Nun nummerierst du einfach deine Datenpackete immer von 0 beginnend durch. Diese Nummerierung ist nur gültig innerhalb einer Session. Du hast also einen versuchten Verbindungsaufbau zum Datenaustausch von Modul A nach Modul B. Modul A erzeugt eine neue Session, gebunden an die Kommunikation zwischen A und B. Dabei wird der Counter auf 0 gesetzt. Nun pingt A Modul B an. Modul B nimt diesen Connectionaufbau entgegen, erzeugt seinerseits eine Session und setzt Zähler auf 0. Nun ist der Kanal belegt und die Datenpackete werden ausgetauscht. Die Zähler werden auf Senderseite immer dann inkrementiert wenn ein ACK vom Empfänger empfangen wurde. Hm, eventuell müssten diese Session Objekte zwei Counter besitzen, einen für abgesendete Packete und einen für empfangene Packete. Diese Zähler beziehen sich dann immer noch auf die aktuelle Verbindung zwischen 2 Modulen. Bei einer 1:N oder N:1 Topologie kann immer nur einer der Master sein. Entweder ist der Master ein Sender an mehrere Empfänger oder umgekehrt. In diesem Falle benöigt der Master N solcher Session Objekte und die Clients nur 1 Session Objekt. Ich meine diese beiden Szenarien sollten ausreichend sein für uns. Also Peer to Peer oder 1:N / N:1 Master Slave. Deshalb meine ich auch das neben der Empfänger/Absender ID in den Header der Packete auch noch ein Feld "Geräte-Art" rein muß. Zb. alle Funkempfänger sind kompatibel zu einer Funkfernsteuerung als Geräteart. Sendet nun ein Master mit Geräteart "fernbedienung" ein Brodcast raus so dürfen darauf nur Funkempfänger-Geräte reagieren. Umgedreht das Gleiche bei zb. Sensoren einer Wetterstation an einen USB-RFM12 Stick als Master. Die Geräteart stellt also sicher das nicht alle RFM12 Module aus alle Nachrichten reagieren. Eventuell könnte man auch auf dieses Feld verzichten wenn man die Addressen der Module in Bereich einteilt. Die Geräteadresse/ID bestimmt dann was das Modul empfangen kann oder nicht. Gruß Hagen
Hallo, ich hatte mir den "Profibus" als Vorbild ausgedacht(nur eben Drahtlos) Grundsätzlich alle Daten an Master (Computer) Master schickt Daten an adressierten Slave. Also wenn jemand das Protokoll "Busaktiv" sendet, horchen alle. dann Datenübertragung mit Fehlerprotokoll. dann Protokoll"Bus deaktivieren" senden. Ich sehe das Problem, das sich die RFM12 sonst stören würden. Wobei bei dem Hausbus kann der Master auch regelmässig jeden Abfragen. (Raumtemperatur reicht doch wohl alle paar Sekunden) Jalousien mit Sammelbefehlen fahren. Uhrzeit nur mehrmals synchronisieren. In meiner 200m² kleinen Hütte ist das wohl so machbar. Wigbert
Hallo Benedikt, ich habe mich auch schon gefragt, ob ein vermaschtes Funknetzwerk mit den RFM12 Modulen möglich ist. Als Vorbild für das Phy- bzw. Mac-Layer würde ich schon vorhandene Standards wie 802.15.4 vorschlagen. Wie gesagt: Nur als Vorbild! Das würde also auf jeden Fall schon einmal die Dinge beinhalten, die Du schon eingebaut hast. Nachrichtenzäher, Dest.-ID, Src-Id, Message-Type, CRC-16, etc. Wie regelst Du denn den Zugriff auf den Äther? CSMA/CA mit random exponential backoff? Geht das überhaupt mit den RFM12 Modulen? Interessant wird die ganze Sache aber erst so richtig , wenn RFM12-Knoten routen können und ein vermaschtes Netzwerk bilden könnten. Das würde natürlich noch entsprechend mehr MCU Resourcen benötigen. Könnte man Dich evtl. auf einen größeren Controller hochhandeln? :-) Mit mehr Flash und RAM. Die höheren Layer über dem Mac-Layer könnten sich an verschiedenen anderen existierenden Lösunge orientieren: Zigbee, Z-Wave, 6LoWPAN. Evtl. ist 6LoWPAN hier die cleverste Lösung, da sie wirklich offen ist und es die Specs von der IETF gibt. Es gibt auch bereits einen funktionieren 6LoWPAN Stack von der Firma Sensinode. http://www.sensinode.com/top/information.php?info_id=10 Der Stack steht unter der GPL und basiert auf den 802.15.4 Chips von TI: CC2420 - nur Radio bzw. dem CC2430 - Radio + 8051 MCU. Ich überlege nun, ob man für die RFM12 Module soetwas wie einen 802.15.4 Konvergenz-Layer schreiben könnte, der es ermöglicht, diesen Stack dann auf den RFM12 Modulen aufsetzen zu lassen. Noch deutlicher: es müssten "nur" die Low-Level Funktionen wie rf_enable, rf_write, rf_read, rf_cca_check, etc. neu geschrieben werden für das RFM12 Modul. Die Dinge, die Du ja jetzt proggst, um den Zugriff auf MAC Ebene zu regeln, könnte man prima an diesen Stellen im Stack einbauen. Aber wie schon oben geschrieben: ein ATmega8 wird vom Speicher her nicht ausreichen. Gruss, Christian
Nachtrag: Hier ein Link zu den existierenden 6LoWPAN Dokumenten inkl. Protokoll- und Formatbeschreibung. http://tools.ietf.org/wg/6lowpan/ Der Sensinode Nanostack beinhaltet momentan die Möglichkeit IPv6 UDP Pakete über ein 802.15.4 Netz zu schicken (inkl. einfachem Routing). Nanostack-Manual: http://www.sensinode.com/pdfs/sensinode-manual-nanostack-v1.0.1.pdf Der Stack beinhaltet momentan, wie im letzen Beitrag erwähnt, Treiber für die 802.15.4 Chips von TI. Hier wäre also ein Treiber für ein RFM12 Modul gefragt. Ein RFM12-Treiber muss natürlich all das, was die 802.15.4 Chips von TI in Hardware machen (CCA[Clear Channel Assessment], CRC-16, Auto-ACK) zusätzlich in Software machen. Das ist aber nicht viel. Eine mögliche Verschlüsselung mit AES lasse ich mal außen vor. Zur Anbindung der ganzen Geschichte an das vorhandene Ethernet würde ja momentan der evtl. schon vorhande Server-PC zuhause reichen. Auch dafür sieht der Nanostack extra ein kleines Protokoll (nRP) über die serielle Schnittstelle vor. Hinterher könnte man natürlich ein kleines Gateway bauen, das aus einem ATmega, einem ENC28F60 und einem RFM12 besteht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.