Ich Baue mir zurzeit ein Kleines Arduino Netzwerk basierend auf einer RS485 Schnittstelle auf.
Im Netzwerk soll es einen Master und mehrere Slaves geben, welche Messdaten Ermitteln und diese an den Master senden sollen, sobald der Master Sie dazu auffordert.
Soweit zur Theorie , da ich allerdings wenig bis gar keine Kenntnisse von Serieller Datenverbindung habe, scheitert es bei mir gerade ein wenig
Meine Grundidee war Folgende : Der Slave misst die Daten und Speichert sie in ein Array ab, wenn dann die Aufforderung vom Master kommt soll er das Array Senden, Der Master Wartet dann darauf , liest es ein und Speicher es in Einzelnen Int. Und Genau daran scheitere ich zurzeit das Senden ist keinerlei Problem nur weiß ich nicht genau wie ich die Komplette "Sendung" abfangen soll und dann Separieren soll.
Bin Beim Googlen dann auf mehrere Ähnlich vorhaben gestolpert allerdings keine in denen der Vorhanden Code ein wenig erklärt worden ist.
Da es mir Wichtig ist bei dem Projekt was zu lernen und den Code auch zu verstehen hoffe ich das ich den ein oder anderen hier vielleicht finde der mir ein bisschen unter die Arme greift.
Warum willst Du das Array an den Master senden und dort in einen Integer umwandeln (Mittelwert? ) Das kann doch der Slave selbst machen und das Ergebnis übertragen. Suche mal nach gleitendem Mittelwert.
Ansonsten als Zeile mit Zeilenende ('\n') senden, wenn mehrere Werte, dann mit Trennzeichen (z.B. trennen.
Bis zum Zeilenende einlesen, mit '\0' abschließen. Wenn mehrere Werte, die über strtok trennen und die Teile / den einzelnen Wert mit atoi oder atof (float) in Zahl umwandeln.
Ein Startzeichen (z.B. 0xFF)
Ein Sender Zeichen (= wer schickt z.B. 'M' für den Master)
Ein Empfänger Zeichen (= wer soll reagieren z.B. 'A' für den Slave A)
deine Payload ( "123;44;33")
Ein Ende Zeichen (z.B. LF oder CR damit du das auch bequem am Serial Monitor testen kanns.
Zeichne dir selber auf was du alles hin und her schicken musst, dann kannst du dein Protokoll von Anfang an gut planen.
Oder verwende Industriestandards - da brauchst aber zum einarbeiten vermutlich noch länger.
Jedenfalls ist das nichts was an einem Nachmittag fertig sein wird.
Hallo
zeige Deinen Sketch, dann können wir Dir besser helfen.
BTW:
RS485 ist nur eine Verpackung in der die Daten versendet werden. Für den Labortisch langen zwei Arduinos mit gekreutzen RX/TX Leitungen.
RS485 ist nur eine Verpackung in der die Daten versendet werden. Für den Labortisch langen zwei Arduinos mit gekreutzen RX/TX Leitungen.
ist mir bewusst , habe die Arduinos zurzeit auch so Verbunden, bis das Programm steht
Der Master
müsste zunächst mal an Slave A senden "A - schick was"
danach sofort wieder auf "Empfangsbereitschaft" gehen
Der Slave A
müsste nun was senden sobald er den Befehl am Bus bekommen hat "A - schick was"
Der Master
da empfangsbereit jedes Zeichen das nun von Slave A reinkommt zu einem c string zusammenbauen.
wenn fertig - den c-string mit strtok zerteilen.
Genau so habe ich mir das in etwa vorgestellt .
Der Sender prüft aktuell ob die vom Master empfangende Datei mit der Internen Adresse übereinstimmt und sendet dann das Array mit den Daten. Das kann ich Soweit auch am Master Über den Seriellen Monitor Auslesen allerdings bekomme ich es wie gesagt nicht gescheit Strukturiert in einzelne INT Geschrieben.
Dann überlegst dir ein Protokoll
z.B.
Ein Startzeichen (z.B. 0xFF)
Ein Sender Zeichen (= wer schickt z.B. 'M' für den Master)
Ein Empfänger Zeichen (= wer soll reagieren z.B. 'A' für den Slave A)
deine Payload ( "123;44;33")
Ein Ende Zeichen (z.B. LF oder CR damit du das auch bequem am Serial Monitor testen kanns.
Bezüglich Protokoll war mein Plan folgendes:
Master Sendet Auf dem BUS Die Adresse 1-256
Der Slave Prüft die Adresse und Sendet Falls sie Übereinstimmt das Zeichen "X" als Bestätigung
Der Master Liest dies und Weis das er auf die Daten warten muss die der Slave direkt Nach dem Bestätigungszeichen Sendet.
Ein "Start", "End" . "für wenn ist die MSG" Zeichen würde Natürlich auch noch Sinn machen oder würde es mit meiner Minimal Ausführung auch schon hinhauen?
Das dass kein Programm bzw. Projekt wird was welches ich an einem Tag machen kann, ist mir völlig bewusst.
Mir ist es bei dem Projekt nur wichtig das ich die Sache recht Professionell löse und am ende des Tages auch verstehe was ich da überhaupt Programmiert habe um das Projekt problemlos erweitern zu können.
der würde es mit meiner Minimal Ausführung auch schon hinhauen?
nein.
wenn das "Startzeichen" nur ein byte ist - dann würde ein Slave jedes zufällig passende Zeichen als sein Startzeichen interpretieren und losquatschen. Du kannst dir nun ausmalen was passieren wird wenn du mal mehrere Slaves am Bus hast.
Da RS485 ein halb-duplex Bus ist, braucht man da für einen sicheren Betrieb schon ein kleines Protokoll. Sonst ist auch bei mehreren Byte 'Identifikation' nicht ausgeschlossen, dass sowas zufällig mal in den Daten vorkommt.
Also z.B. blockweise Übertragung mit eindeutigen Anfangs- und Endekennungen. Oder Identifikation ist 128...255, und Daten sind nur Standard-Ascii, bei denen das Bit7 immer 0 ist.
Irgendwas muss man sich da überlegen und festlegen.
paulpaulson:
BTW:
RS485 ist nur eine Verpackung in der die Daten versendet werden. Für den Labortisch langen zwei Arduinos mit gekreutzen RX/TX Leitungen.
Das ist dann genau das Testszenario, wo man die oben angesprochenen Probleme nicht erkennt. Es ist eben nicht nur eine andere 'Verpackung'. Das Besondere ist der halb-duplex Busbetrieb, und der muss per Protokoll organisiert werden. Wie man das macht, legt die RS485 aber nicht fest.
Habe mich heute mal hingesetzt und anhand eurer Hilfe einen ersten Empfänger Grund Gerüst geschrieben.
Der Schematische Ablauf ist folgender:
Der Empfänger bekommt ein Startbit "0xFF" Sobald dieses erkannt wird Speichert er alle Empfangen Daten in ein Array. Nach dem das End Bit gekommen ist (0xEE), überprüft das Programm ob die
Empfänger Adresse richtig ist (erstes Gespeicherte Array (0-255). Falls dieses Richtig ist könnte man jetzt die Empfangen Nachricht weiterverwerten.
Nun weiß ich gerade leider nicht so genau wie ich die Array daten wieder in Einzelne INT bekomme um diese Separat zu verwenden.
Ändere bitte mal die quote (=Zitat) in code Tags. Bei der Gelegenheit kannst Du auch gleich die unnötigen Leerzeilen entfernen.
Mein Fehler sry
Ich hatte Vorhin vergessen zu erwähnen für welches Protokoll Muster ich mich entschieden habe.
Mein Code Soll Sich Aus Folgendem Zsm. Setzen
Startbyte -> Adressenbyte -> Aufgabenbyte 1 -> Aufgabenbyte 2 -> 5 Datenbytes -> Wertbytes -> Endbyte
Startbyte (0xFF)
Adressenbyte 0x01-0xEE
Aufgabenbytes ( W;R;S) je nachdem ob der Slave Was machen was senden oder ins Setting Menü gehen soll
Beide Aufgabenbytes müssen Identisch sein
Datenbytes: Zum übermitteln von aus /an zuständen oder simplen werten.
Wert Byte Zum übermitteln von Großen zahlen bzw. Werte mit Kommastellen. Soll mit Trennzeichen übermittelt werden und dann wieder Auseinandergezogen werden.
Endbyte (0xEE);
An sich habe ich die Grund Funktionen schon implementiert, nur Scheitere ich schon die Ganze zeit dran aus dem Empfangsarray Buffer die Werte wieder zu trennen.
Ist das überhaupt möglich oder ist meine Vorgehensweiße schonmal komplett falsch?
Dann wäre es gut, wenn Du vor dem Endebyte ein 0-Byte einfügen würdest oder bei Erkennung des Endebytes eine 0 ins Array am Ende einträgst. Dann kannst Du das mit strtok problemlos zerlegen und mit atof wieder in Fließkommawerte umsetzen. Hier mal ein paar Infos dazu.
Gesendet werden daten wie Temperatur / Luffteuchte / Co2 Werte etc.
Typische Float werte.
du schreibst oben
Startbyte (0xFF)
Adressenbyte 0x01-0xEE
Aufgabenbytes ( W;R;S) je nachdem ob der Slave Was machen was senden oder ins Setting Menü gehen soll
Beide Aufgabenbytes müssen Identisch sein
Datenbytes: Zum übermitteln von aus /an zuständen oder simplen werten.
Wert Byte Zum übermitteln von Großen zahlen bzw. Werte mit Kommastellen. Soll mit Trennzeichen übermittelt werden und dann wieder Auseinandergezogen werden.
Endbyte (0xEE);
und jetzt hätt ich gern von dir eben eine klare Spezifikation und reichlich Beispiele die zu dieser Spezifikation passen
nur zum Beispiel:
FF 01 77 AA 00 00 00 00 EE
FF Startbyte
01 Addresse
77 w für write???, r für read?, s für schmeck's?
AA Datenbyte heißt was? Ist das ein Identifer/Tag für den nachfolgenden Wert?
00 00 00 00 ein int32, oder ein float, irgend ein 4byte typ halt, oder willst das abhängig vom Datenbyte?
EE das Endbyte
Ich Saß gestern Abend noch recht lang am Programm und habe mir gedanken gemacht nun bin ich auf folgendes Resultat gestoßen .
FF 01 77 00 00 00 00 00 EE
FF Startbyte
01 Addresse 01-FF ( Abzüglich FF,EE,DD
54 G / T / S / D / Z G/T/S bedeutet immer das eine Naricht von Master für Slave kommt
G = Give Slave weis er muss was ausführen;
T = take Slave Weiß er muss was Senden
S-Setting Slave geht in einen Einsetllungsmodus
D und Z bedeutet das eine NAricht vom Slave zum Master geht
d = Data Kündigt dem Master an das gleich daten kommen
z = Dient einfach nur als Rückmeldung famit der Master weiß das der Slave alles Richtig gemacht hat
00 00 00 00 00 Beim Protokoll sollen immer 5 Bytes mitgeschickt werden welche Simple Zustände Übertragen
EE das Endbyte
Falls nun aber auch Werte wie Floats gesendet werden müssen ( Im falle eines Slave Sensors zbs)
Wird anstelle des Endytes ein DD Byte gesendet welches Die String abfragen einschaltet.
Ich habe das dann gestern versucht mal das ganze als code niederzuschreiben :