Forum: Mikrocontroller und Digitale Elektronik Motion Capture Suit mit Raspberry Pi und MPU 9250


von Marek W. (robotrovsky)


Lesenswert?

Hallo Zusammen!

Ich will mir gerne einen Motion Sensor Suit mit einem Raspberry Pi 2 und 
den Invensense MPU 9250 Sensoren bauen. Es gibt Breakout Boards mit den 
Sensoren direkt von invensense:
http://store.invensense.com/ProductDetail/EMSENSRMPU9250-Embedded-Masters/552444/

Der Raspberry PI beherrscht ja nun I2C und SPI, so wie auch die 
Sensoren. Ich habe gedacht, dass ich die Sensoren einfach per I2C 
anbinde, da ich gelesen habe, dass I2C etwas weniger anfällig für 
längere Leitungen ist. Ausserdem spare ich mir die extra Signalleitung 
und kann alle Sensoren schön in Reihe anschliessen. Die maximale 
Leitungslänge wäre ca. 1m.

Meint Ihr das ist richtig auf I2C dabei zu setzen? Ich sage mal im 
optimal Fall schliesse ich bis zu 11 Sensoren an, und will natürlich 
möglichst schnell die Daten bekommen.

Ich habe mir die Verkabelung ganz simpel so vorgestellt:

o = Sensor
| = Leitung
RPI = Raspberry Pi

    o
    |
o-o-o-o-o
    |RPI
    o
   / \
  o   o
  |   |
  o   o

Würde das so passen? Was ist mit Pull-Up Widerständen, und wenn ja wo 
schliesse ich die an? Bin Informatiker und kein Elektrotechniker, also 
bitte nicht viel Grundwissen voraussetzen, was Verkabelung und 
Widerstände angeht ;-)

Ausserdem habe ich etwas von einem I2C Line Driver gelesen. Da wollte 
ich mal fragen was das ist? Kann ich damit die 
Übertragungsgeschwindigkeit tunen, und wenn ja, wie 
konfiguriere/berechne ich den?

Wäre toll, wenn ich zu meinem simplen Projekt mal ein paar 
Expertenmeinungen bzgl Verkabelung und nötige Elemente (Widerstände, 
Switch?) bekomme.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Marco W. schrieb:
> Ausserdem spare ich mir die extra Signalleitung
> und kann alle Sensoren schön in Reihe anschliessen.

Nö, nur maximal 2 Stück, denn der MPU kann lediglich eine von 2 I²C 
Adressen benutzen. Du wirst also Sensoren/2 I²C Busse brauchen.

SPI kann alle Leitungen bis auf den Chip Select (/CS) gemeinsam nutzen, 
du wirst aber für jeden Sensor ein CS Signal erzeugen müssen. Bei vielen 
Sensoren auf einer Leitung wird aber die Treiberleistung interessant.

: Bearbeitet durch User
von Lukas P. (lks)


Lesenswert?

Servus,

die MPU9250 hat nur ein Adresspin (AD0) und somit ist es dir maximal 
möglich 2 verschiedene MPUs mit einem I2C anzuschließen. Alternativ 
müsstest du die AD0 leitung als eine Art Chipselect missbrauchen (klappt 
mit dem 9150 auf jeden Fall, selbst schonmal 5 Stück in dieser Form 
betrieben), da bräuchtest du allerdings noch zusätzliche Steuerleitungen 
(ähnlich SPI). Sonst ggf einen Multiplexer an den raspi schalten und so 
die I2C Leitungen multiplexen.

Welche Daten möchtest du überhaupt bekommen? Accel, Gyro, Mag? Oder die 
vom DMP berechneten 6 Achs Quaternionen? Mit welchen Datenraten?

Die Art und Weise des Multiplexens & die nötige 
Übertragungsgeschwindigkeit würde sich direkt auf die Wahl von 
Treiberbausteinen, Pullups etc. auswirken.

Gruß

: Bearbeitet durch User
von Marek W. (robotrovsky)


Lesenswert?

Danke für die schnelle Antwort. War ja schonmal gut, dass ich gefragt 
habe. Also benutze ich wohl besser SPI, oder? Und könntet ihr mir da 
Tips zur Verkabelung geben, oder ist das einfach Anschliessen aller 
Leitungen und der Rest Treiber-Gefummel?

von Pete K. (pete77)


Lesenswert?

Der Raspi hat die Pullups direkt auf dem Board verlötet, daher sollten 
die zusätzlichen Pullups auf den Adapterplatinen abgelötet werden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Du solltest die schwachen Ausgänge des RPi nicht direkt auf den externen 
Bus legen, vor allem, wenn da einige Sensoren mehr drauf liegen. Ein 
Ausgangstreiber für MOSI und SCLK sowie ein Eingangsgatter für MISO 
können da nicht schaden.
Da du sowieso nicht mehr als einen Sensor gleichzeitg ausliest, kannst 
du CS mit einen Dekoder/Multiplexer generieren und so GPIO sparen. Bei 
16 Sensoren wären 4 bit genug, bei 32 dann 5 bit.

von Marek W. (robotrovsky)


Lesenswert?

Servus Lukas!

Danke für die Antwort. Schön mal mit jemandem zu reden, der das schon 
gemacht hat. Ich will am liebsten erstmal nur die Accelerometer und 
Gyroskop Daten so schnell wie möglich bekommen. Der DMP ist sicher mal 
nett anzusehen, aber bisher hat mich noch keine hardwareseitige 
sensor-fusion überzeugt. Kalman-Filter, User-Acc-Calculator etc. habe 
ich am laufen, so wie ich mir das vorstelle. Das läuft dann alles auf 
dem RPI und wird dann per Ethernet oder WIFI weitergerreicht. Ich will 
die Orientierung zwischendurch mal mit dem Magnetometer norden. Aber das 
wird wenn nötig manuell an und ausgestellt, wenn das ein 
Bandbreitenproblem darstellen sollte.

Also was nehm ich jetzt SPI oder I2C mit Multiplexer(n)? Und gibt es was 
zu beachten, wenn ich so viele Teilnehmer anschliessen will?

von Marek W. (robotrovsky)


Lesenswert?

@Matthias: Danke für die Idee mit dem 4-Bit Multiplexer. Das mit den 
Ausgangstreibern und dem Eingangsgatter guck ich mir mal an, wie das 
macht.

von Lukas P. (lks)


Lesenswert?

Marco W. schrieb:
> Ich will am liebsten erstmal nur die Accelerometer und
> Gyroskop Daten so schnell wie möglich bekommen.
> ...
> Ich will
> die Orientierung zwischendurch mal mit dem Magnetometer norden. Aber das
> wird wenn nötig manuell an und ausgestellt, wenn das ein
> Bandbreitenproblem darstellen sollte.

So schnell wie Möglich könnten ~4kHz sein. Also 4000Hz  2 Datentypen  
2 Byte/Datentyp * 11 Sensoren = 176000 Byte/s. Das über ein bspw. 100kHz 
I2C zu bekommen ist problematisch ;). Die Magnetdaten kommen mit max 
100Hz (eher so ~80Hz). Dadurch wird man sich kein Bandbreitenproblem 
reinholen.

Motioncapture mit ~25-30Hz Ausgangsrate (also berechnete Lagedaten) 
sollte klappen. Aufnehmen würde ich dafür mit ~100-250Hz. Da schaut das 
mit der Bandbreite etwas besser aus.

Wenn du zu einem Zeitpunkt die Magnetdaten bekommen möchtest ist es 
einfacher dies via I2C zu realisieren, da der Magnetsensor intern in der 
MPU mit I2C angeschlossen ist. Da braucht man nur den bypass einschalten 
und kann mit dem ak8963 direkt kommunizieren. Via SPI ist das etwas 
komplizierter. Da gibt es in der MPU ein paar Register über die man die 
Kommunikation indirekt führen muss.

SPI kann natürlich höhere Datenraten, allerdings ist das für längere 
Strecken noch weniger geeignet, als I2C (was an sich idR schon nicht 
optimal ist bzw. bis ~40cm noch "geht").

Meine Lösung war damals die Sensoren mit jeweils einem uC zu versehen 
und eine Uart Busstruktur aufzubauen.

Gruß

edit:
Achja. Der Datensammler war dann auch kein Raspi bei mir sondern ein 
CortexM0, der die Daten über ein WLAN Modul rausgeschickt hat.

: Bearbeitet durch User
von Marek W. (robotrovsky)


Lesenswert?

@Lukas: Danke für das Feedback. Das sind sehr wertvolle 
Vorabinformationen für mich.

Ich werde mich jetzt erstmal in die Grundlagen einarbeiten. Insgeheim 
habe ich mir überlegt, per bit-banging aus den ganzen GPIO Pins so viele 
I2C Busse wie möglich zu machen. Ich hatte mir das so gedacht, dass ich 
mal schaue wie viele I2C Busse ich parallel untergebracht bekomme, dann 
kann ich die vorhandenen Busse parallel abfragen und spare Bandbreite. 
So weit ich gelesen habe, kann ich mit dem RPI2 31 GPIOs ansteuern. 
Würde also theoretisch für 15 Busse reichen, wenn jeder seinen eigenen 
SCL und SDA hat. Pro Bus will ich gerne 2 Sensoren anschliessen können. 
Der RPI ist sowieso ein Quad-Core, also ist das schon ok, wenn ich eine 
CPU exklusiv für das Treiben der Busse nutze. Ausserdem hätte ich so die 
minimale Leitungslänge zu jedem Empfänger. Für die Verbindung würde ich 
dann einfach ein Flachbandkabel mit 4 Adern an jedes Sensorpaar führen.

Ich bestelle mir jetzt mal den RPI2 und eine Hand voll MPUs und probiere 
per bit-banging 2 Sensoren über 2 GPIO-PINS auszulesen. Beispielcode 
gibt es ja genügend. Wenn das klappt, kann ich das ja auf die anderen 
GPIO-PINS auch anwenden und kann den Rest der Sensoren anschliessen.

Noch 2 kurze Fragen:

1. Muss ich wirklich die Pull-Up-Widerstände auf den Breakout-Boards 
rauslöten?

2. Wenn ich per Bit-Banging die GPIOs in I2C Busse umwandel, kann ich 
dann alle an eine gemeinsame Clock Leitung (SCL) hängen? Dann bräuchte 
ich ja nur noch SDA pro Bus. Oder vertue ich mich da mal wieder?



Vielen Dank für die ganzen hilfreichen Antworten! Ich bin da sehr 
dankbar für.

von Lukas P. (lks)


Lesenswert?

Marco W. schrieb:
> 1. Muss ich wirklich die Pull-Up-Widerstände auf den Breakout-Boards
> rauslöten?

Ich kenn die Widerstandsgrößen nicht. Einfach mal ausrechnen, ob das mit 
den Pullups irgendwo zwischen ~1k und 15k landet (10k sind quasi 
standard, bei langen Leitungen gerne etwas weniger).

> 2. Wenn ich per Bit-Banging die GPIOs in I2C Busse umwandel, kann ich
> dann alle an eine gemeinsame Clock Leitung (SCL) hängen? Dann bräuchte
> ich ja nur noch SDA pro Bus. Oder vertue ich mich da mal wieder?

Ich bin der Meinung, ein I2C Slave kann sowas wie Clockstreching machen 
(ob die mpu das beherrscht, weiß ich nicht), also die Clock 
manipulieren. Da könnte es zu komplikationen kommen, wenn mehrere slaves 
gleichzeitig versuchen an der Clockleitung rumzuzerren. Müsste man 
genauer nachlesen, was die mpu kann.

Noch eben was allgemeines zum Thema Magnetsensor: wenn zwei MPUs an 
einem Bus hängen, auch mit unterschieldichen Adressen, haben die AKs 
trotzdem die gleichen Adressen. Also musst du entweder wieder über die 
internen Register gehen, sodass die MPUs mit den AKs kommunizieren oder 
den I2C bypass Modus an und aus schalten. Am besten hat das für mich 
funktioniert zur Konfiguration des AKs den entsprechenden bypass 
anzuschalten, die Einstellungen vorzunehmen, dann den bypass aus und via 
MPU Slave Registern die Kommunikation automatisch ablaufen zu lassen.

Gruß

von Marek W. (robotrovsky)


Lesenswert?

Hi Lukas!

Ja, das mit dem Clockstretching habe ich auch gelesen. Ist ja auch nicht 
nötig, die clock einzusparen und werde ich dann auch gar nicht erst 
probieren. Ich spendier einfach jedem Bus seinen eigenen Takt.

Der Tip mit dem Magnetometer ist auch sehr gut! So was kann 
aufhalten/verwirren, wenn man es nicht weiss.

Bin ja mal gespannt, ob ich das so hinbekomme. Ich melde mich mal, wenn 
was läuft oder eben auch nicht ;-)

Besten Gruss!

von Martin S. (led_martin)


Lesenswert?

bit-banging ist bei I²C nicht ganz einfach, da jeder Slave die LOW-Zeit 
vom Clock verlängern kann, und darauf muß man reagieren. Deine Ports 
müssen auch Open-Drain sein, ob man da, beim Raspberry, 'nah' genug an 
den GPIOs dran ist, um das auch noch auf mehreren Pins gleichzeitig zu 
machen? Da ist SPI definitiv einfacher, da könnte man den Takt für alle 
Bussegmente gemeinsam erzeugen, und immer 8x SDO und 8x SDI auf einen 
Port, und diese Ports dann mit einem kompletten Byte beschreiben / 
lesen.

Mit freundlichen Grüßen - Martin

von Hamster (Gast)


Lesenswert?

Hallo Marco,
spannendes Projekt, ich versuch gerade, genau das gleiche zu 
realisieren. hab mir die Sensoren von Drotec aus frankreich bestellt, 
sind da etwas billger (sind noch nicht da).
Ich will das Projektr aber mit Funkmodulen realisieren, da das gleich 
mit Kabeln und analogen Sensoren bei mir schon läuft und die Kabel 
nerven.


Zur TWI(I2C)-Übertragung: Ich experimentiere gerade mit IMU3000 und 
ADXL345 (Vorläufer von MPU9250) und die TWI-Übertragung ist nicht 
besonders schnell. Ich hätte gerne 200 Hz Abtastrate. Bin nicht sicher, 
dass Du das mit einem Knoten (Raspberry), der alle Sensoren bedienen 
muss, schaffst. TWI ohne Interruptsteierung ist auch ziemlich blöd, weil 
der Prozessor ständig wartet. Du brauchtst also ein ganz speziell für 
diese Sensoren ausgetüfteltes TWI-Programm, das interruptgesteuert ist 
(Das istt so meine Erfahrung).Da wäre schnelles SPI besser.

Das Problem der Synchronisierung der Daten von den Körpersegmenten ist 
nicht trivial. Die Sensoren haben ihren eigenen Takt und der ist 
natürlich innerhalb weniger Sekunden nicht mehr synchron.

Ich bin auch noch nicht fertig mit meiner Lösung, das kann noch ein paar 
Wochen dauern, aber dann hab ich die Daten und dann würd ich Dich evt 
mal nach Kalman-Support fragen, das brauch ich nämlich kanns's aber 
nicht selber programmieren.

Gruß, Hamster

von Marek W. (robotrovsky)


Lesenswert?

Hallo Hamster!

Ich habe noch nichts bestellt, weil gerade pleite :-(
Hab aber auch die Drotecs gesehen und werde die bestellen.
Von dem verkabelten analog-Sensor Aufbau samt Auswertungssoftware würde 
ich ja gerne mal ein Video sehen. Gibts sowas?

Vielleicht wird ja ein schönes Gemeinschaftsprojekt und eventuell ein 
µC.net-Artikel draus. Würde mich freuen, wenn Du (und alle die das selbe 
vorhaben) auch weiterhin deine Fortschritte berichtest.

Im Grunde genommen ist es ja eh ne Kopie vom PrioVR:
http://priovr.com/

Aber bevor ich mir das kaufe, bau ich mir das selber, da weiss ich was 
ich habe und wie ich es ohne komische corporate-api programmiere.


Gruss
robotrovsky

von Marek W. (robotrovsky)


Angehängte Dateien:

Lesenswert?

Update: Also ich habe mittlerweile mein Zeug bestellt und gestern ist es 
angekommen. Ich hab jetzt den Cross-Compiler aufgesetzt und auch schon 
brauchbaren Code zur Ansteuerung über die /dev/i2c Linux Schnittstelle 
gefunden. Der MPU funktioniert auch am I2c ohne die Pull-Ups 
rauszulöten.



Die Software mit der es auf Anhieb ging habe ich von hier:

http://icube-avr.unistra.fr/en/index.php/I2C_communication_between_RPI_and_MPU9150

Ich denke ich werde jetzt probieren mit WiringPi, das Beispiel 
nachzuprogrammieren, so dass er nicht mehr auf /dev/i2c angewiesen ist, 
sondern man einfach 2 Pins angeben kann.



Meine C++ (g++ 4.9.3) Cross-Toolchain setzt sich übrigens aus diesen 
beiden zusammen:

1. Zum Kompilieren auf x86_64:
http://releases.linaro.org/14.11/components/toolchain/binaries/arm-none-eabi/gcc-linaro-4.9-2014.11-x86_64_arm-eabi.tar.xz

Bsp:
1
arm-none-eabi-g++ -std=c++14 -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -fno-short-enums -c -o hw14.o  hw14.cpp

2. Zum Linken funktioniert die Toolchain aus 1, leider nicht, da sie 
sich in der ABI der Systembibliotheken unterscheidet. Dafür habe ich 
dann den g++ aus den Raspberry-Tools genommen
https://github.com/raspberrypi/tools

Bsp:
1
gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-g++ hw14.o -o hw14
Denn so toll der RPI ist, ich will da nicht drauf programmieren.


Anbei noch ein kleiner Screenshot vom ersten angeschlossenen MPU :-) Das 
Paddle-Board kann ich absolut empfehlen, vor allem in Kombination mit 
nem USB-to-Serial Konsolenkabel. Dann braucht man gar keine andere 
Stromquelle mehr und sieht natürlich auch die Boot und Shutdown 
Messages. Hat sogar genug saft für den Wifi-Dongle.

Wie mache ich das mit dem Jumper auf dem Drotek-Board? Da sind 3 kleine 
silberne Lötstellen. Muss ich da die beiden rechten miteinander 
verlöten, damit er die alternative Adresse nimmt? Oder alle 3?

von Marek W. (robotrovsky)


Lesenswert?

Marco W. schrieb:

> Wie mache ich das mit dem Jumper auf dem Drotek-Board? Da sind 3 kleine
> silberne Lötstellen. Muss ich da die beiden rechten miteinander
> verlöten, damit er die alternative Adresse nimmt? Oder alle 3?

Es waren die ersten beiden. Die Droteks haben mit 0x69 Adresse 1 als 
Standard.

von robotrovsky (Gast)


Lesenswert?

Kleines Update:
Nachbestellte Sensoren habe ich schon hier liegen, denen muss ich aber 
noch die Stecker anlöten. Die Verkabelung hat auch ganz gut geklappt. 
Ich nehme 8 poliges Flachbandkabel und führe durch jedes Kabel zwei 
Busse, die Buchsen sind gecrimpt. In letzter Zeit bin ich jedoch leider 
nicht mehr wirklich dazu gekommen daran weiter zu arbeiten.

Ich habe aber heute mal den I2C bit banging bus fuer den rpi auf github 
hochgeladen. Vielleicht hilft es ja jemandem und sei es nur als 
Einstiegsbeispiel um es besser zu machen. Damit kann man 2 beliebige 
GPIO Pins als I2C Bus verwenden. Ist eventuell auch fuer andere Sachen 
interessant sich mehrere Busse anzulegen. Mit dem MPU 9250 von Drotek 
funktioniert es. Ich habe mittlerweile aber gemerkt, dass der Drotek MPU 
9250 in Wirklichkeit der MPU9150 mit angeloeteten SPI Pins ist. Deswegen 
hatte das Beispiel auch auf Anhieb funktioniert.

https://github.com/robotrovsky/rpi_i2c_bit_banging

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
Noch kein Account? Hier anmelden.