Hallo Leute, ich wollte ein paar 16bit Sensorwerte auf dem PC darstellen. Der Sensor ist an einem Atmega324p (16MHz) angeschlossen. Für die Kommunikation nutze ich einen Ft232r und einen virtuellen COM-Port. Es klappt alles wunderbar, allerdings ist die Kommunikation recht langsam. Ich betreibe es momentan bei 38400 Baud. Da wäre sicher noch mehr drin, allerdings soll erst mein eigenes Kommunikationsprotokoll optimiert werden. Zur Kommunikation: Ich muss jeden Wert einzeln erfragen, was auch so bleiben soll. Dazu schicke ich vom PC Programm einen String "b1" (für Sensor b und Channel 1).Der Atmega bekommt einen Interrupt, wertet den String aus und liefert den geforderten Sensorwert zurück. Dafür wandelt der Atmega den 16bit Integer in einen String und schickt diesen. Der String wird vom PC empfangen und wieder in einen Integer umgerechnet.Klappt wunderbar, allerdings wird jede Zahl einzeln als String geschickt, das ist nicht besonders effizient. Gibt es da eine bessere Variante oder kann ich auch irgendwie direkt Integer über den COM-Port schicken? Vielen Dank
Peter schrieb: > Klappt wunderbar, > allerdings wird jede Zahl einzeln als String geschickt, das ist nicht > besonders effizient. das würde aber kaum etwas ändern. Deine Übertragung ist so langsam, weil du jeden Wert einzeln abfragst. Damit bringt es fast nichts, ob man nun 2 oder 5byte für eine Zahl überträgt. Aber du kannst es gerne versuchen, einfach den 16bit wert in 2bytes zerlegen und diese direkt übertragen. Nur hast du damit ein Problem, das dann auch Sonderzeichen entstehen können, ob du damit klar kommt hängt daovn ab wie du den Protokoll umgesetzt hast.
Peter schrieb: > Da wäre sicher > noch mehr drin Mit einem 14,7456MHz Quarz. Peter schrieb: > kann ich auch irgendwie direkt > Integer über den COM-Port schicken? Dann mußt Du Dir erstmal ein Protokoll ausdenken, was die Paketerkennung gewährleistet. Beim String hast Du das durch das "\n" am Ende gewährleistet.
Du kannst beliebige Daten verschicken, dazu musst Du sie nur in einzelne Bytes zerstückeln. Allerdings solltest Du ein Protokoll verwenden, bei dem Du (resp. Dein Programm) erkennen kann, wo ein Datensatz beginnt und wo er endet. Daher ist es nicht ausreichend, Deinen "int" als zwei bzw. vier einzelne Bytes zu senden -- wenn Dein sendendes und Dein empfangendes Programm "aus dem Takt" geraten, was z.B. beim Stecken/Trennen der Verbindung leicht passieren kann, dann kommt nicht das an, was Du erwartest, sondern Quark. Daher ist die Übertragung als Text, auch wenn sie ineffizient erscheinen mag, gar nicht so schlecht. Das simpelste Protokoll ist bei der Textübertragung die Zeile, d.h. ein Datensatz wird mit \n abgeschlossen. Wenn Du tausende von Werten übertragen willst, ist eine Effizienzbetrachtung angebracht, aber wenn Du nur gelegentlich mal einen Sollwert vorgeben willst, ist das eher irrelevant.
Rufus Τ. Firefly schrieb: > Wenn Du tausende von Werten übertragen willst, ist eine > Effizienzbetrachtung angebracht, aber wenn Du nur gelegentlich mal einen > Sollwert vorgeben willst, ist das eher irrelevant. Mhm, ich würde meine Daten ja gerne als Graph anzeigen. Nun komme ich vielleicht auf eine max. Abtastrate von 1kHz. Falls ich dann noch 2 Sensoren abfrage sinkt die Rate leider deutlich. Ich dachte das Problem hätte bestimmt schon jemand gelöst und ich könnte einen "offenen" Code verweden. Aber dann werde ich wohl erst einmal die Baudrate erhöhen
Peter schrieb: > Ich dachte das Problem hätte bestimmt schon jemand gelöst Im Normalfall löst man dieses Problem, indem man die Telegramme vergrößert - also nicht jeden Wert einzeln abfragt, sondern Wertegruppen, z.B. eine Sensorgruppe oder einen gepufferten Werteverlauf eines einzelnen Sensors. Und wenn das dann immer noch zu langsam ist, gibt es noch mehr Standardmethoden, z.B. Komprimierungsverfahren. Aber um das zu beschreiben, müßte man mehr über Deine Anforderungen an Latenz und Bandbreite wissen. "Als Graph darstellen" klingt zum Beispiel nach sehr geringen Anforderungen in der Latenz.
Peter schrieb: > Mhm, ich würde meine Daten ja gerne als Graph anzeigen. Nun komme ich > vielleicht auf eine max. Abtastrate von 1kHz. Falls ich dann noch 2 > Sensoren abfrage sinkt die Rate leider deutlich. ja, aber das liegt ja nur ein deinem Protokoll. Ich würde es so machen: PC sagt welchen Sensor wie oft abgefragt werden soll. µC sendet selbstständig alle werte ohne das der PC dafür etwas machen muss. Vor jeden wert kommt einfach die Kennung vom welchen Sensor. Damit kannst du die Leitung fast 100% auslasten und du hast kein Zeitproblem mehr.
Peter schrieb: > Ich betreibe es momentan bei 38400 Baud. Peter schrieb: > Nun komme ich > vielleicht auf eine max. Abtastrate von 1kHz. Das kann man doch einfach ausrechnen. Nehmen wir mal an, der String hat 5 Byte (4 Hex-Digits + \n): 38400 / 10 / 5 = 768 Hz
Walter Tarpan schrieb: > "Als Graph darstellen" klingt zum Beispiel nach sehr geringen > Anforderungen in der Latenz. Ja, das ist nur ein Hobbyprojekt. Ich will ein bisschen mit verschiedenen Sensoren spielen und vielleicht eine kleine Regelung aufbauen. Peter II schrieb: > Ich würde es so machen: > > PC sagt welchen Sensor wie oft abgefragt werden soll. > µC sendet selbstständig alle werte ohne das der PC dafür etwas machen > muss. Vor jeden wert kommt einfach die Kennung vom welchen Sensor. Das klingt schon sehr gut... Momentan möchte ich die Einzelwertabfrage behalten, weil ich auch eine kleine Regelung am PC (nicht auf dem Atmega) realisieren will. Je nach Abtastwert soll dann zwischendurch noch ein Wert an ein Stellglied geschickt werden. Wahrscheinlich bieten sich dann zwei Modi an. Zusätzlich zur Einzelwertabfrage realisiere ich auch deine Paketabfrage. Peter Dannegger schrieb: > Nehmen wir mal an, der String hat 5 Byte (4 Hex-Digits + \n): > 38400 / 10 / 5 = 768 Hz Das passt schon ganz gut, dann reicht mir die Erhöhung der Abtastrate eigentlich.
Peter Dannegger schrieb: > Das kann man doch einfach ausrechnen. > Nehmen wir mal an, der String hat 5 Byte (4 Hex-Digits + \n): > 38400 / 10 / 5 = 768 Hz nein kann man nicht. Es kommt ja noch die zeit für die Abfrage dazu. Dann kommt auch noch die Verbartungszeit auf beiden Seiten dazu weil es scheinbar ein synchrones Protokoll ist. PC -> µC "b1\n" 3byte µC verarbeitet ? ms µC -> PC 1234\n 5byte USB Latenz ? ms PC verarbeitet ? ms dann geht es wieder von vorne los. Damit wird mal nie sinnvoll schnell werden.
Peter schrieb: > Der Sensor > ist an einem Atmega324p (16MHz) angeschlossen. da kannst du doch bis 1M baud gehen http://forum.arduino.cc/index.php?topic=240000.0 der FTDI oder CH340 macht das mit! leider erlaubt Hyperterminal nur 921600 Bd und Hterm nur 256000 Bd (Achtung 256kBd != 250kBd) 250kB und 1M geht prima mit 16MHz alle anderen brauchen eben Baudratenquarze für 921600 Bd wäre ein Baudratenquarz nötig https://www.mikrocontroller.net/articles/Baudratenquarz http://www.gjlay.de/helferlein/avr-uart-rechner.html http://wormfood.net/avrbaudcalc.php http://elektronik-kompendium.de/public/arnerossius/programme/windows/avrbaud.htm http://www.avrcalc.elektronik-projekt.de/xmega/baud_rate_calculator
Joachim B. schrieb: > leider erlaubt Hyperterminal nur 921600 Bd > und Hterm nur 256000 Bd (Achtung 256kBd != 250kBd) glaubst du, das er die Daten Hyperterminal abruft?
Hab mir den Beitrag nicht komplett durchgelesen, aber noch ein kleiner Hinweis: Nur die Baudrate hochschrauben bringt allein nix, richtig Speed bekommt das wegen dem USB-Serial-Converter erst wenn das größere Pakete sind. Das liegt daran dass USB-Pakete immer gleich lang sind - und X Bytes in ein Byte beinhaltenden Paketen zu senden dauert länger als X Bytes am Stück zu verschicken. Ralf
Vielleicht nicht exakt die Antwort, aber ein paar Anregungen... Ich habe mal eine Messverbindung zwischen Arduino (ATMega256) und PC aufgebaut. Dabei sollten je bis zu ca. 120Bytes ca. 50Mal pro Sekunde übertragen werden (48kBaud netto). Der Controller sendet: - 2 Byte Startkennung (bei mir $0D0A = Zeilenumbruch) - feste Anzahl Datenbytes - 2 Byte Prüfsumme Der PC synchroniert bei der ersten Messung: - lese bis $0D0A gefunden wird - lese feste Anzahl Datenbytes - lese Prüfsumme und vergleiche mit Selbstberechneter - wenn die Prüfsumme stimmt: Synch hergestellt - wenn nicht: war $0D0A wohl zufällig in den Nutzdaten -> nochmal Bei "lebenden" Messdaten, die sich ständig etwas ändern, ist es damit recht unwahrscheinlich, dass die Startsequenz permanent falsch erkannt wird. Zu erwähnen ist, dass der PC über USB verbunden die RS232-Schnittstelle auf PC-Seite per Treiber emuliert (soweit ich verstanden habe) und das die CPU-Last erstaunlich erhöht. Ich bin bei 65kBaud gebleiben, bei 115 gab es Probleme. Da kam der PC nicht mehr hinterher, die Daten wurden gepuffert und die Messung war dann nicht mehr Echtzeit sondern ein paar Sekunden verzögert. ------- Zum Rückkanal (Befehle PC and µC): Wenn keine Daten, sondern nur reine eindeutige 8Bit "Befehle", z.B. $01="Sensor1Aus" gesendet werden, braucht man dafür ggf. kein extra Protokoll. ------- Auch wenn die Daten nur auf Anforderung und nicht kontinuierlich gesendet werden, sollte man irgendwie markieren, um welches Datum es sich jeweils handelt. Ansonsten ist die zeitlich Zuordnung schwer, falls sich etwas verzögert oder außer Takt gerät.
CaptainAlbern schrieb: > Ich bin bei 65kBaud gebleiben, bei 115 > gab es Probleme. Da kam der PC nicht mehr hinterher, die Daten wurden > gepuffert und die Messung war dann nicht mehr Echtzeit sondern ein paar > Sekunden verzögert. dann war es ein Programmfehler. PC habe auch mit weit über 1Mbaud keine Problem wenn man es richtig macht.
Peter II schrieb: > nein kann man nicht. Es kommt ja noch die zeit für die Abfrage dazu. Die UART ist Full-Duplex, man kann also die nächsten Daten schon anfordern, bevor die vorherigen Daten eingetroffen sind. Sinvoller Weise spendiert man der UART auf dem MC eine FIFO und liest ständig den ADC (ADC-Interrupt), so daß man die Daten sofort losschicken kann. Als Flaschenhals bleibt dann wirklich nur die reine Senderate übrig. Ich mach das oft so, daß der Master die FIFO-Größe abfragen kann. D.h. er weiß also, wieviel Anfragen er auf einen Rutsch losschicken kann.
Peter Dannegger schrieb: > Peter II schrieb: >> nein kann man nicht. Es kommt ja noch die zeit für die Abfrage dazu. > > Die UART ist Full-Duplex, man kann also die nächsten Daten schon > anfordern, bevor die vorherigen Daten eingetroffen sind. deswegen habe ich geschrieben, das er vermutlich ein Synchrones Protokoll verwendet. Sonst könnte er ja gar nicht mehr erkennen, welchen zahl zu welcher Anfrage gehört. Und da hilft es nicht wenn Full-Duplex ist, wenn er es nicht nutzt.
Peter II schrieb: > glaubst du, das er die Daten Hyperterminal abruft? ich bin vor 47 Jahren ausgetreten, glauben ist nicht so mein Ding. Weisst du mit was er die Daten abruft und welche Baudraten er einstellen kann?
Peter schrieb: > Für die Kommunikation nutze ich einen Ft232r und einen virtuellen > COM-Port. Es klappt alles wunderbar, allerdings ist die Kommunikation > recht langsam. Wenn es dir auf Geschwindigkeit ankommt, dann machst du das Ganze in zweifacher Hinsicht grundfalsch. 1. Nimm anstelle des seriellen Chips von FTDI einen mit 8 Bit Parallelschnittstelle, denn da bist du frei von allen Baudraten-Beschränkungen. Kannst also mit größter Speed, was dein Atmel so hergibt, senden. 2. Versuche bloß nicht irgend ein Ping-pong-Protokoll. Also PC sendet "haben wollen", µC ermittelt und sendet "da isses" zurück. Sowas ist IMMER grottenlangsam. Laß den µC stattdessen lustig vor sich hinsenden, also Daten sammeln, in eine ausgemachte Protokollform bringen und dann raus damit. Das Programm auf dem PC muß aus dem sprudelnden Stream dann bloß noch sich das heraussuchen, was es haben will. So geht es am schnellsten. W.S.
Ein USB 2.0 time slot dauert immer 1ms egal ob du 1000 Byte oder 1 Byte sendest. Dann kommt noch die Antwort, die auch immer 1ms dauert egal ob 1 Byte oder 1000. Das ist halt so bei USB.
uwe schrieb: > Ein USB 2.0 time slot dauert immer 1ms egal ob du 1000 Byte oder 1 Byte > sendest. Dann kommt noch die Antwort, die auch immer 1ms dauert egal ob > 1 Byte oder 1000. Das ist halt so bei USB. Nö, in deinen Angaben stimmt fast garnix. Erstens hängt die Sache natürlich nicht direkt von der USB-Version ab, sondern vom "Speed-Grade". Von der USB-Version hängt nur ab, welche Speed-Grades überhaupt verfügbar sind. Bei USB2.0 gibt es LowSpeed(1,5MBit/s), FullSpeed(12MBit/s) und HighSpeed(480MBit/s). Bei LowSpeed und FullSpeed dauert ein "time slot" (richtiger: ein Frame) tatsächlich genau 1ms, bei HighSpeed hingegen nur 125µs. Da für ein "Ping-Pong-Protokoll" mindestens zwei Frames erforderlich sind, ist also die kürzestmögliche Latenz für Low/FullSpeed 2ms, für HighSpeed hingegen nur 250µs. Dazu kommen aber natürlich die Latenzen des OS und sofern es sich nicht um ein Echtzeit-OS handelt, können die die durch USB vorgegebene Mindestgröße der Latenz nochmal locker um ein bis zwei Größenordnungen "nach oben korrigieren", wenn im System gerade viel los ist.
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.