MPU-6050 MEMS 6-Achs-Sensor

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • MPU-6050 MEMS 6-Achs-Sensor

      Der MPU-6050 ist ein Sensor, der in 3 Achsen Beschleunigungen und Drehraten messen kann.
      Die Kommunikation erfolgt über die I2C/TWI Schnittstelle.
      Hier habe ich ein kleines Beispiel für den ersten Einstieg und Messung der Beschleunigung.
      Das Programm konfiguriert den Sensor für die Inbetriebnahme, also Wahl der Taktquelle und Ausschalten des Sleep-Mode.
      Die 3 Achsen werden per I2C ausgelesen und als Bandanzeige an PortA ausgegeben.

      P.S.: Den Sensor gibt es übrigens für ca. 1,50 Euro beim freundlichen Ebay-Chinesen.

      BASCOM Source Code

      1. 'Demo MEMS-Sensor MPU-6050 Beschleunigung auslesen
      2. 'Created with Bascom-AVR 2079 Michael Kinz 01/2017
      3. $regfile = "m32def.dat"
      4. $crystal = 8000000
      5. $hwstack = 32
      6. $swstack = 32
      7. $framesize = 24
      8. '-------- Init I2C --------
      9. $lib "I2C_TWI.LBX" 'Hardware I2C
      10. Config Scl = Portc.0
      11. Config Sda = Portc.1
      12. I2cinit
      13. Const W_addr = &HD0 'I2C Adresse MPU-6050
      14. Const R_addr = &HD1
      15. '-------- Init I/O ---------
      16. Ddra = 255 'Ausgang für Bandanzeige
      17. '--------- Init Variablen ------------
      18. Dim Register_adresse As Byte
      19. Dim Register(6) As Byte
      20. Dim Acc_x As Integer At Register(1) Overlay
      21. Dim Acc_y As Integer At Register(3) Overlay
      22. Dim Acc_z As Integer At Register(5) Overlay
      23. Dim Z As Byte 'Hilfsvariable für Forschleife
      24. Dim Temp As Integer 'Hilfsvariable zum Rechnen
      25. '---------- Init Sensor ---------
      26. Register_adresse = &H68 'Signalpath Reset
      27. I2cstart
      28. I2cwbyte W_addr
      29. I2cwbyte Register_adresse
      30. I2cwbyte &H07 'Reset Gyro + Acc + Temp
      31. I2cstop
      32. Waitms 10
      33. Register_adresse = &H6B 'Power Management Register
      34. I2cstart
      35. I2cwbyte W_addr
      36. I2cwbyte Register_adresse
      37. I2cwbyte &H01 'Sleep = 0, Clocksource X-Gyro
      38. I2cstop
      39. Waitms 10
      40. Do
      41. I2cstart
      42. I2cwbyte W_addr 'Adresse I2C schreiben
      43. Register_adresse = &H3B 'Registerbeginn Acceleration Daten
      44. I2cwbyte Register_adresse
      45. I2cstart
      46. I2cwbyte R_addr 'Adresse I2C lesen
      47. For Z = 1 To 6
      48. I2crbyte Register(z) , Ack
      49. Next
      50. I2crbyte Register(6) , Nack
      51. I2cstop
      52. Swap Acc_x 'die Register sind MSB first, AVR aber LSB first
      53. Swap Acc_y
      54. Swap Acc_z
      55. 'Ausgabe als Bandanzeige auf 8 LEDs an Port A
      56. Temp = Acc_y / 4096 'Reduzieren der Auflösung
      57. Select Case Temp
      58. Case 0 : Porta = &B00000000
      59. Case -1 : Porta = &B00010000
      60. Case -2 : Porta = &B00110000
      61. Case -3 : Porta = &B01110000
      62. Case Is < -3 : Porta = &B11110000
      63. Case 1 : Porta = &B00001000
      64. Case 2 : Porta = &B00001100
      65. Case 3 : Porta = &B00001110
      66. Case Is >= 4 : Porta = &B00001111
      67. End Select
      68. Loop
      69. End
      Display All

      MCU-6050.jpg

      The post was edited 2 times, last by Michael: Schreibfehler korrigiert ().

    • Riedleweg wrote:

      Hab so eine Platine seit Monaten im Keller liegen, jetzt endlich ein Grund das Teil mal aus der Versenkung zu holen.
      Ja, so ähnlich war das auch bei mir, jetzt über die Feiertage hab ich ein paar hinausgeschobene Hobby-Themen abgearbeitet ;)

      Riedleweg wrote:

      War mal gedacht als "Antidrift" im Modellauto
      Das ist interessant, wenn es soweit ist, dann teil uns das bitte mit.
      Ich bin immer an solchen Anwendungen und Lösungen interessiert.
      Ich stelle mir eher eine Art blinde Odomertie vor. Also eine ungefähre Ortsbestimmung durch die Sensordaten. Ein Fahrzeug soll sich durch einen Raum bewegen und kurz vor der Wand langsamer werden, damit der Stoss nicht zu hefig wird. Andersherum beschreibt es vielleicht besser: Das Fahrzeug soll auf freiem Feld schnell fahren können ;)

      Hier hab ich das Programm von oben nochmal erweitert, es liest jetzt auch die Temperatur- und die Gyrodaten aus und verarbeitet die Temperatur korrekt zu Grad Celsius.

      Gruß, Michael

      BASCOM Source Code

      1. 'Demo MEMS-Sensor MPU-6050
      2. 'Beschleunigungen, Temperatur und Drehraten (Gyro) auslesen
      3. 'Created with Bascom-AVR 2079 Michael Kinz 01/2017
      4. $regfile = "m32def.dat"
      5. $crystal = 8000000
      6. $hwstack = 32
      7. $swstack = 32
      8. $framesize = 24
      9. '-------- Init I2C --------
      10. $lib "I2C_TWI.LBX" 'Hardware I2C
      11. Config Scl = Portc.0
      12. Config Sda = Portc.1
      13. I2cinit
      14. Const W_addr = &HD0 'I2C Adresse MPU-6050
      15. Const R_addr = &HD1
      16. '-------- Init I/O ---------
      17. Ddra = 255 'Ausgang für Bandanzeige
      18. '--------- Init Variablen ------------
      19. Dim Register_adresse As Byte
      20. Dim Register(14) As Byte
      21. Dim Acc_x As Integer At Register(1) Overlay
      22. Dim Acc_y As Integer At Register(3) Overlay
      23. Dim Acc_z As Integer At Register(5) Overlay
      24. Dim Temp_raw As Integer At Register(7) Overlay
      25. Dim Gyro_x As Integer At Register(9) Overlay
      26. Dim Gyro_y As Integer At Register(11) Overlay
      27. Dim Gyro_z As Integer At Register(13) Overlay
      28. Dim Temperatur As Single
      29. Dim Z As Byte 'Hilfsvariable für Forschleife
      30. Dim Temp As Integer 'Hilfsvariable zum Rechnen
      31. '---------- Init Sensor ---------
      32. Register_adresse = &H68 'Signalpath Reset
      33. I2cstart
      34. I2cwbyte W_addr
      35. I2cwbyte Register_adresse
      36. I2cwbyte &H07 'Reset Gyro + Acc + Temp
      37. I2cstop
      38. Waitms 10
      39. Register_adresse = &H6B 'Power Management Register
      40. I2cstart
      41. I2cwbyte W_addr
      42. I2cwbyte Register_adresse
      43. I2cwbyte &H01 'Sleep = 0, Clocksource X-Gyro
      44. I2cstop
      45. Waitms 10
      46. Do
      47. I2cstart
      48. I2cwbyte W_addr 'Adresse I2C schreiben
      49. Register_adresse = &H3B 'Registerbeginn Acceleration Daten
      50. I2cwbyte Register_adresse
      51. I2cstart
      52. I2cwbyte R_addr 'Adresse I2C lesen
      53. For Z = 1 To 13
      54. I2crbyte Register(z) , Ack
      55. Next
      56. I2crbyte Register(14) , Nack
      57. I2cstop
      58. 'die Register sind MSB first, AVR aber LSB first
      59. Swap Acc_x
      60. Swap Acc_y
      61. Swap Acc_z
      62. Swap Temp_raw
      63. Swap Gyro_x
      64. Swap Gyro_y
      65. Swap Gyro_z
      66. 'Ausgabe als Bandanzeige auf 8 LEDs an Port A
      67. Temp = Gyro_x / 4096 'Reduzieren der Auflösung
      68. Select Case Temp
      69. Case 0 : Porta = &B00000000
      70. Case -1 : Porta = &B00010000
      71. Case -2 : Porta = &B00110000
      72. Case -3 : Porta = &B01110000
      73. Case Is < -3 : Porta = &B11110000
      74. Case 1 : Porta = &B00001000
      75. Case 2 : Porta = &B00001100
      76. Case 3 : Porta = &B00001110
      77. Case Is >= 4 : Porta = &B00001111
      78. End Select
      79. 'Temperatur Auswertung
      80. Temperatur = Temp_raw / 340
      81. Temperatur = Temperatur + 35.53
      82. ' Print Fusing(temperatur , "#.##") + " Grad C "
      83. Loop
      84. End
      Display All
    • Mit den Teilen beschäftige ich mich seit Monaten auch immermal wieder. Das Initialisieren des Sensors und Auslesen der Wert klappt. DieFrage ist was macht man jetzt mit den 6 Werten (Acce + Gyro).
      Ziel meinerseits wäre eine Neigungssensor, quasi in der Art Libelle einer Wasserwaage (in zwei Richtungen).

      Ausgangssituation wäre, dass der Sensor beliebig im Raum orientiert ist. Man müsst also erst eine Kalibrierung durchführen, bei der die Lage im Raum ermittelt wird. Dann soll bei einer Winkelabweichung von z.B. 5°nach links und rechts sowie z.B. 10° nach vorn und hinten ein Alarm ausgelöst werden. Hat hier jemand einen für mich verständlichen einen Ansatzpunkt. Meine höhere Mathematik ist schon verdammt lang her ;)
    • Michael wrote:

      Der MPU-6050 ist ein Sensor, der in 3 Achsen Beschleunigungen und Drehraten messen kann.
      Die Kommunikation erfolgt über die I2C/TWI Schnittstelle.
      Gibt's da nicht noch einen, der zusätzlich noch 3-Achs-Kompassfunktion hat?
      Wäre vielleicht nützlich für:

      Michael wrote:

      Ich stelle mir eher eine Art blinde Odomertie vor. Also eine ungefähre Ortsbestimmung durch die Sensordaten. Ein Fahrzeug soll sich durch einen Raum bewegen und kurz vor der Wand langsamer werden, damit der Stoss nicht zu hefig wird. Andersherum beschreibt es vielleicht besser: Das Fahrzeug soll auf freiem Feld schnell fahren können
      Viele Grüße
      Mathias
      Heisenberg bei einer Radarkontrolle:
      Polizist: "Wissen Sie, wie schnell Sie waren?"
      Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"

    • rakohr wrote:

      soll bei einer Winkelabweichung von z.B. 5°nach links und rechts sowie z.B. 10° nach vorn und hinten ein Alarm ausgelöst werden. Hat hier jemand einen für mich verständlichen einen Ansatzpunkt. Meine höhere Mathematik ist schon verdammt lang her
      Der MPU 6050 hat eine eingebaute Motion-Detect Funktion ;)
      Und ich sehe gerade, der MPU9150 hat sogar eine Motion Tracking Funktion, das wollte ich ja ;)

      mac5150 wrote:

      Gibt's da nicht noch einen, der zusätzlich noch 3-Achs-Kompassfunktion hat?
      Der MPU6050 hat eine I2C Masterfunktion, mit der man an XDA und XCL (auxiliary interface) einen I2C Slave (z.B. Compass) anschließen kann. Der HMC5883L wäre ein Kandidat dafür.
      Allerdings gibt es das zusammen auch als MPU 9150 beim freundlichen Chinesen ab ungefähr $7,50
    • Michael wrote:

      Allerdings gibt es das zusammen auch als MPU 9150 beim freundlichen Chinesen ab ungefähr $7,50
      Uuups - teuer!
      Dann lieber einen weiteren I2C-Slave: Kompass und eventuell Ultraschall-Detektor?
      Kein Hindernis -> Full Speed a_38_b45e201d

      Viele Grüße
      Mathias

      Edit: Habe zwar eine neue Brille aber den Preis als 57,50 gelesen.
      Heisenberg bei einer Radarkontrolle:
      Polizist: "Wissen Sie, wie schnell Sie waren?"
      Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"

    • Heißer Tipp: Es gibt massenhaft ältere Controller für Multicopter, die haben sowohl die Gyro's, die Beschleunigungssensoren und auch mit Braometer + Kompass. Die Kosten zusammen mit einem 328p meist unter 10 Euro. Dafür bekommt man sonst nicht mal die Sensoren...
      Und z.B. die KK-Mini Boards mit ATMega644a, 6050 Sensor, LCD Display gibts regelmäßig beim Hobbykönig für 9,99

      Und sicher wollen viele "Aufrüster" ihre alten Boards loswerden.

      Nachtrag: Crizs MWC MultiWii SE V2.6 mit 6050, 3-Achs Kompass, Pegelwandler, BMP180 für 19,90$ (knapp 18,50)
      Aus datenschutzrechtlichen Gründen befindet sich die Kontaktdaten auf der Rückseite dieses Beitrages.

      The post was edited 1 time, last by monkye: Update ().

    • Hallo,
      erstmal ein super Forum hier!
      Danke an alle die "uns" laien helfen etwas in gang zu bekommen.

      Ich habe versucht dieses Teil hier (sieht Baugleich aus): Link

      mit eurem Code zum laufen zu bringen. Leider ohne Erfolg.
      Angeschlossen an einen ATmega32 erreiche ich nur ein konstantes wechsel Blinken der LED`s

      Keine Ahnung was es sein kann. Zwei fragen hätte ich mal.

      Müssen die i2c Anschlüsse vom Atmega mit 10k an 5v angeschlossen sein? (PullUp)
      Stimmen die i2c Adressen für das Modul ?

      Am Code hatte ich nur den $crystal = 16000000 gesetzt... sonst alles so gelassen.
      Schaltungstech. habe ich nur die vier Anschlüsse vom Modul angeschlossen Also 5V, gnd, scl und sda

      Vielen Dank für eure Hilfe.

      Jörg
    • QEK-75 wrote:

      Müssen die i2c Anschlüsse vom Atmega mit 10k an 5v angeschlossen sein? (PullUp)
      Ja die müssen angeschlossen sein, aber pro Strang nur einmal.

      QEK-75 wrote:

      Stimmen die i2c Adressen für das Modul ?
      Dafür gibt es auch I2C-Scanner mit denen du die Adresse herausfinden kannst.

      QEK-75 wrote:

      Am Code hatte ich nur den $crystal = 16000000 gesetzt... sonst alles so gelassen.
      Hast du dazu auch die Fuse gesetzt? Denn nur den Wert bei $crystal zu ändern reicht nicht.
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • Vielen Dank für die super schnelle Antwort!

      Leider sind alle Versuche erfolglos geblieben (außer dass die LEDs nicht mehr blinken)

      Die Widerstände habe ich eingelötet.

      FUSE hatte ich gesetzt.

      Den i2c Scanner habe ich angepasst und gleich ausprobiert. (tolles Programm !!!)
      Er zeigt mir ( bei Modul Anschluss AD0 gegen Masse ) die Adresse hD0 an

      und ( bei Modul Anschluss AD0 gegen 5V ) die Adresse hD2 an.


      Also alles ok mit meinen i2c bus nehme ich mal an ?


      Die hD0 Adresse war ja eingestellt, habe es aber auch mal mit hD2 versucht leider erfolglos.


      Dann habe ich noch den Atmega auf die internen 8 MHz gestellt und das Programm damit getestet leider auch erfolglos.


      Um mal zu sehen ob was vom Modul rauskommt habe ich die variabel acc_x - z auf dem LCD ausgegeben alle Werte stehen bei 15163 (Auch keine Veränderung bei Bewegung)



      Scheinbar klappt das auslesen des Moduls irgendwie nicht?

      Hat einer noch eine Idee? Ich habe zuletzt die 2 Code variante von Michael verwendet


      Jörg
    • Wenn das Modul auf den I2C Scanner antwortet, und dann auch noch mit der richtigen Adresse, dann funktioniert I2C eigentlich.
      Ich kann mir jetzt ein paar Gründe vorstellen, warum es nicht so geht wie gewünscht.

      -das Modul könnte kaputt bzw. Fake sein
      -das Layout ist schlecht, dass die Adresse noch beantwortet wird, aber der Rest untergeht.
      -die Stromversorgung hat ein Problem, für die Zeit der Adresse reicht es noch, aber dann nicht mehr
      -die Spannung liegt ausserhalb der erlaubten Werte (AD0 an 5V geht gar nicht, Vlogic darf nicht über Vcc (3,3V) sein)

      Ich würde jetzt erstmal das System auf 3,3V bringen, vielleicht hast du einfach Glück.
      Ich habe den Code oben ja mit 8MHz geschrieben, weil der Atmega32 nur so viel schafft bei 3,3V
      Ein Arduino Nano (Atmega328p) schafft da 16MHz.
    • Michael wrote:

      -die Spannung liegt ausserhalb der erlaubten Werte (AD0 an 5V geht gar nicht, Vlogic darf nicht über Vcc (3,3V) sein)
      ganz so empfindlich ist er chip wohl nicht
      mpu6050.PNG
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich bedanke mich erstmal!

      Werde mir erstmal noch ein zweites Modul bestellen, vielleicht habe ich es bei meinem probieren mit 5V auf AD0 beschädigt.
      Hatte jetzt nochmal schnell mit alternativer Spannungsversorgung (Akku 3,3 V bei 8mhz) probiert. Aber immer dasselbe.

      Jörg
    • Hast du die gleichen pins wie Michael verwendet oder andere? Der mega32 hat ja die jtag-Schnittstelle, die pins vom portc 'unbrauchbar' macht. Jtag kann man aber in den fuses abschalten.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo nochmal,
      habe das Modul mal an einen 328p angeschlossen. Funktioniert leider genauso wenig.





      Da ich meinen Aufbau aber testen wollte, insbesondere den i2c Bus habe ich den i2c Scanner auf eine binäre Ausgabe angepasst. Die ausgegebene Adresse ist die gleiche wie beim Scanner mit LCD Ausgabe. Der Bus funktioniert auf alle Fälle, scheint also wirklich ein defektes Modul zu sein.
      Hier mein Code für den Scanner mit Binärausgabe:



      Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000
      3. $hwstack = 40
      4. $swstack = 32
      5. $framesize = 60
      6. DdrD = 255
      7. Config Sda = Portc.4
      8. Config Scl = Portc.5
      9. I2cinit
      10. Dim Slaveadresse As Byte
      11. Dim Adresse As byte
      12. Do
      13. Wait 2
      14. For Slaveadresse = 0 To 254 Step 2
      15. I2cstart
      16. I2cwbyte Slaveadresse
      17. If Err = 0 Then
      18. Adresse = not Slaveadresse 'damit LED aus gleich 0 ist
      19. PortD = Adresse
      20. Wait 2
      21. End If
      22. I2cstop
      23. Next
      24. Wait 2
      25. Loop
      26. End
      Display All
      Na dann warte ich mal auf ein neues Modul und berichte dann wieder.

      Jörg