.. note::

    Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Gemeinschaft auf Facebook! Tauchen Sie tiefer ein in die Welt von Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten.

    **Warum beitreten?**

    - **Expertenunterstützung**: Lösen Sie Nachverkaufsprobleme und technische Herausforderungen mit Hilfe unserer Gemeinschaft und unseres Teams.
    - **Lernen & Teilen**: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu verbessern.
    - **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und exklusiven Einblicken.
    - **Spezialrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
    - **Festliche Aktionen und Gewinnspiele**: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

    👉 Sind Sie bereit, mit uns zu erkunden und zu erschaffen? Klicken Sie auf [|link_sf_facebook|] und treten Sie heute bei!

.. _2.2.9_py_pi5:

2.2.9 MPU6050-Modul
===========================

Einführung
---------------

Das MPU-6050 ist das weltweit erste und einzige 6-Achsen-Bewegungserfassungsgerät (3-Achsen-Gyroskop und 3-Achsen-Beschleunigungsmesser), das speziell für Smartphones, Tablets und tragbare Sensoren entwickelt wurde. Es erfüllt die Anforderungen an geringen Stromverbrauch, niedrige Kosten und hohe Leistung.

In diesem Experiment nutzen wir I2C, um die Werte des Dreiachsen-Beschleunigungsmessers und des Dreiachsen-Gyroskops des MPU6050 zu erfassen und auf dem Bildschirm anzuzeigen.

Benötigte Komponenten
------------------------------

Für dieses Projekt benötigen wir folgende Komponenten.

.. image:: ../python_pi5/img/2.2.9_mpu6050_list.png

Es ist definitiv praktisch, ein komplettes Set zu kaufen, hier ist der Link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Name	
        - ARTIKEL IN DIESEM SET
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Sie können diese auch einzeln über die untenstehenden Links kaufen.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - KOMPONENTENVORSTELLUNG
        - KAUF-LINK

    *   - :ref:`cpn_gpio_board`
        - |link_gpio_board_buy|
    *   - :ref:`cpn_breadboard`
        - |link_breadboard_buy|
    *   - :ref:`cpn_wires`
        - |link_wires_buy|
    *   - :ref:`cpn_mpu6050`
        - |link_mpu6050_buy|

Schaltplan
-----------------

Das MPU6050 kommuniziert über die I2C-Busschnittstelle mit dem Mikrocontroller. Die SDA1- und SCL1-Pins müssen mit den entsprechenden Pins verbunden werden.

.. image:: ../python_pi5/img/2.2.9_mpu6050_schematic.png


Experimentelle Verfahren
-------------------------------

**Schritt 1:** Baue die Schaltung.

.. image:: ../python_pi5/img/2.2.9_mpu6050_circuit.png


**Schritt 2:** Richte I2C ein (siehe Anhang :ref:`i2c_config`. Wenn I2C bereits eingerichtet ist, überspringen Sie diesen Schritt.)

**Schritt 3:** Gehe zum Ordner des Codes.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Schritt 4:** Führe die ausführbare Datei aus.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 2.2.9_mpu6050_zero.py

Mit der Ausführung des Codes werden der Ablenkwinkel der x- und y-Achse sowie die Beschleunigung und die Winkelgeschwindigkeit auf jeder Achse, die vom MPU6050 gelesen werden, nach der Berechnung auf dem Bildschirm angezeigt.

.. note::

    * Wenn der Fehler ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'`` auftritt, beziehen Sie sich bitte auf :ref:`i2c_config`, um I2C zu aktivieren.
    * Bei dem Fehler ``ModuleNotFoundError: No module named 'smbus2'`` führen Sie bitte ``sudo pip3 install smbus2`` aus.
    * Erscheint der Fehler ``OSError: [Errno 121] Remote I/O error``, bedeutet dies, dass das Modul falsch verdrahtet ist oder das Modul defekt ist.


.. warning::

    Wenn die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` angezeigt wird, lesen Sie bitte :ref:`faq_soc`

**Code**

.. note::

    Sie können den untenstehenden Code **modifizieren/zurücksetzen/kopieren/ausführen/stoppen**. Bevor Sie das tun, müssen Sie jedoch zum Quellcodepfad wie ``raphael-kit/python-pi5`` wechseln. Nachdem Sie den Code modifiziert haben, können Sie ihn direkt ausführen, um den Effekt zu sehen.


.. raw:: html

    <run></run>

.. code-block:: python

   import smbus
   import math
   import time

   # Power management registers
   power_mgmt_1 = 0x6b
   power_mgmt_2 = 0x6c

   def read_byte(adr):
       return bus.read_byte_data(address, adr)

   def read_word(adr):
       high = bus.read_byte_data(address, adr)
       low = bus.read_byte_data(address, adr+1)
       val = (high << 8) + low
       return val

   def read_word_2c(adr):
       val = read_word(adr)
       if (val >= 0x8000):
           return -((65535 - val) + 1)
       else:
           return val

   def dist(a,b):
       return math.sqrt((a*a)+(b*b))

   def get_y_rotation(x,y,z):
       radians = math.atan2(x, dist(y,z))
       return -math.degrees(radians)

   def get_x_rotation(x,y,z):
       radians = math.atan2(y, dist(x,z))
       return math.degrees(radians)


   bus = smbus.SMBus(1) # or bus = smbus.SMBus(1) for Revision 2 boards
   address = 0x68       # This is the address value read via the i2cdetect command

   # Now wake the 6050 up as it starts in sleep mode
   bus.write_byte_data(address, power_mgmt_1, 0)

   while True:
       time.sleep(0.1)
       gyro_xout = read_word_2c(0x43)
       gyro_yout = read_word_2c(0x45)
       gyro_zout = read_word_2c(0x47)

       print ("gyro_xout : ", gyro_xout, " scaled: ", (gyro_xout / 131))
       print ("gyro_yout : ", gyro_yout, " scaled: ", (gyro_yout / 131))
       print ("gyro_zout : ", gyro_zout, " scaled: ", (gyro_zout / 131))

       accel_xout = read_word_2c(0x3b)
       accel_yout = read_word_2c(0x3d)
       accel_zout = read_word_2c(0x3f)

       accel_xout_scaled = accel_xout / 16384.0
       accel_yout_scaled = accel_yout / 16384.0
       accel_zout_scaled = accel_zout / 16384.0

       print ("accel_xout: ", accel_xout, " scaled: ", accel_xout_scaled)
       print ("accel_yout: ", accel_yout, " scaled: ", accel_yout_scaled)
       print ("accel_zout: ", accel_zout, " scaled: ", accel_zout_scaled)

       print ("x rotation: " , get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))
       print ("y rotation: " , get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))

       time.sleep(1)


**Code-Erklärung**

#. Liest Sensordaten, die vom MPU6050 gesendet werden.

   .. code-block:: python

       def read_word(adr):
           high = bus.read_byte_data(address, adr)
           low = bus.read_byte_data(address, adr+1)
           val = (high << 8) + low
           return val

       def read_word_2c(adr):
           val = read_word(adr)
           if (val >= 0x8000):
               return -((65535 - val) + 1)
           else:
               return val

#. Berechnet den Ablenkwinkel der y-Achse.

   .. code-block:: python

       def get_y_rotation(x,y,z):
           radians = math.atan2(x, dist(y,z))
           return -math.degrees(radians)

#. Berechnet den Ablenkwinkel der x-Achse.

   .. code-block:: python

       def get_x_rotation(x,y,z):
           radians = math.atan2(y, dist(x,z))
           return math.degrees(radians)

#. Liest die Werte der x-, y- und z-Achse des Gyroskopsensors, wandelt die Daten in Winkelgeschwindigkeitswerte um und gibt sie dann aus.

   .. code-block:: python

       gyro_xout = read_word_2c(0x43)
       gyro_yout = read_word_2c(0x45)
       gyro_zout = read_word_2c(0x47)

       print ("gyro_xout : ", gyro_xout, " scaled: ", (gyro_xout / 131))
       print ("gyro_yout : ", gyro_yout, " scaled: ", (gyro_yout / 131))
       print ("gyro_zout : ", gyro_zout, " scaled: ", (gyro_zout / 131))

#. Liest die Werte der x-, y- und z-Achse des Beschleunigungssensors, wandelt die Daten in Beschleunigungswerte (Gravitationseinheit) um und gibt sie dann aus.

   .. code-block:: python

       accel_xout = read_word_2c(0x3b)
       accel_yout = read_word_2c(0x3d)
       accel_zout = read_word_2c(0x3f)

       accel_xout_scaled = accel_xout / 16384.0
       accel_yout_scaled = accel_yout / 16384.0
       accel_zout_scaled = accel_zout / 16384.0

       print ("accel_xout: ", accel_xout, " scaled: ", accel_xout_scaled)
       print ("accel_yout: ", accel_yout, " scaled: ", accel_yout_scaled)
       print ("accel_zout: ", accel_zout, " scaled: ", accel_zout_scaled)

#. Gibt die Ablenkwinkel der x- und y-Achse aus.

   .. code-block:: python

       print ("x rotation: " , get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))
       print ("y rotation: " , get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled))




