Hallo an alle, ich suche schon ziemlich lange nach einer Lib oder einem Standard für die serielle (UART) Kommunikation zwischen µC und PC bzw. µC und µC. Anwendungsfall wäre üblicherweise folgender: Ich hab irgendein Gerät mit einem (relativ kleinen) µC (Atmega o.Ä.) der per UART (+ FTDI, CP2102) an einem PC hängt. Jetzt möchte ich Datensätze (z.B. aus C Strukturen) an ein Computerprogramm übertragen und dort nutzen und natürlich auch wieder zurück übertragen. Jetzt kann man sich natürlich selbst irgendein Übertragungsprotokoll ausdenken und das ständig anpassen. Ist fehlerträchtig, aufwendig und unflexibel. Hat das jemand schon mal intelligenter und universell gelöst? Diese Problemstellung kann ich ja kaum alleine haben... Ich hab mir schon mal Protobuf bzw. nanopb angeschaut. Zum Verpacken von Strukturen in Arrays OK, aber das löst ja noch nicht die serielle Übertragung. Also ich muss ja auch noch wissen wo ein Datenpaket anfängt und aufhört usw. Die point to point Protokolle aus dem Ethernet Bereich sind irgendwie viel zu mächtig und groß für den kleinen µC. Btw. ich hab jetzt nicht das Problem ein Array per UART zu übertragen oder so. Da gibt es ja je nach µC Libs zu. Wie löst ihr sowas? Gruß!
:
Verschoben durch Moderator
KISS ist klein und hat wenig Overhead. Wenn du dazu noch ein CRC16 spendierst, ist es fast 100% wasserdicht.
> Jetzt kann man sich natürlich selbst irgendein Übertragungsprotokoll ausdenken und das ständig anpassen. Ist fehlerträchtig, aufwendig und unflexibel. > >Hat das jemand schon mal intelligenter und universell gelöst? Diese Problemstellung kann ich ja kaum alleine haben... Man kann sich selbst ein universelles Uebertragunsgprotokoll ausdenken. Weshalb sollten das irgendwelche Anderen besser koennen ? Du kennst die Anwendungsfaelle, du kennst die Resourcen. Man hat nicht immer alle Moeglichkeiten, auch mit fast unlimitiertem Aufwand. Ist es : -Punkt zu punkt, Master-Slave, oder Multimaster -konstante oder variable Paketlaengen -soll man am Terminal mitlesen koennen(ASCII), oder Binaer -wie hoch kann die Ausfallrate sein -muessen die Daten ankommen, oder ist das eher nicht so wichtig -sind Retries moeglich, oder eher nicht. Man kann ein Protokoll an diese Anforderungen anpassen. Die Punkte sind kein witz, existieren alle als Implementationen, resp Implementationsdetails.
:
Bearbeitet durch User
Bimbo 3. schrieb: > Hat das jemand schon mal intelligenter und universell gelöst? Diese > Problemstellung kann ich ja kaum alleine haben... Schon. Benötigt aber doch etwas mehr Framework und ist ev. zu schwergewichtig für deinen Zweck, obwohl's auch auf einem Atmel 32U4 bei mir über UART läuft. Nennt sich intern "network property protocol". Die Geräte beschreibst du dabei in einer XML-Sprache. Source&Demo findest du hier zur Inspiration: http://section5.ch/index.php/2017/09/12/netpp-for-windows-quick-start/ Was damit nicht geht, sind Bulk-Übertragungen von struct-Containern, das musst du in der Version noch mit BUFFER-Datentypen machen. Lohnt sich alles aber erst, wenn du eine Menge Gerätetypen, die sich auch noch ändern können, mit einem Protokoll erschlagen willst.
In der Industrie gibt es natuerlich viele Protokolle. Ein relativ verbreitetes und auch offenes (du findest Dokus) ist Modbus. Der Vorteil, neben der vorhandenen Doku, besteht darin das du auch Diagnosetools auf dem PC nutzen kannst. Eine andere Moeglichkeit waere natuerlich CAN-Bus, setzt aber in der Regel einen Microcontroller vorraus der das unterstuetzt. Und selbst wenn man was komplett eigenes macht, es empfiehlt sich die Doku von so einem Industriekram mal zu lesen weil man dann einige kluge Ideen uebernehmen kann. (Pruefsummen, Blockcounter, Laengen usw) Olaf
Bevor man sich in Details wie CAN, RS485, usw verheddert sollte man sich vergewaertigen was mit Paketverlusten geschehen soll. -Sind egal, Retries genuegen -Sind egal, weitermachen, verlorene Daten sind nicht so wichtig. -Paketverluste sollten minimiert werden Denn je nachdem haben sie Einfluss auf die Uebertragunsgrate und Reaktionszeit. Weiter : gibt es Kriterien an die Reaktionszeit, resp Brutto Uebertragunsgrate. Die Loesung ist nicht immer die Baudrate.
:
Bearbeitet durch User
Bimbo 3. schrieb: > ich suche schon ziemlich lange nach einer Lib Oder hast du einfach nur keine Lust dir was eigenes auszudenken? Generation "LIB" und Generation "Arduino". Du könntest dir - gerade für RS232, RS485 und UART - eine Modbus LIB schreiben. Ja, die gibt es auch für AVR garantiert irgendwo schon frei zum downloaden - oder du schreibst sie an einem Tag selber und weißt dafür, wie sie funktioniert.
Ich verwende gerne http://www.ibrtses.com/embedded/shortmsgprotocol.html oder für größere Datenmengen http://www.ibrtses.com/embedded/longmsgprotocol.html Das hat man realativ schnell umgesetzt und funktioniert gut. Achtung, er beschreibt seine Funktionsrümpfe in Pascal ;-)
Bimbo 3. schrieb: > Jetzt möchte ich Datensätze (z.B. aus C Strukturen) an ein > Computerprogramm übertragen und dort nutzen und natürlich auch wieder > zurück übertragen. Datensätze? Für sowas gibt es nirgendwo ein allumfassendes Protokoll, was allen Ansprüchen genügt. Also ist der Entwurf für was Eigenes wohl immer nötig. Laß mal die Vorstellung von Datensätzen beiseite und beschränke dich auf das Übertragen von Daten - und zwar soweit möglich im Klartext (ASCII), weil du damit fast automatisch einige Sicherheiten eingebaut hast: Du hast die Möglichkeit, z.B. zeilenweise zu senden und zu empfangen, womit du schon mal die Synchronisierung hast, dazu Trennzeichen zwischen Daten-Teilen, eigentlich beliebige Datenformate und so. Denkbar ist aber auch eine Art UPN, also Zahl zuerst (in ASCII), dann ein Buchstabe als Trenner und Kommando zugleich. Denkbar ist ebenfalls, den Zahlenbereich 0..255 von übertragenen Bytes in passable Gruppen zu unterteilen. Ich hatte das für meine Alternativ-Software für den FA-NWT so gemacht, um zugleich Wobbeldaten vom Gerät zum PC sowie Kommando- und Statusverkehr zwischen Gerät und PC zu übertragen. W.S.
Hallo, für das, was Du möchstest, hat sich im Embedded Bereich JSON als Applikationsprotokoll etabliert, wobei da aber natürlich nicht die tieferen ISO Schichten (Busadressierung, Framing etc) adressiert sind. Ich habe ein Protokoll entworfen, das deine Voraussetzungen so ziemlich erfüllt. Es heisst UTISCP (Universal Transport Independent Securable Communication Protocol) und ist z.Zt. bei mehreren industriellen Kunden in der Pilotphase. Der Applikationslayer ist komplett konfigurierbar, d.h. Du kannst auf demselben Basisframing verschiedene Applikationsprotokolle nebeneinander fahren. Es wird letztendlich offen sein und nichts kosten, aber während der Pilotphase ist ein NDA Voraussetzung (bis eventuelle Kindekrankheiten raus sind, will ich wissen, wo es ist und wer damit schafft). Interessenten dürfen sich gerne per PM oder über meine HP (www.ruediger-asche.de) melden.
Ich würde mal noch msgpack in die Runde werfen: https://msgpack.org/ "It's like JSON. but fast and small."
@ Nils N. (nils_h494) >> ich suche schon ziemlich lange nach einer Lib >Oder hast du einfach nur keine Lust dir was eigenes auszudenken? >Generation "LIB" und Generation "Arduino". Nö, der macht das schon richtig und will das Rad NICHT neu erfinden. Warum sollte jeder seinen OneWire, LCD, Ethernet, TCP/IP Treiber selber schreiben? Wiederverwendung bestehender, getesteter und BEWÄHRTET Komponenten war schon immer sinnvoll, nicht erst im IT-Zeitalter.
Daniel V. schrieb: > Ich verwende gerne... Das hat den Nachteil, daß man erstens nur blockweise arbeiten kann und zweitens (schwerwiegender) nicht zwischen Daten und Steuerzeichen unterscheiden kann: [SYN+] STX Len SRC DST Cmd [Data] CRC bzw. [SYN++] STX (LenLo LenHi) SRC DST Cmd [Data] (CRCLo CRCHi) Hierbei muß man immer den Blockbeginn kennen, sonst funktioniert das Ganze überhaupt nicht. Dieses Protokoll ist rein binär und deshalb eben nicht selbstsynchronisierend. Es kommt noch etwas hinzu: bei rein binären Formaten ist man darauf angewiesen, daß beide Geräte intern exakt die gleiche Darstellung haben. Das geht öfter als einem lieb ist in die Hose. Ich hab lange genug Daten austauschen müssen zwischen Geräten mit internem big endian und solchen mit little endian - und da kracht es eben immer, sobald Daten länger sind als 8 Bit. Ein ähnliches gilt für numerische Daten im Gleitkommaformat. Also tut man gut daran, auf einer seriellen Schnittstelle mit endianfreien Daten zu arbeiten, z.B. eben mit reinem ASCII-Text. Das braucht zwar ein paar Zeichen mehr zur Übertragung, aber dafür ist es unabhängig von den Interna der beteiligten Geräte. W.S.
W.S. schrieb: > Daten austauschen müssen zwischen Geräten mit internem big endian und > solchen mit little endian Das kann man auch konvertieren, wenn man das mit Bitshifts macht ist das auch portabel. Wenn es nur um uC<->PC geht könnte man sich überlegen USB direkt zu nutzen. Da muss man keine Paketanfänge erkennen und keine Flusskontrolle und Fehlereekennung implementieren, weil das da schon die Hardware macht. Natürlich ist einiges an Basis Software nötig, aber wenn man die einmal hat (als Library oder selbst gemacht) braucht man nur noch seine eigenen Daten zu übertragen. Siehe z.B. USB-Tutorial mit STM32. Soll es doch UART sein, kann man Paketanfänge über den IDLE Interrupt (d.h. die Pause zwischen Paketen) erkennen und danach ein Paket am Stück empfangen. Eignet sich auch gut für DMA-fähige Controller.
> Also tut man gut daran, auf einer seriellen Schnittstelle mit
endianfreien Daten zu arbeiten, z.B. eben mit reinem ASCII-Text.
Ach soooo? ... waere '1234' also 1234, oder eher 4321, alles als ASCII?
Da man den Code auf beiden Seiten schreibt, solle es doch moeglich sein,
die Meldungen richtig zu formatieren. Man muss nicht bitshiften, sondern
Bytes in der passenden Reihenfolge senden.
Ob bei Little Endian, oder Big Endian, die Bytes sind auf alle faelle 1
& 2 & 3 & 4, in ASCII geschrieben.
Falk B. schrieb: > @ Nils N. (nils_h494) > >>> ich suche schon ziemlich lange nach einer Lib > >>Oder hast du einfach nur keine Lust dir was eigenes auszudenken? >>Generation "LIB" und Generation "Arduino". > > Nö, der macht das schon richtig und will das Rad NICHT neu erfinden. > Warum sollte jeder seinen OneWire, LCD, Ethernet, TCP/IP Treiber selber > schreiben? > > Wiederverwendung bestehender, getesteter und BEWÄHRTET Komponenten war > schon immer sinnvoll, nicht erst im IT-Zeitalter. Was ja per se auch vollkommen in Ordnung ist. Aber gerade ein kleines, simples Protokoll hätte er schneller selber programmiert, als "ich suche schon ziemlich lange nach einer Lib".
W.S. schrieb: > Daniel V. schrieb: >> Ich verwende gerne... > > Das hat den Nachteil, daß man erstens nur blockweise arbeiten kann und > zweitens (schwerwiegender) nicht zwischen Daten und Steuerzeichen > unterscheiden kann: > > [SYN+] STX Len SRC DST Cmd [Data] CRC > bzw. > [SYN++] STX (LenLo LenHi) SRC DST Cmd [Data] (CRCLo CRCHi) > > Hierbei muß man immer den Blockbeginn kennen, sonst funktioniert das > Ganze überhaupt nicht. > > Dieses Protokoll ist rein binär und deshalb eben nicht > selbstsynchronisierend. > Ich glaube du irrst dich. In meinen Implementationen habe ich sehr wohl eine Selbstsynchronisierung. Das kann man bei EMV-Tests sehen. > > Also tut man gut daran, auf einer seriellen Schnittstelle mit > endianfreien Daten zu arbeiten, z.B. eben mit reinem ASCII-Text. Das > braucht zwar ein paar Zeichen mehr zur Übertragung, aber dafür ist es > unabhängig von den Interna der beteiligten Geräte. > Das habe ich jetzt nicht verstanden. Willst du behaupten dass z.B. das Ethernetprotokoll ASCII bassiert ist? Was du in deinen Datenbereich reinpackst, bleibt bei dem vorgeschlagenen Protokoll völlig offen. Von mir aus ASCII.
@Nils N. (nils_h494) >Was ja per se auch vollkommen in Ordnung ist. Aber gerade ein kleines, >simples Protokoll hätte er schneller selber programmiert, als "ich suche >schon ziemlich lange nach einer Lib". Nö. Du unterschätzt den Aufwand für Selbermachen und Testen um Größenordungen! Wie auch dieser Teilnehmer. Beitrag "Re: FIFO32: Versatile 32 bit fifo with variable array length"
W.S. schrieb: > > Es kommt noch etwas hinzu: bei rein binären Formaten ist man darauf > angewiesen, daß beide Geräte intern exakt die gleiche Darstellung haben. > Das geht öfter als einem lieb ist in die Hose. Ich hab lange genug Daten > austauschen müssen zwischen Geräten mit internem big endian und solchen > mit little endian - und da kracht es eben immer, sobald Daten länger > sind als 8 Bit. Ein ähnliches gilt für numerische Daten im > Gleitkommaformat. > > Also tut man gut daran, auf einer seriellen Schnittstelle mit > endianfreien Daten zu arbeiten, z.B. eben mit reinem ASCII-Text. Das > braucht zwar ein paar Zeichen mehr zur Übertragung, aber dafür ist es > unabhängig von den Interna der beteiligten Geräte. > > W.S. Tut mir leid, der Empfehlung muss ich widersprechen. Das Aufblähen jedes Bytes auf die doppelte Grösse wird erfahrunsggemäss von der Last auf der seriellen Schnittstelle her untragbar, wenn das Datenvolumen etwas grösser wird. Jeder in der Netzwerkprogrammierung erfahrene Entwickler hat es verinnerlicht, htons(), htonl(), ntohs() und ntohl() zu verwenden, um genau die Little-Big Endian Probleme zu umschiffen. Ist halt eine Disziplinierungsfrage. Wer aber einmal dadurch musste, in einer Codebasis sämtliche Konvertierungsschludereien beim Umstieg auf eine andere Endian Architektur zu finden und zu bereinigen, wird IMMER htons()... im Hinterkopf haben (ist wie Elektroschocktherapie). Ein "Vorteil" der ASCII Protokollspezifikation ist, dass das framing leichter wird (wenn alle Zeichen einer Payload in einem eingeschränkten Zeichensatz sind, lassen sich Framingzeichen aus dem verbleibenden Vorrat wählen, ohne an Transposition o.ä. denken zu müssen). Wenn man allerdings ein sauberes framing implementiert, sit das auch bei Binärprotokollen kein Problem.
Ruediger A. schrieb: > > Ein "Vorteil" der ASCII Protokollspezifikation ist, dass das framing > leichter wird (wenn alle Zeichen einer Payload in einem eingeschränkten > Zeichensatz sind, lassen sich Framingzeichen aus dem verbleibenden > Vorrat wählen, ohne an Transposition o.ä. denken zu müssen). Wenn man > allerdings ein sauberes framing implementiert, sit das auch bei > Binärprotokollen kein Problem. Ach so. Jetzt habe ich verstanden worauf er hinaus wollte. Ist aber bei dem vorgeschlagenen Protokoll wie gesagt kein Problem. Insofern scheint das "Framing" gut zu sein :-)
Bimbo 3. schrieb: > Also ich muss ja auch noch wissen wo ein > Datenpaket anfängt und aufhört usw. > Die point to point Protokolle aus dem Ethernet Bereich sind irgendwie > viel zu mächtig und groß für den kleinen µC. SLIP, RFC 1055 https://tools.ietf.org/html/rfc1055. Damit kannst du Datensätze übertragen wie du lustig bist, auch binäre. Sourcecode gibt es auf den letzten Seiten des RFC. Das Gerede über IP im RFC kann man ignorieren, es sei denn man braucht IP. SLIP ist so einfach, dass es hier schon Leuten die Zornesröte ins Gesicht getrieben hat, weil es nicht ihren Vorurteilen über Protokollen aus dem IP-Umfeld entsprach.
Bimbo 3. schrieb: > Hat das jemand schon mal intelligenter und universell gelöst? Aus der Arduino Welt: Schaue dir den CmdMessenger an. (oder schaue dir da was ab) Der machts dir wahlweise in ASCII und auch binär. Anbindung an C# ist dabei.
Ruediger A. schrieb: > Tut mir leid, der Empfehlung muss ich widersprechen. Das Aufblähen jedes > Bytes auf die doppelte Grösse wird erfahrunsggemäss von der Last auf der > seriellen Schnittstelle her untragbar, wenn das Datenvolumen etwas > grösser wird. Und lustig wird's dann, wenn die Länge des ASCII-Strings a priori noch nicht bekannt ist. Spricht insbesondere gegen Zero-Copy-Ansätze zur simplen/performanten Übertragung. Aber über Transport-Layer lässt sich beliebig streiten. Ich bin ein Freund von Framing/Timeouts, irgendwelche Start/Stop-Zeichen, die im Datenstrom dann ge-escape't werden müssen sind auch wieder problematisch. Dass uCs dann einen Datenstrom durchsuchen sollen um sich wieder zu synchronisieren ist in manchen Anwendungen ein no go. Also divide et impera: - Suche dir entsprechend deiner Schnittstelle und ihrer Fehleranfälligkeit ein Frame-basiertes Transportprotokoll - Verpacke deinen Lieblings-Protokoll-Layer - Und ja, ntoh*/hton* sollten dabei das geringste Thema sein
> Also tut man gut daran, auf einer seriellen Schnittstelle mit > endianfreien Daten zu arbeiten, z.B. eben mit reinem ASCII-Text. Das > braucht zwar ein paar Zeichen mehr zur Übertragung, aber dafür ist es > unabhängig von den Interna der beteiligten Geräte. Halte ich fuer totalen Quatsch weil dann die Uebertragung doppelt so lange dauert und der Mikrocontroller viel zu lange aus dem Sleepmode geht und viel zu viel Strom braucht.Und gerade Datenuebertragungen sind Strommaessig teuer weil sie oft ueber Optokoppler gehen. Absolut inaktzeptabel. Jedenfalls fuer meine Anwendungen. :-) Und das ist auch der Grund warum es schlecht ist wenn Arduinokids nichts mehr selber auf die Reihe bekommen und nur noch faul kopieren. Wenn man die Interna nicht mehr versteht findet man keine optimalen Loesungen fuer die eigenen Probleme. Und wenn man sich drei Loesungen aus drei Quellen zu einem 'eigenen' Programm zusammenkopiert dann ist man nicht nur ein Looser weil man nichts eigenes mehr schafft, sondern die Wahrscheinlichkeit ist auch gross das man sich ein dickes Probleme eingekauft hat weil unterschiedliche fremde Software nicht immer so gut miteinander harmoniert. Olaf
DUST 3964R ist ein grottenaltes Protokoll, funktioniert aber auch heute noch gut. Da findet man bestimmt auch Arduino Libs und es gibt viele Analysetools die das verstehen.
Ruediger A. schrieb: > Tut mir leid, der Empfehlung muss ich widersprechen. Das Aufblähen jedes > Bytes auf die doppelte Grösse... Also erstens, du redest von der doppelten Größe und das ist mir zu primitiv. Ich versuch's mal weiter unten zu erläutern. Zweitens wird hier immer wieder und zwar hartnäckig von blockorientierter Übertragung (framing..) geschrieben. Das ist in Umgebungen von Ethernet und HF zwar usus, aber bedenke mal, daß zwischen einer Übertragung in QPSK o.ä. mit entsprechenden Endgeräten und einem simplen UART im µC, wie es der TO angesprochen hat, Welten dazwischen liegen. Was meinst du eigentlich, weshalb es nen UART in jedem popligen µC gibt und sowas wie Ethernet MAC und PHY drei Nummern dicker daherkommen? Also: all die tollen blockorientierten Protokolle taugen herzlich wenig für eine simple UART-Situation in einem ebenso simplen µC. Selbst für sowas wie olle Kermit und Konsorten braucht es etwas mehr Aufwand. Und nochwas: das Endian-Problem ist mittlerweile zwar in den Hintergrund getreten, aber das Prinzip-Problem bleibt: bei den auszutauschenden Daten muß man sich auf irgend ein Austauschformat einigen, sonst ist Neese. Also das betrifft eben nicht die Blockstruktur und Blockerkennung usw., sonder es betrifft die zu übertragenden Daten selbst. So, nun hier mal ein Selbst-Zitat aus der Dokumentation meiner Firmware zum FA_NWT als eines von tausenden möglichen Verfahren:
1 | 3.2 der physische Datenverkehr vom PC zum PIC |
2 | |
3 | Der PC darf alle Zeichen von 20h bis 5Fh sowie 0Dh und 0Ah zum PIC senden. Das umfaßt alle Großbuchstaben, Ziffern, Leerzeichen, Zeilenschaltungen und |
4 | die nötigsten Sonderzeichen. |
5 | Der PIC sendet alle empfangenen und nicht ignorierten Zeichen zurück an den PC. |
6 | |
7 | 3.3 der physische Datenverkehr vom PIC zum PC |
8 | |
9 | Die vom PIC an den PC gesendeten Zeichen sind in Wertebereiche aufgeteilt, die sich in ihrer Bedeutung unterscheiden. |
10 | 00h .. 0Fh = Bereich für Steuerzeichen |
11 | 10h .. 1Fh = Bereich für Meßpunkt-Infobytes |
12 | 20h .. 5Fh = Bereich für Klartext aller Art |
13 | 60h .. 6Fh = Bereich für Kurvenprotokoll-Infos |
14 | 70h .. 7Fh = spezifisch je nach Kurvenprotokoll |
15 | 80h .. FFh = binäre Meßwerte. Bedeutung je nach Art |
16 | des aktuellen Kurvenprotokolles." |
Die mit hohem Datenaufkommen daherkommenden Meßwerte werden in 7 Bit Portionen über die Serielle geschickt. Das ist hier der Knackpunkt. Die Wertebereiche $10..$1F und $70..$FF sind also der Übertragung der eigentlichen Meßwerte reserviert und nutzen damit die Bandbreite zu fast 90% aus. Aber die restlichen Zeichen können zwischendurch für die household-Kommunikation benutzt werden. Ich hatte damals (so etwa 2008) sogar einen Dekoder für ne IR-FB in den Wobler mit eingebaut, weil mir die PC-tastatur auf dem basteltisch zu sperrig war. Über die Serielle geht damit also: - die eigentlichen Meßdaten - die Infostruktur für die Meßdaten - der "household"-Verkehr (Wobbel-Einstellungen) - die Bedienungs per Fernbedienung und das alles völlig asynchron durch- und miteinander, ohne daß sich da was ins Gehege kommt. Und selbstsynchronisierend ist das Ganze auch, obwohl hier ohne Pausen back to back gesendet wird. Es gibt also keine Pausen oder Breaks, an denen man einen Anfang erkennen könnte. Jetzt siehst du, daß deine pauschale Annahme "Das Aufblähen jedes Bytes" durchaus NICHT zwangsläufig so sein muß. Es geht weitaus effizienter - und das eben asynchron und ohne die diskutierten Blockstrukturen. W.S.
W.S. schrieb: > Also: all die tollen blockorientierten Protokolle taugen herzlich wenig > für eine simple UART-Situation in einem ebenso simplen µC. Das STK500-Protokoll funktioniert so, diverse IMU's und Displays nutzen sowas, die XBee-Module von Digi ebenso usw. Das einzige, was dagegen spricht, ist die etwas kompliziertere Implementierung der Kodierung, dafür wird das Empfangen einfacher, weil die Blockgröße typischerweise fix ist - man empfängt einfach bis der Puffer voll ist. Weil man keine Division/Multiplikation zur ASCII-Zahlenkodierung braucht ist so etwas gerade für kleine Controller geeigneter. Schließlich passen bei weitem nicht alle Messwerte/Daten in 7bit, und wenn man mehr als 1 Messwert-Typ hat muss der Empfänger ja auch wissen, was was ist.
W.S. schrieb: > Die vom PIC an den PC gesendeten Zeichen sind in Wertebereiche > aufgeteilt, die sich in ihrer Bedeutung unterscheiden. > 00h .. 0Fh = Bereich für Steuerzeichen > 10h .. 1Fh = Bereich für Meßpunkt-Infobytes > 20h .. 5Fh = Bereich für Klartext aller Art > 60h .. 6Fh = Bereich für Kurvenprotokoll-Infos > 70h .. 7Fh = spezifisch je nach Kurvenprotokoll > 80h .. FFh = binäre Meßwerte. Bedeutung je nach Art > des aktuellen Kurvenprotokolles." ???? Wie erkennst du Störungen auf der Leitung?
W.S. schrieb: > > Zweitens wird hier immer wieder und zwar hartnäckig von > blockorientierter Übertragung (framing..) geschrieben. Das ist in > Umgebungen von Ethernet und HF zwar usus, aber bedenke mal, daß zwischen > einer Übertragung in QPSK o.ä. mit entsprechenden Endgeräten und einem > simplen UART im µC, wie es der TO angesprochen hat, Welten dazwischen > liegen. Was meinst du eigentlich, weshalb es nen UART in jedem popligen > µC gibt und sowas wie Ethernet MAC und PHY drei Nummern dicker > daherkommen? > Vielleicht schreiben wir aneinander vorbei und sollten erstmal die Begriffsbildung klären. Framen heisst für mich nicht, jeden Block a la TCP/IP in geschachtelte Header mit Dutzenden von Verwaltungsbytes zu prefixin. Framing kommt eigentlich aus der seriellen Welt (z.B. PPP über Modemleitungen) und ist gerade in seriellen Protokollen absolut essentiell. Zum Einen kann in einer Peer-o-Peer Verbindung jeder Partner asynchron durch einen Reset gehen, muss also (da es in den meisten seriellen Protokollen keine Möglichkeit gibt, eine logische Verbindung physikalisch zu verwalten) im laufenden Datenstrom auf einen Paketanfang synchronisieren können. Dazu gibt es z.B. Framingstartzeichen und Transpositionen, um die Framingstartzeichen überall anders im Datenstrom zu eliminieren (sh. z.B. RFC 1661). > Also: all die tollen blockorientierten Protokolle taugen herzlich wenig > für eine simple UART-Situation in einem ebenso simplen µC. Selbst für > sowas wie olle Kermit und Konsorten braucht es etwas mehr Aufwand. > Absolut falsch. Nimm z.B. einen Multidrop Master-Slave Bus über RS485. Hier ist das o.d. framing absolut unerlässlich, um Buskollisionen zu verhinden. Wie gesagt braucht es hier keinen Frame im Sinne von TCP/IP, aber Blockanfang und -ende müssen eindeutig identifizierbar sein. > Und nochwas: das Endian-Problem ist mittlerweile zwar in den Hintergrund > getreten, aber das Prinzip-Problem bleibt: bei den auszutauschenden > Daten muß man sich auf irgend ein Austauschformat einigen, sonst ist > Neese. > Ja, dafür stehr in jeder vernünftigen Protokollspec "transmission of length in network byte ordering." Wenn zwei oder mehr Instanzen miteinander kommunizieren wollen, müssen sie dabei Regeln einhalten, egal ob es Menschen oder Maschinen sind. > > 3.3 der physische Datenverkehr vom PIC zum PC > > Die vom PIC an den PC gesendeten Zeichen sind in Wertebereiche > aufgeteilt, die sich in ihrer Bedeutung unterscheiden. > 00h .. 0Fh = Bereich für Steuerzeichen > 10h .. 1Fh = Bereich für Meßpunkt-Infobytes > 20h .. 5Fh = Bereich für Klartext aller Art > 60h .. 6Fh = Bereich für Kurvenprotokoll-Infos > 70h .. 7Fh = spezifisch je nach Kurvenprotokoll > 80h .. FFh = binäre Meßwerte. Bedeutung je nach Art > des aktuellen Kurvenprotokolles." > Bin ich mir nicht ganz sicher, wie das zu verstehen ist. Wenn der zu übermittelnde Datenstrom a priori nicht begrenzt werden kann - z.B. beim Herunterladen eines Images für einen Firwmaredownload - wie würde sich das in deinem Protokoll niederschlagen?
:
Bearbeitet durch User
Ruediger A. schrieb: > Bin ich mir nicht ganz sicher, Also, das ist ein Protokoll für einen Wobbler am PC. Ist grob gesagt so etwas ähnliches wie ein PC-Oszilloskop, bloß ein bissel anders. Da habe ich damals vornehmlich Wert darauf gelegt, daß die Meßwerte (regulär 10 Bit, 1 bis 5 Kanäle) möglichst schnell vom Wobbler zum PC gelangen. Eben deshalb werden sie in Stücken zu je 7 Bit übertragen. Natürlich muß diese Nutzlast ihrerseits einem festgelegten Format genügen, aber das kann mitten im Datenstrom vom PIC her angepaßt werden per Angaben in $60..$7F Bereich. Ebenso wichtig war es mir auch, daß es mittendrin in jeglicher Meßwertübertragung eben auch Kommandos und anders Zeug in beiden Richtungen geben darf, was sozusagen den Meßwert-Datenstrom interruptieren kann, ohne ihn zu stören. Eine Blockstruktur, die zunächst vorgibt, wieviel Bytes da kommen werden, wäre viel zu starr und einschränkend gewesen. Immerhin kann es ja bei heutigen Bildschirmen sein, daß man ja ein Wobbelbild von fast 1800 Punkten und bis zu 5 Kurven sehen will - und das bittesehr nicht im Schneckentempo, und wenn man was verstellt, will man auch nicht erst ewig warten, bis es greift. Das Ganze ist zweckgebunden und hier war es nicht der Zweck, Firmwareupdates zu machen. Ich hatte ja viel weiter oben bereits geschrieben, daß es m.E. eben NIEMALS ein alleinseligmachendes Universal-Protokoll geben wird. War meine Antwort auf die Frage des TO. Für Firmwareupdates hatte ich (in der Firma) ein anderes Verfahren benutzt, wo ich an die Ziel-HW angepaßte Blöcke mit Adresse, Daten und Adler32 gebildet hatte, diese dann komprimiert, dann ähnlich UU codiert und übertragen hatte. Der geräteinterne Updater hat dann blockweise gearbeitet und jeden Block und dessen Programmierung quittiert. Aber das war was für 32 Bitter und keinen kleinen PIC. Andere Aufgabe, anderes Verfahren. W.S.
Olaf schrieb: > Halte ich fuer totalen Quatsch weil dann die Uebertragung doppelt so > lange dauert und der Mikrocontroller viel zu lange aus dem Sleepmode > geht und viel zu viel Strom braucht. Was für riesige Datenmengen überträgst Du bitte? Für ein paar Sensordaten ist das irrelevant. > Und gerade Datenuebertragungen sind > Strommaessig teuer weil sie oft ueber Optokoppler gehen. Absolut > inaktzeptabel. Dann ist halt Dein Design kaputt. Schau mal nach ADUM1201, da kannst Du mit wenig Strom viele Daten übertragen.
Karl schrieb: > Für ein paar Sensordaten ist das irrelevant. Nicht jeder hat nur „ein paar Sensordaten“, und nicht jeder hat nur einen ATtiny13. Bei uns kommen hier auch oft Megabytes zusammen, vorzugsweise über USB, aber seriell geht auch. Da drehen wir dann aber auf 500 kbit/s hoch (der FTDI auf der Gegenseite macht das zum Glück).
Bimbo 3. schrieb: > Anwendungsfall wäre üblicherweise folgender: Ich hab irgendein Gerät mit > einem (relativ kleinen) µC (Atmega o.Ä.) der per UART (+ FTDI, CP2102) > an einem PC hängt. Ich denke, darum geht es dem TO? Übertragung per ASCII sollte dabei doch kein Problem bereiten. Die Datenmenge ist auf Grund des kleinen µCs stark begrenzt. Der große Vorteil von ASCII-Kodierung dabei ist noch, daß die Daten per Terminal angesehen werden können. Als CSV kann man sie bei Bedarf aufzeichnen und direkt in ein Kalkulationsprogramm einlesen. Für den PC ist die Belastung gleich 0. Für einfache Anwendungen ist das doch voll in Ordnung!
Jörg W. schrieb: > Bei uns kommen hier auch oft Megabytes zusammen, vorzugsweise über USB, > aber seriell geht auch. Da drehen wir dann aber auf 500 kbit/s hoch Broken by design. RS232 war für 500kbit nie spezifiziert. Und wo nimmst Du aus einem ATmega Megabyte an Daten in wenigen Sekunden her? Das stimmt hinten und vorn nicht. RS232 am PC oder am Raspi haben keinen Datenbuffer für Megabyte, da kannste froh sein wenn der Fifo ein paar Byte hat, bessere Karten haben 16kByte. Wenn das OS gerade mit was anderen beschäftigt ist, gehen die Daten ins Nirvana. Es sei denn, Du machst Hardware-Handshake, aber dann: Müsste der ATmega bei einem Stop die Megabyte an Daten zwischenspeichern. Wo soll er das tun? Ist ja nicht so, dass der Megabyte an RAM hätte. Kann ja sein, dass man das mit Realtime-OS machen kann. Aber das ist sicher nicht der übliche Anwendungsfall für RS232. Dafür gab es schon vor 30 Jahren andere Schnittstellen. Und heute würde man das sicher über USB machen, aber dann nativ und nicht mit einem RS232-Treiber.
Karl schrieb: > Broken by design. Du musst es ja wissen. > RS232 war für 500kbit nie spezifiziert. Ja, und? Solange es funktioniert, ist es besser als sinnloses Warten. > Und wo nimmst > Du aus einem ATmega Megabyte an Daten in wenigen Sekunden her? Ich habe erstens nicht von einem ATmega gesprochen, zweitens kommen die Daten wortwörtlich „aus der Luft“ (eine Art SDR). > Das stimmt hinten und vorn nicht. Nochmal: du musst es ja wissen. Theoretisiererei. Wir machen es einfach, und es funktioniert (über USB natürlich nochmal viel schneller als über UART). ps: Ich habe natürlich nicht geschrieben, dass wir solch eine Datenrate kontinuierlich nutzen müssen. Die Daten fallen über einen bestimmten Zeitraum an (einige 10 bis 100 ms) und können so lange im Controller gepuffert werden. Dennoch kommen bei Messungen schnell einige Megabyte zusammen, und neben der Geschwindigkeit der Schnittstelle selbst ist daher ein effizientes Protokoll wichtig. Daher sind wir vom ursprünglichen ASCII dann zum schon genannten msgpack übergegangen.
:
Bearbeitet durch Moderator
Jörg W. schrieb: > Ich habe erstens nicht von einem ATmega gesprochen Der TO allerdings schon. Wie sinnvoll ist es, einen Sonderfall zu präsentieren, der den TO nicht tangiert? Binäre Übertragung bringt nunmal einige Probleme, die man mit ASCII-Übertragung nicht hat. Nullbyte, Steuercodes, Framing. Ganz abgesehen vom Komfort, den man hat wenn man die ASCII-Werte direkt auf einem Terminal mitlesen kann.
Karl schrieb: > Wie sinnvoll ist es, einen Sonderfall zu > präsentieren, der den TO nicht tangiert? Woher weißt du, was ihn tangiert? Ein „Atmega o.ä.“ deckt als Begriff eine ziemliche Bandbreite ab. > Ganz > abgesehen vom Komfort, den man hat wenn man die ASCII-Werte direkt auf > einem Terminal mitlesen kann. Daher haben wir ja auch mit ASCII angefangen. Ist aber eben irgendwann lästig, auf dem Controller Ressourcen zu verplempern, um die interne Darstellung in ASCII zu wandeln, nur um auf der anderen Seite wieder Ressourcen zu verplempern, aus der ASCII-Darstellung eine interne zu machen. Irgendwann ist dann eben der Schalter reingekommen, der zwischen human und machine readable umschaltet.
Karl schrieb: > Ganz > abgesehen vom Komfort, den man hat wenn man die ASCII-Werte direkt auf > einem Terminal mitlesen kann. Naja... einen Decoder zu schreiben, der einen binären Datenstrom lt. Protokollspec lesbar aufbereitet, ist vielleicht eine einmalige Mehrarbeit von zwei Stunden, bringt dem Entwickler viel Kenntnis des Protokolls und bedeutet im Workflow beim Analysieren gerade mal einen Schritt mehr. Unter Docklight kann man mit einem Script sogar in Echtzeit den aufbereiteten Datenstrom eines binären Protokolls mitlesen. Ein Vorteil eines binären Protokolls zeigt sich auch bei der Analyse: Wenn man Langzeittraces aus dem Feld ziehen und postmortem analysieren muss (um eines der typischen Killerbugs zu finden, die nur bei Vollmond auftreten), ist ein Tracefile eines "menschenfreundlichen" Protokolls ca. doppelt so gross wie der eines komprimierten. Das kann z.B. bei einem rund um die Uhr laufenden Master-Slave Protokoll schon Mal in die Gigabytes grosse Datei gehen. Da man die dann (unabhängig vom verwendeten Protokoll) eh nicht mehr mit Durchsicht analysiert kriegt, muss man sie sowieso automatisch vorverarbeiten, was den "Lesbarkeitsvorteil" dann wieder wett macht - aber 8G sind logistisch immer leichter zu handeln als 16G. Das sind jetzt keine theoretischen Konstrukte. Genau dieser Fall begegnet mir in der Praxis immer wieder. Ausserdem bedeutet ein - wie Jörg es sehr schön beschrieben hat - unnötig auf der einen Seite aufgepumptes und auf der anderen Seite wieder abgepumptes Protokoll zwar in Einzelpaketen klein aussehenden overhead, kann in der Masse aber einen Riesenunterschied machen. Wer schon Mal versucht hat, in einem RS485 Master-Slave Bus mehr als 8 Knoten (z.B. Kartenleser mit recht komplexen Interaktionen) so effizient zu bedienen, dass das System praktisch benutzbar ist, weiss wovon ich schreibe...
Ruediger A. schrieb: > ca. doppelt so gross Auch gerne 3 oder 4mal, wenn Mann Leer- und Trennzeichen mitzähl. Von ASCII zu binär ist es aber am Ende nur eine Optimierung ohne großes Potential (keine Größenordnung). Die kann (und sollte) man angehen, wenn es notwendig wird. Und ASCII löst auch die endian-probleme, die hton nunmal nicht lösen kann.
> Was für riesige Datenmengen überträgst Du bitte? Für ein paar > Sensordaten ist das irrelevant. Hihi...ich mache Meetings wo es um einstellige Mikroampere geht. Da ist ALLES relevant. > Dann ist halt Dein Design kaputt. Schau mal nach ADUM1201, da kannst Du > mit wenig Strom viele Daten übertragen. Brauchen viel zuviel Ruhestrom. 0.85mA Ruhestrom? Das ist ja fast der Gesamtstrom mancher Anwendung. Was ich aber eigentlich aufzeigen wollte, es gibt halt unterschiedliche Probleme die unterschiedliche Loesungen beduerfen. Sieht man ja auch an dem Beispiel von W.S. Seine Loesung ist gut fuer genau sein Problem. Olaf
Hi bimbo385, ich hab das alles so gut wie mitgelesen und nu möchte ich dir auch mein Vorschlag unterbreiten. Bei ASCII sehe ich das problem, dass du Sequenzen "escapen" musst. Außerdem musst du dabei deine Werte erst von Binär in ein String wandeln und auf der anderen Seite wieder zurück, was ich als überflüssig empfinde, denn sollte dies so eine größer Sicherheit bringen, würden TCP/IP ASCII basiert sein :-D kaum vorstellbar... Ich übertrage alles binär, so kannst du auch direkt strukturen zum versenden laden, wenn du sicher stellst, dass das alignment stimmt. Frameaufbau: | CRC16 | Type | CMD | Length (der Daten) | Data | Ich würde es mir nicht komplizierter machen wie es sein muss... siehe: Georg G. schrieb: > KISS ist klein und hat wenig Overhead Gruß
:
Bearbeitet durch User
Moin, da habe ich was losgetreten ;-) Vielen Dank erstmal für die ganzen Infos. Natürlich habe ich mir schon für mehrere Anwendungsfälle irgendwelche Protokolle über UART ausgedacht (ASCII basiert) und war mit dem Ergebnis nicht immer 100%tig zufrieden (nicht das es nicht funktioniert hätte). Es scheint also keine gut/weit verbreitete Universallösung zu geben, das ist schon mal gut zu wissen. Mein Problem bei direkter binärer Übertragung von Werten via UART ist immer, dass es kein Escape- oder Trennzeichen mehr gibt. Schließlich kann jeder 8-Bit Wert ja auch in einem zu übertragenden Wert vorkommen. Daher muss man immer mit Längeninformationen arbeiten. KISS, SLIP, der CMDmessenger und die Idee von Adam P. sehen auf den ersten Blick schon mal ganz gut aus. Ich werde mir das in Ruhe mal anschauen und ausprobieren. Es geht wie schon diskutiert nicht um riesige Datenmengen. Meistens sind es nur ein paar hundert Byte pro Sekunde die übertragen werden müssen. Das heftigste sind normalerweise Konfigurationsdaten, die schnell in einem Rutsch ausgetauscht werden sollen. Aber auch das beschränkt sich auf maximal 1-2 kByte und wird manuell vom Benutzer ausgelöst. Gruß
Es sind ein paar Moeglichkeiten erlaeutert worden, die Einige mit etwas viel Herzblut und mangelhaftem Wissen verteidigt haben wollten. Du hast zumindest zumindest gesehen, dass an einem Protokoll mehr als "nehmen wir eine fertige general purpose library" ist.
Achim S. schrieb: > > Und ASCII löst auch die endian-probleme, die hton nunmal nicht lösen > kann. Welche sind das? Die "Normalisierung auf network byte ordering" wird ja gerade durch <h|n>to<n|h><s|l> realisiert. Welche ungelösten Probleme bleiben dann noch? Eine Längendarstellung wie "123" statt 0x0000007b wirft natürlich das Konvertierungsproblem gar nicht erst auf, aber um den Preis, dass die eine Seite aus 0x0000007b (wie immer sie intern repräsentiert wird) den String "123" bauen und die Andere Seite den ganzen Prozess umkehren muss. Ausserdem wird typischerweise eine ASCII Länge nicht den gesamten Wertebereich eines Short oder long umfassen, d.h. die faktische Maximallänge eines Pakets wird durch den Wertebereich begrenzt, der in das fixe Längenfeld passt. In den seltensten Fällen wird ein Längenstring in Hex definiert oder es werden 9 bzw. 5 Dezimalzeichen für die Länge vorgesehen (die man bräuchte, um den Wertebereich eines long bzw. eines shorts zu codieren), und wenn die Länge fix in 3 Dezimalstellen abgelegt wird, ist bei 999 Zeichen definitiv Schluss.
Hallo, ich habe auf AVR vor Jahren mal das alte X-Modem Protokoll benutzt. Mit 128Byte Blöckgröße vom Ram gut nutzbar, das Handling mit ACK/NACK ist simpel und man hat (für AVR-Verhältnisse) für das Füllen oder Auswerten des Buffers ewig Zeit, weil die Timeouts recht hoch sind. Auf der PC-Seite findet man noch ein paar Terminslprogramme, die XModem (nicht XModem 1k) können, man kann das dann zum Debug gut als Datei ablegen. Gruß aus Berlin Michael
Falls man ASCII haben will, weil die Daten hinreichend langsam daherkommen, und man per Terminal zuschauen moechte, wuerde ich ASCII-Hex, anstelle von ASCII-Dezimal empfehlen, da etwas kompakter und man als Entwickler eh in Hex denken kann.
Ruediger A. schrieb: >> Und ASCII löst auch die endian-probleme, die hton nunmal nicht lösen >> kann. > > Welche sind das? Vielleicht hat er es unglücklich geschrieben: mit ASCII kannst du natürlich auch Gleitkommazahlen übertragen, bei denen es binär neben der Endianess noch die Details der internen Darstellung zu berücksichtigen gibt. Im Gegenzug verliert man typischerweise durch die Hin- und Rückwandlung über ASCII Genauigkeit, außerdem kostet die Wandlung Rechenleistung. Andererseits spielt Endianess und Zahlendarstellung mittlerweile eine ziemlich untergeordnete Rolle. Big-Endian-Systeme sind nur noch sehr spärlich anzutreffen, und auch bei Gleitkommazahlen macht kaum noch jemand was anderes als IEEE754.
Ruediger A. schrieb: > Dazu gibt es z.B. Framingstartzeichen und > Transpositionen, um die Framingstartzeichen überall anders im Datenstrom > zu eliminieren (sh. z.B. RFC 1661). Da hast du dir mit PPP aber ein etwas kompliziertes Beispiel rausgesucht. Ansonsten volle Zustimmung. Ich versehe auch nicht, warum, wie beim letzten Mal, die Leute voll durch die Decke gehen, wenn man erprobte Techniken aus der Datenkommunikation vorschlägt. Erprobt heißt meist auch alt, also zu einer Zeit eingeführt, als ein AVR als Hochleistungsrechner durchgegangen wären. Klar kann es Fälle geben bei denen die nicht verwendbar sind, aber dieser Reflex ist schon merkwürdig.
Jack schrieb: > Ich versehe auch nicht, warum, wie beim letzten Mal, die Leute voll > durch die Decke gehen, wenn man erprobte Techniken aus der > Datenkommunikation vorschlägt. „die Leute“? Das war wohl einer, und derjenige ist auch dafür bekannt, dass er so gut wie nur seine Sichtweise propagiert und akzeptiert.
Bimbo 3. schrieb: > Aber auch das beschränkt sich > auf maximal 1-2 kByte und wird manuell vom Benutzer ausgelöst. ok...Super Bsp. Nehmen wir an 2048 Byte müssen übertragen werden. Wir haben eine Baud von 115200. Würdest du nun die 2048 Byte "raw" übertragen, brauchst du ca. 177ms. Angenommen du willst ASCII nutzen und hast lediglich Byte Werte, keine uint16_t oder uint32_t - dann sieht die Rechnung wie folgt aus: 2048 Mögliche Werte * max. 3 Stellen (Byte) = 6144 Byte Dies würde das 3 Fache an Übertragungsdauer kosten + die Konvertierung von Binär -> ASCII und wieder zurück... Wer's will - bitte - aber in meinen Augen ist es sinnlos und bringt kein Vorteil. Und wenn man es sich im Terminal ansehen will, dann wird man ja wohl ein Debug-Interface haben und kann sich die empfangenen Daten aufbereiten und ausgeben. Und falls nicht...sieht man mit einem Logic-Analyser auf der RX/TX Leitung sowhl HEX, DEC und auch ASCII. Und damit sollte jeder der sein System kennt zurecht kommen, falls es Übertragungsprobleme geben sollte.
:
Bearbeitet durch User
Adam P. schrieb: > Wer's will - bitte - aber in meinen Augen ist es sinnlos und bringt kein > Vorteil. Bei 'manuell ausgelöst' ist die Senderate aber eher gering und ein µC kann das schon schnell verarbeiten. Bei ASCII und einer Struktur wie JSON kann man auf Senderseite etwas dazupacken ohne auf Empfängerseite ein Update zu machen. Binär mit fester Struktur hätte diesen Nachteil, und bei einer 1 zu n Architektur müssten evtl. viele Empfänger aktualisiert werden. Ich sehe da schon Vorteile ASCII/JSON zu nutzen, man darf sich nur nicht an den kleinsten verfügbaren µC klammern.
Johannes S. schrieb: > Binär mit fester Struktur hätte diesen Nachteil, Na, auch binäre Strukturen darf man erweiterbar konzipieren. Ein Beispiel ist das OpenFlight-Format. So etwas ist zwar etwas weniger verbreitet, aber mindestens mal ein Versions-Feld um Abwärtskompatibilität zu ermöglichen ist gängige Praxis. Beim CAN-Bus ist es z.B. überhaupt kein Problem, neue Nachrichten hinzuzufügen...
Bimbo 3. schrieb: > Mein Problem bei direkter binärer Übertragung von Werten via UART ist > immer, dass es kein Escape- oder Trennzeichen mehr gibt. das von mir vorgeschlagene DUST 3964R ist ein transparentes Protokoll, https://de.wikipedia.org/wiki/3964R Wenn im Datenstrom das Steuerzeichen 'DLE' vorkommt wird es vom Treiber verdoppelt, der Empfänger muss das entsprechend filtern. Wenn der µC wenig Speicher hat ist ein grosser Datenblock natürlich ungüstig, da macht es Sinn die Werte mit verschiedenen Kennungen in kleineren Häppchen zu übertragen.
Jack schrieb: > Ruediger A. schrieb: >> Dazu gibt es z.B. Framingstartzeichen und >> Transpositionen, um die Framingstartzeichen überall anders im Datenstrom >> zu eliminieren (sh. z.B. RFC 1661). > > Da hast du dir mit PPP aber ein etwas kompliziertes Beispiel > rausgesucht. Richtig, PPP macht es komplett überdreht - da wird jedes nicht lesbare Zeichen transponiert, und über eine konfigurierbare Maske lassen sich auch noch im Restbereich Zeichen zwangstransponieren. Ich hatte PPP nur gewählt, weil es vermutlich noch eine Menge Leute gibt, die damit in Berührung gekommen sind. In UTISCP mache ich es Minimalinvasiv; es werden nur das Framestartzeichen und das Escapezeichen selber transponiert (andere Protokolle machen es auch so). Wenn man die beiden nicht zu ungeschickt wählt, ist damit der Overhead sehr gering.
Adam P. schrieb: > Und wenn man es sich im Terminal ansehen will, dann wird man ja > wohl ein Debug-Interface haben und kann sich die empfangenen Daten > aufbereiten und ausgeben. Wenn man das für sich zu Hause oder im Labor macht... Ich mach das halt im Feld, und die Kommunikation fragt nicht nur Daten ab, sondern steuert auch Geräte. Zum einen tut sich die Steuersoftware der Kunden mitunter schwer mit Nullbytes oder ASCII über 127, zum anderen ist es halt unheimlich praktisch, wenn man mal schnell ein Terminal aufmachen und die Steuerung händisch überprüfen kann, ohne dafür das Debug-Interface zu benötigen, welches zuhause auf dem Rechner liegt oder welches man auf dem Kundenrechner nicht installieren will oder darf. Ich hab durchaus schon größere Datenmengen binär übertragen und weiss daher um die Probleme, die sich dabei ergeben. Daher nehme ich für kleine Datenmengen, Sensordaten ASCII. Und mal ehrlich: Umrechnung Binär-ASCII im µC => das Rausschicken der Daten dauert üblicherweise länger, erheblich länger als die Konvertierung. Umrechnen ASCII in Binär am PC => das unter einem OS, welches nebenher die Festplatte indexiert und Seti rechnet zu diskutieren ist müßig. Datenmenge => zählt nur, wenn ASCII immer den vollen Wertebereich auch nutzen würde. Speichergröße => Wer Logfiles von 8GB anlegt, hat ganz andere Probleme. Bei 115kBaud sind pro Sekunde 15kByte möglich. Bei ununterbrochenem Schreiben sind das 7 Tage für 8GB. Ups, die Logdaten der letzten 7 Tage sind weg, weil die Speicherkarte voll war... Ich würd sowas ja in kleine Dateien aufteilen.
Karl schrieb: > wenn man mal schnell ein > Terminal aufmachen und die Steuerung händisch überprüfen kann, ohne > dafür das Debug-Interface zu benötigen OK, das mag ja sein, aber dann nimmt man z.B. HTerm und kann den Datenstrom auch mitlesen (Hex-Darstellung), wenn man den Frameaufbau kennt. Ich glaub eher, dass ist reine Geschmackssache. Ja die Umrechnungen sind schnell erledigt, aber meins ist es nicht. Ich (wir) übertragen Daten zwischen medizinischen Geräten und das funktioniert im Binär Format super...für ASCII hätten wir gar keine Zeit, bzgl. Datenrate und Menge. Ich würde ja auch meine struct z.B. nicht erst in ASCII konvertieren um dies in eine Datei zu speichern - dafür gibts ja den binären Schreib-Modi. ...Aber ich denke eher, jeder hat seine Vorgehensweisen und man wird nie einer Meinung sein ;-)
:
Bearbeitet durch User
Karl schrieb: > Bei 115kBaud sind pro Sekunde 15kByte möglich. Bei ununterbrochenem > Schreiben sind das 7 Tage für 8GB. Ups, sind natürlich 11.5kByte und etwas über 8 Tage...
Adam P. schrieb: > Aber ich denke eher, jeder hat seine Vorgehensweisen und man wird nie > einer Meinung sein Ich denke eher es ist eher eine Frage für den Einsatzzweck das richtige Format zu nehmen. Wie gesagt hab ich auch mit binär angefangen. Als dann noch Steuerdaten übertragen werden sollten, hab ich auf Steuerbytes plus Hex-Übertragung der Werte gesetzt. Als dann das Datenformat flexibler werden sollte (unbekannte Anzahl an Sensoren abfragen oder Aktoren steuern), bin ich um Adressbytes plus Steuerbytes nicht mehr drumrumgekommen, und hab die Werte als Ganzzahlen überragen. Dann war es noch einen Punkt davon entfernt, die Kommawerte gleich als Festpunktzahlen zu übertragen. Das ist eine Entwicklung über 2 Jahrzehnte und einige Dutzend Projekte. Man passt sich halt auch den Möglichkeiten der Hardware an: Zum Beispiel könnte man mit 9-bit RS232 prima mit einem Steuerbit zwischen Daten und Steuerzeichen umschalten und hätte die vollen 8 Bit Datenbereich. Aber viele USB-RS232-Wandler unterstützten 9-bit nicht, und einiges an Software kann damit nichts anfangen, obwohl es die meisten µC problemlos könnten.
Karl schrieb: > Zum Beispiel könnte man mit 9-bit RS232 prima mit einem Steuerbit > zwischen Daten und Steuerzeichen umschalten und hätte die vollen 8 Bit > Datenbereich. Kannst ja ein BREAK senden. ;-)
Karl schrieb: > Das stimmt hinten und vorn nicht. RS232 am PC oder am Raspi haben keinen > Datenbuffer für Megabyte, da kannste froh sein wenn der Fifo ein paar > Byte hat, bessere Karten haben 16kByte. Wenn das OS gerade mit was > anderen beschäftigt ist, gehen die Daten ins Nirvana. Es sei denn, Du > machst Hardware-Handshake,... Also ich schätze mal, daß du ein Linuxer bist, denn Windows puffert bei Bedarf allemal 64K Bytes oder gar noch mehr bei seriellen Interfaces in beiden Richtungen. Da geht überhaupt nichts ins Nirvana. Schreib also nicht solche Behauptungen hin. Jörg W. schrieb: > Da drehen wir dann aber auf 500 kbit/s hoch.. ..und das erscheint mir doch recht fraglich -un das mal so zurückhaltend wie möglich zu sagen. Nach meiner Erfahrung bringt es fast garnichts gerade bei einem FTDI, die Baudrate wesentlich über 140kBaud hochzudrehen. Es wird dabei nämlich doch nicht schneller, sondern fängt bloß an zu lücken. Da ist es eine wesentlich bessere Sache, einen FT245 zu benutzen und dafür eben auf der µC-Seite nen bytebreiten Port zu spendieren. W.S.
W.S. schrieb: > Also ich schätze mal, daß du ein Linuxer bist, […] Woran man einfach nur erkennt, dass du von Linux keine Ahnung hast. Aber das ist nicht das Thema. > Jörg W. schrieb: >> Da drehen wir dann aber auf 500 kbit/s hoch.. > > ..und das erscheint mir doch recht fraglich -un das mal so zurückhaltend > wie möglich zu sagen. Nach meiner Erfahrung bringt es fast garnichts > gerade bei einem FTDI, die Baudrate wesentlich über 140kBaud > hochzudrehen. Es wird dabei nämlich doch nicht schneller, sondern fängt > bloß an zu lücken. Wie soll er denn „lücken“? Wir reden von der Richtung Controller -> PC. Der Controller pumpt seine Daten mit 500 kbit/s (auch 1 Mbit/s haben wir schon genutzt, lässt sich nur in unserer aktuellen Hardware in der UART nicht konfigurieren, weil der Mastertakt nicht passt) in Richtung FTDI. Der FTDI kann da nichts „aussitzen“, der muss den Salat ordentlich in USB-Päckchen einwickeln und zum PC schicken. Datenverluste an dieser Stelle hatten wir nie, die resultierenden Datenraten passen allemal über ein Fullspeed-USB. ("PC" ist übrigens mal Linux, mal Windows, um deine obige Unterstellung, Linux wäre für sowas nicht zu gebrauchen, zu den Akten zu legen.)
Karl schrieb: > Zum Beispiel > könnte man mit 9-bit RS232 prima mit einem Steuerbit zwischen Daten und > Steuerzeichen umschalten.. Jaja. Du guckst nicht weit genug: Demnächst brauchst du nicht ein Steuerbit, sondern zwei - was dann? Nee, sowas ist von hause aus zu oberschlau ausbaldowert und man fällt damit (wie du ja bereits schriebest) schon an der nächsten Ecke auf die Nase. Abgesehen davon frag ich mich, warum hier so viele Leute sich an den 8 Bit festklammern. Da beißt sich grundsätzlich der Datenstrom mit den erforderlichen Steuer- und Kontroll-Informationen. Natürlich kann man mit Blockstrukturen und den darin enthaltenen mehrbytigen Präambeln die Wahrscheinlichkeit von Fehlinterpretationen absenken - aber eben NICHT grundsätzlich beseitigen. Wenn sowas wirklich ne Rolle spielt, dann muß man eben die vollen 8 Bit aufgeben und sich entweder mit einem Bitstream anfreunden, der z.B. in 7 Bit Häppchen zerteilt wird oder man muß einige der 256 Codes als Spezialcodes reservieren und damit leben. So ähnlich (jaja, ganz grober Vergleich) wird das ja auch bei HTML gemacht: <irgendwas>. W.S.
W.S. schrieb: > oder man muß einige der 256 Codes als Spezialcodes reservieren und damit > leben Genau das ist das, was die üblichen Protokolle dafür machen. Sie reservieren dabei üblicherweise nur sehr wenige Spezialcodes (zuweilen auch nur einen einzelnen), sodass der größte Teil des Datenstroms 1:1 rübergeht.
Gerade bei Blockstrukturen ist das ja aber gar nicht nötig, weil der Header ja hoffentlich die Länge des Blocks enthält, und man somit weiß wo der nächste Block beginnt. Somit kann man die Daten im Block 1:1 am Stück senden.
Was machst du, wenn beide Teile die Synchronisation verloren haben? Dann interpretiert Teilnehmer B irgendwas als „Blocklänge“ und wartet sich zu Tode, weil Teilnehmer A nur ein Hundertstel davon sendet …
Jörg W. schrieb: > um deine obige > Unterstellung, Linux wäre für sowas nicht zu gebrauchen, zu den > Akten zu legen.) Ich habe da überhaupt nichts unterstellt. Also! Allerdings habe ich - als Windows-Benutzer - mich wirklich nicht in die Details der Verwaltung von seriellen Schnittstellen von Linux gekümmert. Wozu auch? Wenn jemand also felsenfest behauptet, daß es zu Datenverlusten kommt, sofern auf einer Karte nicht Puffer vorgehalten wird ("bessere Karten haben 16kByte"), dann kann er kein Window'ser sein, folglich ist er vermutlichst ein Linuxer oder ein FBSDler (was fast auf's Gleiche hinausläuft) - dort mag es ja so sein wie beschrieben. Und falls beides nicht zutrifft, ist die Behauptung der Datenverluste einfach nur Dummschwätz. Aber ich nehme bei jedem zunächst an, daß er ernsthaft und logisch sich äußert - jedenfalls solange, bis ich erkenne, daß er sich entgegengesetzt outet. Das ist eben Logik. Klaro? W.S.
Jörg W. schrieb: > Dann interpretiert Teilnehmer B irgendwas als „Blocklänge“ und wartet > sich zu Tode, weil Teilnehmer A nur ein Hundertstel davon sendet … Dafür gibts Timeouts. Wenn 10ms lang o.ä. kein Byte mehr ankommt (weil das Paket zuende ist, aber der Empfänger noch mehr erwartet), setzt man den Zustandsautomaten zurück und wartet auf einen neuen Paketbeginn. Die Gegenstelle wiederholt Pakete, die nicht bestätigt worden sind alle 15ms, so berappelt sich das System automatisch. Das passt man natürlich noch an die genaue Situation an, welche Seite wartet und welche wiederholt, ob/wie man Pakete bestätigt usw. Eine Prüfsumme ist ja sowieso Pflicht, um kaputte/halbe Pakete nicht anzunehmen.
Beitrag #5308302 wurde von einem Moderator gelöscht.
W.S. schrieb: > Wenn jemand also felsenfest behauptet, daß es zu Datenverlusten kommt, > sofern auf einer Karte nicht Puffer vorgehalten wird ("bessere Karten > haben 16kByte"), dann kann er kein Window'ser sein, folglich ist er > vermutlichst ein Linuxer oder ein FBSDler (was fast auf's Gleiche > hinausläuft) - dort mag es ja so sein wie beschrieben. Es ist entweder bei keinem wie beschrieben oder bei allen möglich. Wenn sich irgendwas im System gerade verklemmt (bspw. infolge eines Hardwareproblems mit der Festplatte), dann gehen Daten verloren, die nicht in irgendeinen Puffer gepasst haben. Dagegen kann kein OS was machen, wenn der Zustrom auf Dauer größer als der Abfluss ist, dann geht's irgendwann nicht mehr weiter. Dabei ist es mittelprächtig wurscht, ob die Daten nun in einem Hardware-FIFO oder in einem Puffer des OS gespeichert werden. FIFOs in UARTs beim PC interessieren ja sowieso niemanden mehr, seit PCs gar keine UARTs mehr haben … davor waren sie nur deshalb wichtig, damit man nicht für jedes einzelne Zeichen einen Interrupt bedienen muss im OS, ansonsten frisst der Interrupt-Overhead übermäßig Ressourcen.
Hi, Ich benutze ASCII. Der UART ist komfortabel angebunden an den stdio stream. Mit der stdio.h/string.h werden einfach printf/getline/scanf etc. unterstützt. Noch einen kleinen Line-Empfangspuffer auf AVR Seite implementiert...voila Den Komfort in der Konsole zu schreiben "set led 10 on<enter>" will ich nicht missen. Für große Blöcke kann man ein Read oder Write Kommando implementieren, um einmalig auf Blocktransfer einer bestimmten Länge zu schalten. Klar kann der bei Byte-Verlust auch mal hängen... Ich hab nie Timeouts oder CRC implementiert, kann man machen. Aber war auch nie Mission Critical. BTW: Arbeite etwa 20 Jahre mit unterschiedlichen Controller von AVR Tiny / PIC16 / PIC 32 / AVR Mega SamD SamV bis imx7/AM335x und ich kann mich nicht erinnern, dass ich jemals bewusst auf einer seriellen Verbindung einen Fehler gesehen habe. Und bis SSH über LAN läuft, muss uboot und Co darüber laufen... Aber ich muss zugeben, die Boards laufen alle bei Raumtemperatur zwischen 20° und 27° und mit massiven Streaming Daten auf der seriellen Schnittstelle habe ich wenig zu tun gehabt. Allerdings mit Logview alle paar 100ms ein paar Daten dauerhaft. PS : Die AVRs liefen mit internem RC Oszillator damals noch mit CALBYTE :-) Aber wehe, man ändert die Spannung zu sehr, dann gibt es wirre Zeichen... Gruß Kai
W.S. schrieb: > Also ich schätze mal, daß du ein Linuxer bist, denn Windows puffert bei > Bedarf allemal 64K Bytes oder gar noch mehr bei seriellen Interfaces in > beiden Richtungen. Windows puffert bis zu 64kByte, wenn man die Buffer entsprechend groß einstellt. Üblicherweise eingestellt sind 16kByte. Das ist aber Softwarepuffer, die RS232-Karten oder die USB-seriell-Wandler halten nur einige Byte. 64kByte sind bei 115kBaud in 6 Sekunden voll. Und ja, ich hatte schon den Effekt, dass ein Vergrößern oder Verschieben des Fensters die Eventloop so lange beschäftigt hat, dass der Eventtimer nicht ausgeführt wurde und die RS232 für mehrere Sekunden nicht abgefragt wurde, was bestenfalls zum schnellen Einlaufen der fälligen Daten, schlechtestenfalls zum Datenverlust führte. Gelöst habe ich das durch eine andere Timerstruktur, aber - kann vorkommen. W.S. schrieb: > Jaja. Du guckst nicht weit genug: Demnächst brauchst du nicht ein > Steuerbit, sondern zwei - was dann? Ähem, mit einem Bit mehr verdoppele ich die Zeichenzahl. Damit kann ich 8bit-Binärdaten von 0..255 schicken und hab noch 256 Steuerzeichen zur Verfügung. Theoretisch könnte man das auch mit 8 Bit machen: Zeichen von $00 bis $7F als Steuercodes, Zeichen von $80 bis $FF, also mit dem höchsten Bit gesetzt sind 7-bit-Binärzahlen, damit könnte man 7 Bit, 14 Bit, 21 Bit Binärwerte senden. Das Anpassen auf 8-bit Werte kann einfach durch Shift erfolgen und die Datenrate wäre gerade mal 1/8 = 12% langsamer. Wenn man davon ausgeht, dass sowieso seltenst alle 16 bit eines Integer genutzt werden, verliert man gar nix. Also nur so eine Idee, nicht das ich das machen würde... ;-)
> Das Anpassen auf 8-bit Werte kann einfach durch Shift > erfolgen und die Datenrate wäre gerade mal 1/8 = 12% langsamer. Ja, koennte man machen. Aber da Daten in der Regel auf zwei Byte ueber die Schnittstelle gehen, auf welche der beiden Haelften bezieht sich dein so gewonnenes Steuerbit? > Wenn man davon ausgeht, dass sowieso seltenst alle 16 bit eines Integer > genutzt werden, verliert man gar nix. Und wenn doch? Sonderfallbehandlung? Seufz. Noe, mein Gehirn hat eine Granularitaet von 8Bit und das soll so bleiben. :-) Olaf
Die einfachsten Protokolle haben doch z.b. ein reserviertes Start-Byte (z.B. 0xaa) und Ende-Byte (z.B. 0xbb) und dazwischen halt den Datenstrom irgendwie aufgebaut (Längen-Infos, Daten, Checksumme, ...) Da braucht man dann keine Pausen, keine Wartezeiten, keine irgendwas. Wenn 0xaa kommt, lege ich los, wenn 0xbb kommt, werte ich aus, wenn 0xaa vorher kommt (dann gab es wohl einen Fehler, den ich nicht beheben kann), dann fange ich von vorne an. Damit 0xaa und 0xbb im restlichen Datenstrom nicht vorkommen, gibt's noch ein drittes (Bytestuff)-Zeichen (0xcc). Kommt eines der 3 Zeichen im Datenstrom vor, so wird 0xcc gesendet und das zeichen danach z.b. um 0x80 verändert. Wenn die Sonderzeichen selten sind, ist alles gut, die Telegrammlänge wird kaum mehr. Im Worst-Case aber doppelt so lang. Wählt man dagegen Sonderzeichen, die häufig vorkommen, so kann man das Verfahren oben umstellen, so dass das Telegramm auch im Worst Case kaum länger wird. für das Beispiel oben: 1 Zeichen länger im Normalfall Im Worst Case zusätzlich noch 1 Zeichen alle 126 Zeichen
Weia.. W.S. schrieb: > Also ich schätze mal, daß du ein Linuxer bist, denn Windows puffert bei > Bedarf allemal 64K Bytes oder gar noch mehr bei seriellen Interfaces in > beiden Richtungen. Da geht überhaupt nichts ins Nirvana. Schreib also > nicht solche Behauptungen hin. Was soll das mit Linux oder Windows zu tun haben? Mit Verlaub, sowas ist unreflektierter Fanboy-Dummschwätz a la carte. Wenn ein OS was anderes macht und die Hardware/der Treiber kein DMA macht, kann immer mal was verloren gehen. Darum haben beide Desktop-Konfigurationen bei Echtzeit-/Safety-Anforderungen nix verloren und man muss sich seine HW genau aussuchen (es ist allerdings dann mit Linux/Xenomai und anderen RT-Erweiterungen möglich). Und zum Stichwort DMA: Spätestens wenn abrissfreier Datentransfer garantiert werden muss, fliegt auf dem uC typischerweise der Streaming-Ansatz mit Escape-Bytes und Software-Start/Stop-Synchronisation eben raus, da die Blocklängen je nach Inhalt variabel sind. Sowas im eigentlichen Protokoll zu reflektieren (siehe Frage des TO) ist Murks. Das gehört wenn nötig in einen Paketisierungs-Layer. Kai schrieb: > Ich hab nie Timeouts oder CRC implementiert, kann man machen. Aber war > auch nie Mission Critical. Wenn ich schon sowas lese...da trennt sich eben Industrie von Frickelei. Zu Recht kann man argumentieren, dass UART nur noch als Board-To-Board-Kanal mit kurzem Kabel implementiert werden sollte, aber niemals ohne Timeout-Handler. Ansonsten: Siehe Modbus and keep it simple. Und ich erinnere noch an RTS-CTS-Leitungen, wenn ihr schon mit lustigen Ideen wie 9. Kontrollbit kommt. Wenn viele Fehler erwartet werden und Performance ein Thema ist, muss man fast immer seinen Transport-Layer neu designen, sei es mit forward-error-correction oder Resend-Möglichkeit, oder was auch immer. Dabei läuft es aber so gut wie immer auf Frames raus, kein Streaming-Gefrickel. Man sehe sich z.B. ieee802.11 an. Wenn ein Protokoll gut getestet/auf Fehleranfälligkeit verifiziert wurde, sind eigentlich auch ASCII-Hacks nicht mehr nötig. Dann macht es mehr Sinn, ein "Human Interface" a la "set led 1" zu implementieren, aber sicher nicht auf Protokollebene, denn da wären wir wieder beim Stream (mit u.U undefinierten States ohne Timeout) versus Paket. Wie dann der Payload interpretiert wird, sollte eine Frage des höheren Layers sein, mit den gängigen Auswahl: - Registerbasiert - Kommandoprotokoll - Mailboxen (a la CAN) Das simpelste dürfte nach wie vor das erste sein. Da muss man sich dann nur noch Registerlänge und Endianness überlegen. Das Marshalling von Datenstrukturen, wenn sie als ein Paket wie ein Remote-Procedure-Call daherkommen, dürfte die nächste Frage sein. Da kann man durchaus JSON, oder andere XML-Ansätze zur Beschreibung der statischen Datenstrukturen gut verwenden, letzere Datenübertragung im Klartext aber für den uC bloss nicht, das ist wieder was für HTML-4-Anwendungen.
Karl schrieb: > Und ja, ich hatte schon > den Effekt, dass ein Vergrößern oder Verschieben des Fensters die > Eventloop so lange beschäftigt hat, dass der Eventtimer nicht ausgeführt > wurde und die RS232 für mehrere Sekunden nicht abgefragt wurde, Du hast also NICHT mit separaten Threads gearbeitet? Da solltest du eventuell noch ein bissel dazulernen. Dann kommt sowas nämlich nicht mehr vor. Bei meinem o.g. PC-Programm für den Wobbler hatte ich den gesamten Verkehr zwischen PC und PIC in einen separaten Thread ausgelagert. Das entkoppelt alle UI- und Bildschirm- Obliegenheiten sehr schön von der Datenübertragung. Aber dein Einwurf ist dennoch gut, denn er zeigt etwas ganz anderes sehr deutlich: Bei einer seriellen Schnittstelle muß man immer damit rechnen, daß die Verbindung nie wirklich schulbuchmäßig ist und eben DESHALB sein Protokoll auf der Seriellen so einrichten, daß es sich ohne Probleme wieder selbst synchronisiert. Bei einer sturen Blockübertragung ist das erwiesenermaßen ne Schwierigkeit. W.S.
Adam P. schrieb: > denn sollte dies so eine größer Sicherheit bringen, würden > TCP/IP ASCII basiert sein :-D kaum vorstellbar... > > Ich übertrage alles binär, so kannst du auch direkt strukturen zum > versenden laden, wenn du sicher stellst, dass das alignment stimmt. Du schmeißt hier alles durcheinander. Bedenke mal, daß gerade Ethernet und TC/IP als blockorientierte Übertragungen völlig anders organisiert sind als eine simple UART-Verbindung. Und das sowohl hardwaremäßig als auch bzgl. der logischen Layer. Und wenn du "alles binär" überträgst, dann ist das wie der Tanz auf dem Rand des Vulkans. Es kann recht oft gut gehen, aber man kann damit auch barbarisch auf die Nase fallen, denn es gibt keine Sicherheiten in jeglicher Hinsicht. ich stell mitr grad mal vor, rein binär nen struct auszutauschen zwischen einem 8 Bitter und einem 32 Bitter oder mal bloß zwischen einem Cortex M0 und einem M4, wo beim einen misaligned Zugriff möglich ist was beim anderen in die Hose geht. Kurzum, rein binäre Übertragungen bedürfen ihrerseits eines Austausch-Protokolls und so müssen beide Parteien an den Daten herumrechnen. Von wegen "alles binär"... W.S.
Jörg W. schrieb: > Es ist entweder bei keinem wie beschrieben oder bei allen möglich. Schon wieder stellst du Behauptungen auf. Woher nimmst du die Chuzpe, über "bei allen" hinzuschreiben? Du kennst doch mit Gewissheit nicht Alle, sondern nur all diejenigen, die dir grad einfallen. Von mir wirst du wohl kaum Behauptungen lesen, die sich auf Zeugs beziehen, was ich nicht oder zu wenig kenne - allenfalls mehr oder weniger fundierte Vermutungen. Das ist wohl der Unterschied, gelle? W.S.
W.S. schrieb: > Und wenn du "alles binär" überträgst, dann ist das wie der Tanz auf dem > Rand des Vulkans Wenn man es falsch macht vielleicht. W.S. schrieb: > denn es gibt keine Sicherheiten in > jeglicher Hinsicht. Es gibt den C-Standard, der diverse Dinge garantiert. Wenn man nur diese Dinge annimmt, kann man auch problemlos binär Daten übertragen. W.S. schrieb: > ich stell mitr grad mal vor, rein binär nen struct > auszutauschen zwischen einem 8 Bitter und einem 32 Bitter oder mal bloß > zwischen einem Cortex M0 und einem M4, wo beim einen misaligned Zugriff > möglich ist was beim anderen in die Hose geht. Überhaupt kein Problem bei portablem, korrektem Code. Wie sonst können binäre IP-Pakete zwischen allen möglichen Plattformen ausgetauscht werden, und offenbar effizient genug für sehr große Datenraten? W.S. schrieb: > Kurzum, rein binäre > Übertragungen bedürfen ihrerseits eines Austausch-Protokolls und so > müssen beide Parteien an den Daten herumrechnen. Das Rechnen beschränkt sich auf Bitshifts, die sind meist sehr effizient und können von Compilern gut optimiert werden. Besser als ASCII-Kodierung allemal. W.S. schrieb: > daß es sich ohne Probleme > wieder selbst synchronisiert. Bei einer sturen Blockübertragung ist das > erwiesenermaßen ne Schwierigkeit. Ja, es erfordert etwas zusätzlichen Aufwand. Das ist aber ein alter Hut und ist schon lange gelöst, selbst bei Shared Medium Systemen (Ethernet, WLAN).
Achim S. schrieb: > Kommt eines der 3 Zeichen > im Datenstrom vor, so wird 0xcc gesendet und das zeichen danach z.b. um > 0x80 verändert. Soso, und wenn im Datenstrom nativ 0xCC vorkommt? Und wenn im Datenstrom nativ 0xCC und dann 0x2A? Klar kann man das mit weiteren "Stuffbytes" erschlagen. Aber der Witz ist ja, dass im binären Datenstrom prinzipiell jede Kombi vorkommen könnte, die man sich auch als "Stuffbytes" vorstellen kann.
W.S. schrieb: > Du hast also NICHT mit separaten Threads gearbeitet? Da solltest du > eventuell noch ein bissel dazulernen. Mit Multithreading holt man sich wieder andere Probleme rein, und es war in dem Fall unnötig. Bekommt man auch ohne hin. Aber danke dass Du Dir um meinen Lernzustand Gedanken machst. Ist aber auch unnötig.
Karl schrieb: > Achim S. schrieb: >> Kommt eines der 3 Zeichen >> im Datenstrom vor, so wird 0xcc gesendet und das zeichen danach z.b. um >> 0x80 verändert. > > Soso, und wenn im Datenstrom nativ 0xCC vorkommt? > > Und wenn im Datenstrom nativ 0xCC und dann 0x2A? > Genau, deswegen wird das Escapezeichen selber auch immer transponiert. Damit gibt es grundsätzlich nur eine kleine Menge Sequenzen, die legal einem Escape folgen dürfen. Das funktioniert auch extrem robust und zuverlässig.
Niklas G. schrieb: > Das Rechnen beschränkt sich auf Bitshifts, die sind meist sehr effizient > und können von Compilern gut optimiert werden. Besser als > ASCII-Kodierung allemal. Siehste, und das ist der Witz an der Sache: Da hat mal jemand mit irgendwelchen Stringoperationen in C versucht Binär in ASCII zu wandeln, was der Compiler dann beschissen und mit ganz vielen Divs umgesetzt hat. Dann wars so arschlahm, dass fortan des Urteil feststeht: ASCII-Konvertierung ist langsam. Binär in ASCII mit feststehender Stelle (10er) geht über Subtraktion in wenigen Takten, ich schätze jetzt mal 60 Takte pro Stelle maximal. ASCII in Binär geht mit Multiplikation in etwa 10 Takten pro Stelle bei 16 Bit, bei 8 Bit in 5 Takten. Man multipliziert einfach den bisherigen Wert mit 10 und addiert die neue Ziffer dazu. ASCII in Binär bei ATtinys ohne mul-Befehl geht mit einigen Shifts. x10 ist nämlich einfach x2 + x8. Sind 3 Shifts und 2 Additionen. Binär in Hex oder Hex in Binär geht rein über swap, and und add. Achso, und was die unglaublich vielen 60 Takte von oben angeht: Das Rausschieben dieser Stelle bei 8MHz und 115kBaud dauert mehr als Zehnmal solange.
Karl schrieb: > Binär in ASCII mit feststehender Stelle (10er) geht über Subtraktion in > wenigen Takten, ich schätze jetzt mal 60 Takte pro Stelle maximal. Da es um ATmega geht: Beitrag "schnelle Wandlung long -> ASCII"
Karl schrieb: > Binär in ASCII mit feststehender Stelle (10er) geht über Subtraktion in > wenigen Takten, ich schätze jetzt mal 60 Takte pro Stelle maximal. Ich hab nicht gesagt dass der Unterschied gigantisch ist; es ging mir nur um W.S.' Argument, dass Binär mit (viel) Rechnen verbunden ist. Karl schrieb: > Achso, und was die unglaublich vielen 60 Takte von oben angeht: Das > Rausschieben dieser Stelle bei 8MHz und 115kBaud dauert mehr als Zehnmal > solange. Klar, aber es kann ja auch sein dass man noch andere Dinge laufen lässt, für die man die Rechenzeit braucht.
Niklas G. schrieb: > Klar, aber es kann ja auch sein dass man noch andere Dinge laufen lässt, > für die man die Rechenzeit braucht. Ja aber mal ehrlich: Bei den meisten Anwendungen rödelt der Controller eh meistens in der Schleife und könnte nebenbei noch Seti rechnen. Gerade wenn es um die Abfrage irgendwelcher Sensorwerte geht. Ich hab letztens die Umrechnung der Sensorwerte eines BMP180 Drucksensors anhand dessen Kalibrierdaten gemacht. Da sind so viele Divs drin, bei 8MHz braucht der 5msec zur Wandlung eines Wertes. Da gönn ich mir auch den Luxus, die Werte dann per nRF in ASCII zu übertragen.
Karl schrieb: > Ja aber mal ehrlich: Bei den meisten Anwendungen rödelt der Controller > eh meistens in der Schleife und könnte nebenbei noch Seti rechnen. Könnte sein. Energieverbrauch bei Akku-Betrieb wäre noch ein Punkt - aber ok, wenn man mit einem PC kommuniziert hat man wahrscheinlich eh Netzbetrieb. Andererseits wird hier im Forum oft auf den letzten Takt optimiert... Wenn man es wagt die Nutzung von C++ vorzuschlagen wird direkt dagegen diskutiert weil es den einen oder anderen Takt langsamer sein könnte (was ohnehin zweifelhaft ist).
:
Bearbeitet durch User
Niklas G. schrieb: > Andererseits wird hier im Forum oft auf den letzten Takt optimiert... > Wenn man es wagt die Nutzung von C++ vorzuschlagen wird direkt dagegen > diskutiert weil es den einen oder anderen Takt langsamer sein könnte > (was ohnehin zweifelhaft ist). Beispiel: Ein 8-Kanal-PWM-LED-Dimmer mit 300Hz in Software. Ist in Assembler vom Timing ausgereizt. Dennoch kann man problemlos die Steuersignale mit 9600baud in Ascii konvertieren, nebenher noch ein Display mit Zeichen beschicken, natürlich auch mit ASCII-Konvertierung und eine Tastenmatrix abfragen. Weil der Dimmer im Interrupt läuft, während der Rest nebenher rödelt und es ihm nicht schadet, wenn der Interrupt immer mal dazwischengrätscht. Optimieren da, wo es drauf ankommt.
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.