Serial adressierung

Hallo

ich möchte mit einem Mega daten an mehrere unos senden.

um datenverkehr und speiche zu sparen will ich z.b. dezimal werte bis 255 direkt als 1 byte übertragen statt 3 ASCII zeichen.

wenn nun der eine uno die adresse A hat sende ich zuerst das A (65) und dann den rest der daten

also z.b. "65 255 66 140"
nun da alle diese daten empfangen fängt der uno mit der adresse B leider bei der 66 auch an mit zu hören.

meine überlegung war schon einfach per Serial.readBytes() das ganze paket in ein array zu speichern und dann wegen der adresse eben nur das erste byte überprüfen.

das blöde ist nur das die pakete immer unterschiedlich groß sind und ich somit keine genaue größe angeben kann.

andere überlegung war ein end byte hinzu zu fügen. z.b. '/n' das blöde ist nur wenn dann das datenpaket so aussieht...

"65 10 66 140 10"
sollte es so interpretiert werden
(A 10 66 140 '/n')
aber leider kommt es so an
(A '/n' B 140 '/n')

A liest nichts da es sofort das end byte bekommt und B versucht was mit der 140 an zu fangen obwohl es ja eigentlich für A bestimmt war

klar ich könnte eine library verwenden die dafür gedacht ist.
nur ich möchte ja wie oben erwähnt speicherplatz sparen und da in einer library meist mehr drinn ist als man benötigt kommt das nicht in frage.

zu dem will ich gerne wissen wie das ganze funktionirt und nicht blind fertige schnipsel zusammenkleben...

Hoffe mir kann jemand helfen...

Erstmal:
Die Serielle Schnittstelle ist kein Bus.
“Mehrere” Unos ist also verboten.

Alternativ:
Ein Umbau auf RS485
Oder ein Tokenring Verfahren
Oder I2C verwenden

Wie auch immer…
Ein Protokoll wird nötig sein.

ja rs485 ist wegen der späteren abstände eingeplant.
nur die daten die dann ankommen sind ja die gleichen...

habe auf der suche nach einer lösung schon davon gelesen das ein eigenes protokoll zu schreiben garnicht so schwer ist. nur stoße ich da doch auf die gleichen probleme oder etwa nicht

nur stoße ich da doch auf die gleichen probleme oder etwa nicht

Wenn du meinst....

Tipp:
Dauernde Kleinschreibung ist ein Protokollverstoß.
Das hier verwendete Protokoll nennt sich "Deutsche Sprache".

In die Zukunft gesehen:
Sorgfalt und Disziplin lassen dich dein Ziel erreichen.

:o :o :o

Nagut, wenn du da so viel Wert drauf legst.

Es sollte aufgefallen sein, dass ich in diesem Bereich nicht sonderlich viel Erfahrung habe.
Trozdem will ich das lernen und verstehen wie es funktioniert.

Hoffe mir kann trozdem jemand weiterhelfen.

Wenn man ein Protokoll erfinden will ....

Daten bettet man in einen Rahmen ein.
Zum Beispiel:

  1. Startkennung
  2. evtl. Quell und Ziel Adresse
  3. evtl. Längenangabe
  4. Nutzdaten
  5. Prüfsumme

Was Du brauchst ist eine Art Protokoll, das definiert was wann wie an wen übertragen wird. Wie die Übertragung technisch realisiert wird ist dabei erstmal nebensächlich.

Wenn die Länge des Datenpaketes bekannt ist (auch wenn sie dynamisch ist), dann kannst Du ja als erstes die ID des angesprochenen Ziels senden (1 Byte) und dann die Länge der folgenden Daten als 2 Byte, dann kannst Du bis 64k übertragen. Wenn es immer weniger als 256 bytes pro Übertragung sind, dann reicht auch ein Byte.

Also:

<ID:8><length:8><data:8*(length)>

Zusätzlich kannst Du z.B. noch einen CRC Prüfsumme als letztes Byte übermittlen, damit der Empfänger prüfen kann ob die Daten korrekt sind.

Mario.

Xasir:
ja rs485 ist wegen der späteren abstände eingeplant.
nur die daten die dann ankommen sind ja die gleichen...

habe auf der suche nach einer lösung schon davon gelesen das ein eigenes protokoll zu schreiben garnicht so schwer ist. nur stoße ich da doch auf die gleichen probleme oder etwa nicht

Das ist falsch.

RS485 ist ein Busprotokoll mit Adressierung, das auf RS422 aufbaut. RS422 gibt dabei die physikalischen Parameter vor, also keine Spannungsschnittstelle sondern eine Differentialschnittstelle. RS485 ist dann für den Datenfluss zuständig. RS232 kann man mit Ethernet oder WLAN vergleichen, während RS485 eher dem IP/TCP entspricht.

Du kannst zwar TX auf 2 RX connecten aber nicht 2 TX auf einen RX. Das wäre aber nötig um zurück zu melden von Slave zu Master. Sobald dann ein TX auf HIGH geht und der andere noch auf LOW steht hast du auf der selben leitung GND und +5V drauf geschaltet von 2 verschiedenen Ausgängen. Das gibt Schrott.

Bau also vorerst mal auf RS485 mit der richtigen Bibliothek und den richtigen Umsetzern die Kurzschlussfest sind, weil sie als OpenCollector arbeiten. Irgendwann wenn du tiefer in die Materie eingestiegen bist kannst auch mal eigene Protokolle entwickeln.

2 TX auf einen RX gehen mit entsprechender Logik schon. Vielleicht sogar für Arme mit 2 Dioden. Habs noch nicht getestet. Ob es Sinn macht, sei dahingestellt.
Ich würde sagen, mit einem kleinen Protokoll kommt er da schon ans Ziel. Oder notfalls sogar mit Byte stuffing

Mit Schutzbeschaltung gehts, trotzdem wird die Kommunikation des einen die des anderen stören. Du hast dann ja immer noch keine Collisionsdetekt.

Also besser nicht machen, ein Quell ewiger Fehlersuche.

Das regelt ja auch ein Protokoll.

Für die Langstrecke nehme ich jeweils einen max485.
Wenn ich da doppelt sende, kommt auch Datenmüll bei rum.

Bin bis jetzt immer davon ausgegangen das rs485 nur die physikalische norm ist.
Und rs485PRO das dazugehörige Protokoll.

Wohl etwas aneinander vorbei geredet... :o

naja ich versuch mal was zusammen zu bauen. danke an alle

chefin:
RS485 ist ein Busprotokoll mit Adressierung, das auf RS422 aufbaut. RS422 gibt dabei die physikalischen Parameter vor,...

Das ist falsch!
RS422 ist was anderes. Es ist z.B. nicht Kurzschlussfest.

Bin bis jetzt immer davon ausgegangen das rs485 nur die physikalische norm ist.

Das ist richtig.
Man kann durchaus verschiedene Protokolle darauf "fahren"

hi,

sorry, aber RS232, RS422 und RS485 sind allesamt keine protokolle. das sind einfach standards, die die art der physischen übertragung festlegen. RS485 verwendet im gegensatz zu RS422 kurzschlussfeste ausgänge, also können mehrere teilnehmer gleichzeitig senden, ohne daß was kaputtgeht.

zur adressierung: brauchst Du die wirklich? nur dann, wenn mehr als ein empfänger die exakt gleiche funktion ausführen soll.
ein beispiel: wenn Deine "zentrale" befiehlt: "schalte das licht im wohnzimmer ein!", warum sollten das nicht alle hören? es wird ohnehin nur der reagieren, der die funktion "licht im wohnzimmer einschalten" kennt.

zur länge der daten: ich sende (größtenteils) nur zwei byte. einen befehl und einen wert. z.B. 46 7
46 für vorzimmerlicht und und 7 für dimmstufe 7 (0 für aus). dafür verwende ich readBytes(buffer, 2).

wenn ich aber 101 144 senden, weiß der client im wohnzimmer durch die 101, daß ich seine grundwerte sende (da stehen z.B. die werte für die dimmstufen drin). die länge der daten ist 144 bytes, also readBytes(buffer, 144).

übrigens: wenn Du nicht groß schreiben willst, laß es. hier ist nicht das deutsche rechtschreibforum oder mikrocontroller.net.

gruß stefan

PS.:die einstellung "lieber selber machen als fertige bibliotheken" gefällt mit, bin genauso. aber oft spart man damit keinen platz, weil der compiler nur die verwendeten funktionen einbindet.

PPS.: ich kenne rs485PRO nicht, aber es ist nicht "das zugehörige protokoll", sondern "ein mögliches protokoll".

übrigens: wenn Du nicht groß schreiben willst, laß es. hier ist nicht das deutsche rechtschreibforum oder mikrocontroller.net.

Ich persönlich gebe mir große Mühe meine Postings in verständlicher Sprache zu schreiben. Auch finde ich dass die Technik schon schwierig genug ist, da muss man die Texte nicht noch künstlich verwirren.
Warum soll ich mir beim Antworten mehr Mühe machen, als es der Fragesteller tut?

Erfahrung:
Wer schlampiges Deutsch schreibt, programmiert in der Regel auch schlampig.

Von mir aus darf jeder schreiben wie er/sie/es will.
Aber er/sie/es riskiert, keine Hilfe von mir zu bekommen, oder auch mal Kollisionen, so wie wir beide gerade eine haben.

Warum vereinfacht Großkleinschreibung die Texterfassung?
Beispiele:

Die Spinnen
Die spinnen

Der gefangene Floh.
Der Gefangene floh.

Er verweigerte Speise und Trank.
Er verweigerte Speise und trank.

Der Junge sieht dir ungeheuer ähnlich.
Der Junge sieht dir Ungeheuer ähnlich.

Wäre er doch nur Dichter!
Wäre er doch nur dichter!

Vor dem Fenster sah sie den geliebten Rasen
Vor dem Fenster sah sie den Geliebten rasen

Er hat in Berlin liebe Genossen.
Er hat in Berlin Liebe genossen.

Warme Speisen im Keller
Warme speisen im Keller

Beschädigte Liegen in meiner Filiale.
Beschädigte liegen in meiner Filiale.

Die nackte Sucht zu quälen.
Die Nackte sucht zu quälen.

Warum sind füllige Frauen gut zu Vögeln?
Warum sind füllige Frauen gut zu vögeln?

Sich brüsten und anderem zuwenden.
Sich Brüsten und anderem zuwenden.

Sie konnte geschickt Blasen und Glieder behandeln.
Sie konnte geschickt blasen und Glieder behandeln.

Helft den armen Vögeln.
Helft den Armen vögeln.

Schwester, würden sie mir bitte einen Blasen- oder Nierentee bringen?
Schwester, würden sie mir bitte einen blasen oder Nierentee bringen?

ergänzung:

wegen des gegensendens gehe ich so vor, daß der angesprochene teilnehmer die gleichen zwei bytes zurückschickt und damit der sender weiß: alles ok. nachdem einer etwas gesendet hat, darf kein anderer als der angesprochene eine zehntel sekunde was losschicken, das ist klar.

übrigens: ein vorteil der nicht-adressierung ist, daß sich auch mehrere angesprochen fühlen können. wenn ich den lichtschalter im vorzimmer betätige, sendet der eingebaute sender 46 20 über RS485. wir erinnern uns: 46 ist vorzimmerlicht. 20 ist die höchste dimmstufe. der teilnehmer in der decke empfängt und schaltet das licht.

die "zentrale" empfängt es auch und weiß jetzt, wie das vorzimmerlicht geschalten ist und aktualisiert die webseite, über die ich auch steuern kann.

gruß stefan

Selber machen bedeutet ja nicht zwangsläufig das Rad (Protokoll) neu zu erfinden.
combie beschreibt z.B. fast das OBD II Schema.

combie:

  1. Startkennung
  2. evtl. Quell und Ziel Adresse
  3. evtl. Längenangabe
  4. Nutzdaten
  5. Prüfsumme

Womit der Eisebaer vollkommen Recht hat, ist dass Du ohnehin jeden Empfänger alles lesen lassen musst. Ob der Befehl ihm gilt oder nicht. Sonst weiß dieser ja nicht wann die Nachricht zu ende ist und er wieder lauschen muss.

Nun ist wichtig ob alle Arduinos gleich programmiert sind oder wie bei Stefan nur ein Arduino die Funktion "46" hat. Bei letzterem die Befehle einfach Arduino-übergreifend durchnummerieren:

Befehl + Länge + Wert(e) [+ Checksum]

Sonst:

Empfänger + Befehl + Länge + Wert(e) [+ Checksum]

Um beim OBD II Protokoll zu bleiben: Dort werden die erfolgreichen Befehle mit 0x40 addiert. Damit ist klar, dass alles >64 eine Antwort darstellt.
Damit kann man dann umgehen, das die Zentrale ein "Echo" anstelle einer Bestätigung empfängt.
Das bezieht sich natürlich nur auf eine Lösung ohne Empfänger.

@Combie: Danke für die ausführliche Auflistung der Beispiele für unterschiedliche Inhalte bei Groß-/Kleinschreibung.

Gruß Tommy

combie:
Das ist falsch!
RS422 ist was anderes. Es ist z.B. nicht Kurzschlussfest.

Das ist richtig.
Man kann durchaus verschiedene Protokolle darauf "fahren"

Stimmt RS422 nutzt TX und RX, hat aber keine Definition der höheren protokollschichten. Meist setzt man also RS232 Layer3 Ebene ein, Startbit, Datenbits, Stopbits, keine Frames, keine Adressierung. Aber RS422 definiert das man Differenzialsignale nutzt. Wer also einen Spannungs-differentialumsetzer nutzt diese dann mit dem serial-befehl über TX und RX Leitungen benutzt fährt kein 485. In 485 sind auch höhere Protokollschichten definiert, zb das Kurzschlussfest sein muss, weil TX und RX über eine Leitung geht. Das man zuerst hören muss bevor man senden darf (collision-detect) und das man Master-Slave fährt und ein Master über bestimmte Sequenzen seine Slaves findet und ihre Adressen. Dann spricht er Slaves direkt an.

Gleich im ersten Satz wird erklärt das es nur die physikalischen Eigenschaften beschreibt, nicht das Protokoll. Und ohne Protokoll kann man nicht kommunizieren. Also ist RS422 keine vollständige Schnittstellenbeschreibung.

Weiter unten liest man dann auch das die physikalischen Parameter von RS485 fast gleich sind und die Treiberbausteine fast immer beides können. Weil man auch RS422 OpenCollector betreibt und nicht mit Stromtreibern. Und daher eigentlich kein Kurzschluss entsteht, allerdings 2 TX auf einer Leitung ergeben IMMER Störung. Nur muss das in den höheren Protokollschichten geregelt werden. Man baut keine dedizierten RS422 Treiber die NICHT Kurzschlussfest sind mehr. Theoretisch stimmt deine Aussage, praktisch ist sie schon lange hinfällig geworden.

Auch hier wird RS422 als Untermenge von RS485 angesehen. Auch Ethernet gehört eigentlich in diese Gruppe, weil auch Ethernet differentialleitungen benutzt. Ebenso muss man MODBUS, CANBUS, Profibus in dieser Liga eingruppieren, da sie sich physikalisch nicht unterscheiden, nur die Protokollschichten ab 3 Aufwärts, also Adressierung und Datentransport. Das was in Ethernet als IP und TCP verstanden wird.

Leider kommt man nur schwer noch an die offiziellen Dokumente ran, weil sich EIA aufgelöst hat

Man kann bei diversen Verlagen die Normen noch kaufen, hat aber Copyright drauf, darfs also nicht online stellen. Allerdings haben wir diese Normschriften auch nicht im Portfolio. Eher die einschlägigen Schriften zu EMV und BGV bzw heisen die ja inzwischen DGVU (Deutsche Gesetzliche Unfallversicherung statt Berufsgenossenschaftliche Versicherung).

Das meiste funktioniert halt heute irgendwie, weil die Bausteine hohe Toleranz haben bzw so universell ausgelegt sind.

hi,

der TO ist erstmal ausgestiegen, also stricken wir hier aus spaß weiter. :slight_smile:

Wer also einen Spannungs-differentialumsetzer nutzt diese dann mit dem serial-befehl über TX und RX Leitungen benutzt fährt kein 485. In 485 sind auch höhere Protokollschichten definiert, zb das Kurzschlussfest sein muss, weil TX und RX über eine Leitung geht. Das man zuerst hören muss bevor man senden darf (collision-detect) und das man Master-Slave fährt und ein Master über bestimmte Sequenzen seine Slaves findet und ihre Adressen. Dann spricht er Slaves direkt an.

NEIN !

RS485 ist zur gänze layer 1. wie RS422, nur kurzschlußfest, aber auch das ist natürlich layer 1. definiert wird nur, wie EIN BIT übertragen wird.

es wird keine collision detection beschrieben, keine frames, kein protokoll, kein master-slave, keine adressierung oder wer senden darf.

gruß stefan

Ich halte mich in der Regel an offizielle Beschreibungen und nicht an das was irgendwo dann draus gemacht wird.

Und wenn man den Arduino benutzt mit seriellem Protokoll aber Differentialtreibern ist das allenfalls RS422.

Natürlich steht es jedem frei sich seine Bezeichung selbst zu wählen. Du kannst das also nenen wie du willst, der Funktion tut das keinen Abbruch. Lediglich...meine hier im Einsatz befindlichen Geräte wirst du damit nicht kontaktieren können.

Weder Profibus noch CANbus noch ModBUS verstehen dich, wenn du mit differentiellen Treibern aber serieller Kommunikation loslegst. Weil RS485 eben auch die Adressierung übernimmt, Layer 3 und 4 im OSI-Modell. Ohne das hast du eben kein 485 sondern irgendwas mit differentiellen Treibern. Diese Layer 3 und 4 Normen darf man nicht einfach weglassen und sagen man hätte das gleiche