Hallo Forum, ich hab grad mal ein kleines Problem. Zwar möchte ich über die Serielle Schnittstelle Pakete senden und empfangen. Diese haben folgenden Aufbau an Nutzdaten: [1Byte ID][nBytes Wert] So wie kann ich die Pakete nun am besten verschicken? Also wie erkenn ich Anfang und Ende? Klar durch Start/Stoppbyte. Nur was nehm ich da als Codierung? Ich brauch ja alle 8Bit für die Übertragung der Werte und IDs. Es kann ja jede Bitfolge in einem Wert Byte vorkommen. Wie lös ich also das Problem? Oder hab ich da grad nen Denkfehler? Mein Überlegung war noch das ich nur 7Bit für den Inhalt, und 1 Bit dann für die Erkennung ob Startbit oder nicht. Aber dann brauch ich ja um ein 8Bit Wert zu übertragen schon 2 Byte... Gruß Uwe
> So wie kann ich die Pakete nun am besten verschicken?
Wie ozo schon sagte: eins nach dem anderen, aber bitte
nicht wild durcheinander !
Wenn du 0x00 nicht als End-Byte nehmen kannst, wie wärs mit base64-Codierung? Die Anzahl kannst du zusätzlich übertragen, falls ein Paket verloren geht kannst das dann feststellen.
Das mit dem 9. Bit war auch schon meine Überlegung. Nur können das die meisten Terminal Programme wohl nicht. Die Daten wo ich verschicke sollen dann auch per Labview ausgewertet werden, fraglich ob das damit klar kommt. @holger Da ist nichts wild durcheinander ;) Ein Paket besteht aus 1 Byte wo die ID drin steht, dahinter kommt eine beliebige Anzahl von Bytes wo der dazugehörige Wert steht. Die Pakete sollten so kompakt wie möglich sein. @Minetti Bei der base64 Codierung muss ich ja immer Blöcke mit 3 Bytes verarbeiten. Das erzeugt u.U. wieder viel Overflow. Aber ansonsten eine gute Idee, werde ich mir mal noch genauer anschauen.
Was willst du denn übetragen? Wenn's möglich ist das Ganze ASCII zu übetragen ist das die einfachste Methode. Einfach Startsequenz (mehrere Byte), die Nutzdaten und anschließend eine CRC16-Checksumme schicken. Ich habe auf diese Weise Zählerstände Drahtlos übermittelt und bin sehr zufrieden mit dem Ergebnis. Bei Binärdaten ist das Ganze natürlich etwas komplizierter ...
Ich muss Messwerte von 10 Sensoren auswerten und dann per USART rausschicken. Um die Messwerte zu unterscheiden soll eben eine ID vorne angehängt werden. Da die Sensoren zum Teil mit 1000Hz abgefragt werden, sollten die Pakete nicht unnötig groß sein. Achja, die Messwerte sind also eigentlich nur integer Werte.
Na, da ist ASCII doch prädestiniert für! Kannst dich ja mal am NMEA (GPS) oder Modem-Protokolle orientieren. Baudrate halt etwas hochsetzen (38400 baud oder so), dann klappt das prima!
Ja aber bei ASCII verschwende ich doch pro Zeichen 8Bit, das find ich halt schon etwas viel.
Vergiss die ganzen Posts oben ! Stell deine Schnitstelle auf 1 Startbit, 8 Datenbits, 1 Stopbit ein. Um Startbit und Stopbit musst du dich NICHT kümmern. Das macht die Hardware. Was am Ende rauskommt sind einfach die 8 Datenbits. Wenn du die vernünftig formatierst kann nichts schief gehen. 1:Byte ID wahrscheinlich um auszuwerten wofür das Paket gut ist 2:Byte n gibt an wieviele Datenbytes empfangen/gesendet werden 3:Byte 0 erstes Datenbyte 4:Byte 1 zweites Datenbyte . . . . letztes Datenbyte
Natürlich kannst du das Gaze auch binär übertragen, wie du das codierst bleibt dir überlassen. Am Ende eine CRC-Prüfung, dann klappt das auch. Aber grade wegen der Starterkennung ud IDs ist ASCII eben einfacher.
ja so hatte ich das bisher, nur ohne ein Byte mit der länge. Dann konnte ich aber halt nie unterscheiden wann ein Paket zu ende war. Aber auf die Idee einfach ein Byte mit der Anzahl der Bytes zu senden bin ich nicht gekommen :-( Ich werde mal testen ob das so funktioniert. Und ob Labview das dann korrekt entschlüsseln kann. Kennt jemand sonst noch ne Software die so etwas visualisieren kann?
>1:Byte ID wahrscheinlich um auszuwerten wofür das Paket gut ist
Und wenn ein Datenbyte diesen Wert hat und der Empfänger in diesem
Moment zugeschaltet wird ???
>1000Hz
Und an welche Baudrate hast du gedacht?
Wie wäre es denn, wenn du ein Paket "schnürst", das die Werte der
Sensoren der Reihe nach überträgt.
Interessant ist auch, Temperaturen mit 1kHz abzufragen (vermutlich
irgendein Verbrennungsprozess, da sich die Raumtemperatur in längeren
Intervallen ändert...).
Baudrate? Was der Controller so bringt :D Momentan läufts mit 38400, aber da ist nach oben ja noch etwas Luft. Wie meinst du der Reihe nach? Da gibts das Problem das manche Sensoren eben mit 1kHz (wobei dies noch nicht sicher ist) und manche nur mit 10Hz oder weniger abgetastet werden. Also sollten diese schon sobald ein Wert anliegt verschickt werden. @Sonic Der Empfänger läuft eigentlich bevor der Sender sendet, das sollte erstmal nicht so schlimm sein. Oder hast du grad nen Lösungsvorschlag parat?
Bei der Paketierung muss man nicht ein Bit pro Byte verschwenden, siehe Beitrag "Re: Befehlsschnittstelle erstellen".
Ich habe das bei einem Drahtlossystem so gemacht: EIN Master der alle Slaves nacheinander abfragt. Als Start eine Präambel 0x55 (ist ein Rechtecksignal), danach 2x 0xFF (High-Signal bekannter Länge), hierauf wird der Start der Daten eingeleitet, danach kommen Daten. Am Ende CRC16-Checksumme. Alles was dazwischen kommt kannst du dir einteilen wie du willst. Wenn die Messstellen natürlich willkürlich senden wird's komplizierter.
>Ich muss Messwerte von 10 Sensoren auswerten und dann per USART >rausschicken. Um die Messwerte zu unterscheiden soll eben eine ID vorne >angehängt werden. >Da die Sensoren zum Teil mit 1000Hz abgefragt werden, sollten die Pakete >nicht unnötig groß sein. Autsch ! 10 Sensoren a 2 Bytes plus eine ID. Also sagen wir mal 3 Bytes * 10 mit 1kHz. Das sind 30000 Bytes/s. Bei 8 Datenbits mit 1 Start/Stop Bit sind das 300000 Bits /s. Das macht deine serielle Schnittstelle sicher nicht mehr mit !
Scheiße schon wieder zu spät ;) Könnte er endlich mal eine KOMPLETTE Anforderung rüberreichen ?
@sonic Die Sensoren werden ja vom AVR abgefragt und die Daten auch von dort aus verschickt. @holger Deine Rechnung geht nicht auf ;) Nicht alle 10 Sensoren werden mit 1kHz abgefragt.
Bei der Übertragung von Datenstrings über die serielle Schnittstelle gibt es eine primäre Gefahrenquelle! Und die heisst Synchronisationsverlust. Das heisst, es gibt keine eindeutige Identifikation, an welcher Stelle des Datenstrings man sich gerade befindet. Da in einem binären Datenstring jedes Datenbyte das andere in seinem Wert ersetzen kann, ist es möglich, daß das Protokoll sozusagen außer Tritt gerät. 1. Möglichkeit: Trennung von binären Datenstrings durch eine Zeitlücke, wobei gewährleistet sein muß, daß die Abstände zwischen den Datenbytes im String immer kleiner als die Austastzeitlücke ist. Im Binären Datenstring können Startbyte, Zählbyte, Datenbytes den gleichen Wert annehmen. Sollte im Protokoll ein Fehler auftreten, kann der Anfang des Strings nicht mehr eindeutig identifiziert werden. 2. Möglichkeit: Wie von Sonic schon beschrieben, die Daten als ASCII Werte übertragen. Daher 1 Byte als 2 Zeichen. Dafür brauchst Du dann zwar die doppelte Übertragungsrate, hast aber ein Ultra-felxibles Protokoll. Zeitlücke kannst Du Dir sparen. Wie hoch ist denn Dein Datenaufkommen???
Also die Sensoren werden vom µC abgefragt und aud einen PC (oder ähnlich) per USART übertragen? Dann sammle die Messergebnisse bis der letzte Sensor abgefragt ist und schicke das Ganze in einem festgelegten Protokoll 'raus. Ob da jetzt ein Sensor 10x abgefragt wird ist gegenstandslos, der langsamste gibt den Übertragungsrhytmus vor.
@sonic und gerade das will ich nicht! Die Sensoren sollen schon mit Unterschiedlicher Frequenz abgetastet werden und verschickt werden. Das Datenaufkommen kann ich noch nicht genau bestimme. Zur Test und Kalibrierungsphase sollen die Sensoren so oft abgefragt werden wie der Sensor es her gibt. Dabei müssen nicht alle 10 Sensoren unbedingt übertragen werden. Im späteren Flugbetrieb reicht es sicher wenn man die Abtastrate runter setzt. Nur um das zu beurteilen sollen am Anfang alle Sensorwerte übertragen werden.
Noch ein Vorschlag nach dem gar nicht gefragt wurde. Wenn es nur 10 Sensoren sind, dann würden ja 4 Bit reichen, um die Sensoren zu identifizieren. Bleiben von einem Byte noch 4 Bit übrig (angenommen man sendet 8Bit pro Byte) um die länge zu definieren. Man könnte also noch zwischen 0 und 15 oder 1 bis 16 Datenbyte senden, falls das reicht. So reicht ein Byte für Identifikation und Anzahl der Bytes (Problem ist, dass dann in diesem Byte auch fast jede Information auftauchen kann und ein ausgelassenes Byte die gesamte Kommunikaiton total aus dem Tritt bringt... Gast.
@holger >Deine Rechnung geht nicht auf ;) Nicht alle 10 Sensoren werden mit 1kHz >abgefragt. Danke für die fehlenden Informationen. Ich geh jetzt schlafen und morgen interessierts mich einfach nicht mehr ;)
Andere Variante, ungefähr orientiert an PPP(async): 0xFF trennt Pakete. Kommen im Paket die Codes 0xFE oder 0xFF vor, wird zuerst 0xFE übertragen, danach das ursprüngliche Byte XOR 0x20. Ergibt eindeutige Trennung der Pakete, und kostet anders als Base64 oder andere Recodierungen webder nennenswert Bandbreite (~1%) noch Rechenleistung.
@holger da stehts ;) > Wie meinst du der Reihe nach? Da gibts das Problem das manche Sensoren > eben mit 1kHz (wobei dies noch nicht sicher ist) und manche nur mit 10Hz > oder weniger abgetastet werden. @gast nein das geht leider auch nicht. Ich brauch noch platz für mehrere IDs. Also 6 Bit bräucht ich mindestens.
>Die Sensoren sollen schon mit Unterschiedlicher Frequenz abgetastet werden und
verschickt werden.
Da kriegst du ja jede Menge Kollisionen 'rein, wie soll denn das gehen?
Was für einen BUS benutzt du da? Mit CAN geht das meises Wissens, mit
I²C auch. Aber mit RS232 wird das nicht funktionieren!
@A.K. Also so eine Art ByteStuffing? @sonic Ich versteh das Problem nicht ganz. Die Sensoren sind an den I/O Ports des AVRs angeschlossen. Oder am ADC.
ja genau, der AVR dient im Prinzip nur dazu die Sensoren auszuwerten und die Daten an den PC zu schicken.
Google mal nach "Consistent Overhead Byte Stuffing"... Eine ziemlich einfache und dennoch geniale Lösung, um sämtliche 0x00-Bytes aus den Nutzdaten herauszufiltern um die 0x00 dann als Trennzeichen verwenden zu können; und das bei annähernd garkeinem Overhead.
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.