Archiv verlassen und diese Seite im Standarddesign anzeigen : UART vs. I2C, Was ist schneller?
Fabian E.
19.07.2012, 20:39
Hallo,
ich habe heute mal eine etwas speziellere Frage:
Es geht um das Thema Geschwindigkeit. Da ich nun dank Arexx ein M256 Modul besitze, muss ich mir überlegen, wie genau die Kommunikation zwischen den Modulen ablaufen soll.
Ich habe außerdem ein M128 Modul, welcher leider nicht als I2C Slave benutzbar ist (zumindest nicht ohne Probleme)
Daher muss mein neues M256 als Slave herhalten aber trotzdem als zentrale Kommunikationseinheit mit meinem PC dienen. (Sonst wäre das Wlan ja sinnlos :D )
Nun die eigentliche Frage: Ich muss viele Daten vom I2C Master (M128 ) zum M256 übertragen. Das sind alles Sensordaten, also floats und ints.
Was wäre in diesem Fall günstiger:
Alle Daten über I2C vom Master zum Slave schreiben und dann per Wlan weiter zum PC
Oder vom Master per UART zum Slave und dort dann einfach alles was per UART kommt aufs Wifi spiegeln?
Primärer Entscheidungspunkt wäre die Geschwindigkeit / Latenz der Übertragung. Die entstehende Prozessorlast wäre eher zweitrangig. Allerdings wäre bei der I2C Variante die Rechenlast besser verteilt, da ich die Analyse der PC Befehle auf der M256 machen könnte. Die M128 würde die Befehle dann nur noch umsetzen.
Der Rückweg wäre analog dazu. Also Befehle die vom PC kommen werden entweder in I2C Register geschrieben oder per UART an den Master übertragen.
Das würde mich auch sehr interessieren, ich vermute, dass UART bei einer passenden Baudrate (etwa >=115.2kBaud) schneller ist als I2C (das läuft auf dem RP6 standardmäßig mit 100kHz), wobei durch das erforderliche neue Protokoll je nach Implementierung einiges an Overhead entstehen wird. Passende Baudraten kannst Du z.B. hiermit: http://www.gjlay.de/helferlein/avr-uart-rechner.html errechnen. Noch dazu musst Du bei UART keine Rücksicht auf den fehlenden I2C-Slave des M128 nehmen.
Das sind alles Sensordaten, also floats und ints.
Hier wäre es eventuell von Vorteil, die Sensordaten im "Rohformat" zu übertragen und sie erst auf dem PC/Endprozessor umzuwandeln. Das kann die Datenmenge eventuell schon einmal etwas reduzieren.
Fabian E.
19.07.2012, 22:05
Die Übertragung von der "Einheit" RP6 zum PC ist kein Problem, über Wifi sind das 40-50 KB/s, das ist deutlich mehr als benötigt.
Nur die Kommunikation "intern", also auf dem RP6 ist interessant.
Ich habe ehrlich gesagt keine Ahnung, wie schnell so ein I2C Bus ist, wenn man allerdings per UART überträgt müsste ich eine weitere Entscheidung treffen:
Entweder werden die Daten "formatiert" zwischen M128 und M256 übertragen und die M256 spiegelt einfach alles auf den Wifi Ausgang
Oder die M128 sendet alles "raw" und die M256 muss die Daten interpretieren und dann formatieren und per Wifi senden
Die zweite Alternative halte ich für Verschwendung von Rechenleistung.
Eine andere Alternative ist: M128 I2C Bus deaktivieren, M256 als Master...
Verbindung zwischen M256 und M128 nur per UART und ein paar GPIOs für Interrupts...
Reduziert die Menge der Daten die erst per I2C zur M128 und dann per UART zur M256 gehen müssen da diese den Rest vom Bus
einfach selbst abfragt. Die M128 kümmert sich dann nur um die Sensoren die lokal angeschlossen sind. Das ist dann ähnlich
wie wenn man die M32 als I2C Slave benutzt, aber spart Bandbreite auf dem I2C Bus.
Bitte beachten, dass die M128 ein 14.7456 MHz Baudratenquarz verwendet, die M256 allerdings nicht (um die maximale Taktfrequenz zu erreichen).
Daher sind Baudraten bis 115k möglich, darüber wäre die Abweichung zu hoch. Sollte aber reichen.
Beim I2C Bus ist die Datenrate bei gleicher Bitrate geringer als beim UART, da ja noch Adressen und ggf. Registeradressen sowie ACK/NACK übertragen werden.
Kommt dann drauf an wieviele Daten man in einer Transaktion schreibt - also einmal die Adresse und Startregister übertragen und dann 255 Bytes übertragen ist deutlich schneller als wenn man jedes Byte in einer einzelnen Transaktion sendet.
(das läuft auf dem RP6 standardmäßig mit 100kHz),
Spricht aber nix dagegen das auf 400kHz zu erhöhen wenn mans braucht. Dann würde ich schätzen hat man bei typischer Verwendung eine ähnliche effektive Datenrate wie bei 115k - 230k UART.
MfG,
SlyD
Fabian E.
19.07.2012, 23:18
Das wäre in der Tat eine Alternative. Danke auch für den I2C Tipp, das wäre bei dieser Variante ja ziemlich wichtig.
Das klingt für mich jetzt so, als ob es keinen riesen Unterschied macht. Mal sehen was sich leichter implementieren lässt / besser wartbar ist :)
oberallgeier
19.07.2012, 23:25
... M128 ein 14.7456 MHz Baudratenquarz ... 115k möglich, darüber ... Abweichung zu hoch...Ich habe mir mit nem FTDI einen Eigenbau USB-UART-Wandler (klick (https://www.roboternetz.de/community/threads/36416-RS232-Wandler-in-SMD?p=368059&viewfull=1#post368059) und Bild unten) gebaut - da fahre ich problemlos 256K vom Controller zum PC mit dem Terminal von br@y, vermutlich ist noch mehr möglich. Da vermute ich, dass auch eine evtl. Controller-Controller-Verbindung ähnlich schnell arbeiten könnte.
......http://oberallgeier.ob.funpic.de/mini-SMD-1-DSC_1656+x54.jpg
Allerdings habe ich meine Sende-define-BAUD gelogen:
// CPU definiert im AVRStudio
// #define BAUD 57600 //
#define BAUD 230400 // Diese Einstellung bei USB-Adapter - 256000
Die Fehlermöglichkeit des UARTS durch die ganzzahlige UBRR spielt da offensichtich keine Rolle, ich bin aber dem Grund dafür noch nicht nachgegangen. Allerdings hatte ich mir das bei Verwendung des max232 mal zu Gemüte geführt (klick)
(https://www.roboternetz.de/community/threads/42185-Baudraten-define-xxx-und-einige-Auswirkungen?p=403120&viewfull=1#post403120)
Besserwessi
19.07.2012, 23:47
Wenn auf die Beschränkung auf eine der üblichen Baudraten entfällt, sollte sich für die beiden Quarztakte vermutlich auch noch eine höhere gemeinsame Baudrate (z.B. 193 kBaud) finden lassen.
Noch schneller wäre ein Verbindung per SPI.
Die Übertragung als raw, und dann erst umrechnen ist nicht so abwegig. Es kommt halt darauf an welcher µC noch Rechenleistung über hat. Sonst ggf. die Daten erst am PC vom RAW Format umrechnen.
@Oberallgeier:
Klar geht das mit dem FTDI mit alle möglichen Baudraten - der RP6 nutzt ja auch 500k Baud für den Bootloader.
(Und zum WLAN Modul auch weil es da vom Takt her genau passt)
Der FTDI hat aber auch einen fraktionalen Baudraten Generator drin und kann so ziemlich alle denkbaren Baudraten passend erzeugen.
Die ATMEGAs haben sowas nicht, daher ist der Quarztakt wichtig.
Alles +-3% Abweichung ist übrigens OK.
MfG,
SlyD
Hallo zusammen
Das schnellste wäre wirklich die SPI Schnittstelle.
Beim I2C Bus könnte es aber sein, dass nicht alle Sensoren mit 400kHz arbeiten können.
Normalerweise hat man pro I2C Bus nur einen Master. Es ist aber auch ein Multi Master Mode möglich. Mit dem RP6 weiss ich zwar nicht, ob das gehen wird, aber du könntest dann die M128 und M256 als Master betreiben.
Grüsse Filou
Jo klar!
die M256 holt sich alle Sensordaten der anderen Module (Base, M32, M128 und seine eigenen) aus den Registern und gibt sie an den PC weiter.
außerdem gibt sie via WLAN empfangene Befehle an die M128 über UART weiter, welche dann die Befehle als Master ausführt und weitergibt...
kann das so laufen???
Klingt jedenfalls spannend ;)
Jetzt habe ich eine ähnliche Frage:
Ich habe eine kleine Beschleunigungs-sensor-platine. Sie lässt sich entweder über I2C oder SPI anschliessen. Was macht mehr Sinn? Soll ich den I2C Bus möglichst für die Kommunikation unter den Platinen freihalten?
Grüsse
Ich denke, das ist eher eine persönliche Geschmacksfrage als von technischen Notwendigkeiten abhängig. Zumindest im Hobbybereich.
Hat man eh schon I2C Bausteine, kann man bei I2C bleiben zumal sich Code wiederverwenden lässt und man so vielelicht ein paar Byte einspart.
(Soft-Hardware)SPI hat aber auch Vorteile... z.B. das sich da Geräte eben nicht gegenseitig beeinträchtigen da SPI Slaves meist eigene Hardware-CS Signale haben (wie z.B. Speicherkarten).
Ich seh kein Grund, um die eine oder andere Schnittstelle nen Bogen zu machen oder zu preferieren. RS232 & co ist meist langsamer aber erlaubt größere Leitungslängen... I2C ist ein Bus System.. und SPI irgendwas dazwischen.... und mit allen sind etwa gleiche Speeds möglich - je nach verwendeter Hardware. Man braucht nur eben für jedes Protokoll auch ein eigenen Protokollstack. Das ist aber immer so.. egal ob nu 1-Wire - bis hin zu Ip per Funk oder wlan. Und je aufwändiger die Hardware, um so umfangreicher der Stack. Man kann sogar die I2C oder die SPI mit RS485 Leitungstreibern versehen, Konverter für den CAN bus anbringen oder sonst was frickeln... es gibts so viele serielle Busse.. die eigentlich immer gleich funktionieren... USB und selbst SATA ist nichts anderes, nur sind die eben extrem auf Speed ausgelegt.
Die einzige Überlegung, die für dich relevant ist, dürfte aber sein: Wo bekomme ich einen stabilen Stack her, wie komplex ist der... und passt er noch zusätzlich ins ROM der CPU.
Letztlich läuft auch alles auf ein einheitliches Software Interface hinaus... getchar, putchar... (de)selektieren von Geräten per open und close, Fehlerbehandlung, Ringbuffer für send/receive, Softwarefehlerkorrektur usw... zumindest wenn man es anständig programmiert. Denn auch da lassen sich dann später Synergieen nutzen. Da auf dem RP6 aber eher Lowlevel-Bitgefrickel betrieben wird, dürften so Ansätze aber eher Theorie bleiben... was mich wieder zu meinem Eingangssatz bringt.
Gruß Rolf
Mein Vorschlag zur Einbindung der M128 in ein "RP6-Multimikroprozessorsystem" (klingt das nicht gut?), das zwischen den Plattformen als Single-Master-I2C implementiert wird, wäre:
Wir einigen uns darauf, ...
1. Die M256 WIFI wird Master.
2. RP6Base und M32 sind Slaves.
3. In einem gemeinsamen Projekt entwickeln wir einen universellen M32-Slave (genau wie der Base-Slave).
4. Die M128 wird nicht über I2C eingebunden.
5. Eine µC-µC-Direktverbindung (wie von SlyD vorgeschlagen) wird zwischen M128 und M256 über UART eingerichtet, und zwar von UART1 der M128 zu UART1 der M256 (beide bisher nicht genutzt). Vorteil: Weiterhin kann der RobotLoader oder ein Terminal an beiden Platinen an PROG_UART angeschlossen bleiben.
6. Mit einem Speed-Test ermitteln wir die noch sicher mögliche serielle Übertragungsrate zwischen M128 und M256.
7. Auf der M128 entsteht ein UART-Slave (meine spontane "Erfindung"), über die die M256 ähnlich Daten abfragen kann, wie von den I2C-Slaves.
8. Als "Interrupt-Leitung" zwischen M128 und M256 nutzen wir INT3 des XBUS (M128: INT6, M256: PCINT14). Vorteil 1: Der für I2C benutzte INT1 bleibt frei. Vorteil 2: Auch die M32 KANN diese "Interrupt-Leitung" lesen und schreiben (INT2).
So viel erst einmal ins Unreine gesprochen. Akzeptabel?
@Dirk
Ich bin nach wie vor der Meinung, das ein Multimaster/Salve-I2C Bus Treiber auf allen Plattformen das Problem "RP6-Multimikroprozessorsystem" besser lösen würde und letztlich flexibler ist.
Einzig die M128 ist wegen dem "C-Betriebssystem" erst mal als Slave aussen vor, und als Master im Pollbetrieb recht begrenzt, ich halte es aber auch da für möglich, sowas zu nutzen. Nen IRQ Vector läst sich ja verbiegen.
UART Verbindungen sind natürlich auch möglich, aber nicht weniger Arbeit bezüglich coden - wobei es im Remotrol Projekt bereits ein I2C-Slave für die M32 gibt. Auch die M256 wäre Slave-tauglich und nichts hindert daran, die M128 weiter als "dummer" Master zu nutzen. Ausserdem braucht die M256 ihren mikerigen Speicher um einen Webserver per WLAN bereit zu stellen...
Das Ganze System von I2C auf UART zu krämpeln löst bestimmte Probleme eben nicht - bis auf die Tatsache das bessere UART Treiber Hardware/Software Ringbuffer haben und daher nicht so viel verloren geht... die mögliche Speed bei ALLEN Boards liegt bei deutlich über 400Kbit/sec - wenn man vernünftige I2C Treiber hätte...
LG Rolf
@Rolf:
Ich bin nach wie vor der Meinung, das ein Multimaster/Salve-I2C Bus Treiber auf allen Plattformen das Problem "RP6-Multimikroprozessorsystem" besser lösen würde und letztlich flexibler ist.
Sehe ich genau so. Allerdings müßte man das coden. Was machen deine Tests in die Richtung (https://www.roboternetz.de/community/threads/51816-Dicker-Fehler-in-der-RP6I2CmasterTWI-h-der-RP6Lib-Bugfix)?
Das Ganze System von I2C auf UART zu krämpeln löst bestimmte Probleme eben nicht ...
Sehe ich auch so. Aber nur zwischen der M128 und M256 könnte es eine Lösung sein, falls man die M128 überhaupt mitnehmen will ...
Also mir sagt die Idee von Dirk mehr zu, schon nur wegen der gut klingenden Ausdrücke ;)
Man hätte dann sozusagen einen Roboter mit zwei Gehirnen, die sich über eine UART austauschen.
Es wäre dann noch schön, der M256 I2C Master Lib die Befehle für die M32 beizubringen. Eine M32Slave version gibt es schon, ist aber noch nicht ganz vollständig, sofern ich mich richtig erinnere.
Bei Punkt drei würde ich auf jeden Fall auch mithelfen. Ich habe bloss keine M128!
Grüsse
Filou
@Filou89
Nun wie ich oben schon sagte... sowas liegt im ermessen des Entwicklers.. und ist keine Frage die man demokratisch lösen könnte. Ich hab auch was gegen "Glaubensfragen" beim programmieren denn es verschließt ggf. einfachere oder bessere Lösungsmöglichkeiten.
@Dirk
Zu deiner Frage bezüglich I2C, ich bin letztlich zu dem Schluß gekommen, das die aktuelle Struktur der RP6 Lib eine performante Lösung mit I2C nicht erlaubt. Das liegt an vielen Faktoren.
Für einen Multimasterbetrieb bzw. Master/Slave Betrieb gibts auch funktionierende Ansätze z.B. bei ArudinoLibs usw. aber da der RP6 in der Originalfasung der RP6Lib rein interrupt gesteuert ist, sind geregelte Abläufe vom guten Willen der Anwendung und weiteren Einflüssen wie Fahrkomandos bzw. Encoder interrupts abhängig. Oft genug wird in der RP6Lib gepollt und cpu-Zeit verbrannt was letztlich kein befriedigendes Ergebnis liefert.
Daher mein Engagement für RTOS und dort demnächst auch da mit einem I2C Treiber der stabiler und schneller laufen sollte. So meine Hoffnung/Planung. Das Thema ist für mich noch nicht vom Tisch.
LG Rolf
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.