Seite 1 von 1

Beschleunigungen messen mit Mikrocontrollern (Facharbeit)

Verfasst: Sa 27. Jun 2015, 17:20
von Lukas1818
Mit wenig Aufwand kann man mit Hilfe des 3-Achsen-Beschleunigungssensor MPU6050 Beschleunigungen messen. Mit diesem Thema habe ich mich in meiner Facharbeit beschäftigt (siehe Anhang).

Der MPU6050 kommuniziert über I2C mit dem Attiny (Eine Erklärung zu I2C ist ebenfalls in der Facharbeit enthalten).
Die I2C Adresse des Sensor ist "D0". Am Anfang muss man diesen jedoch zuerst aus dem Standbymodus holen. Dazu wird das Register "6B" des Beschleunigungssensor mit dem Wert 0 beschrieben. Dannach kann man die Beschleunigungen aus den entsprechenden Registern auslesen:
xh = 3B
xl = 3C
yh = 3D
yl = 3E
zh = 3F
zl = 40

"x", "y", "z" steht hier für die drei verschiedenen Richtungen, "h" und "l" steht für High bzw. Low Byte (Eine Erklärung zu High und Low Byte ist ebenfalls in der Facharbeit enthalten).
Der ermittelte Wert entspricht aber noch nicht der Beschleunigung in m/s^2. Laut dem Manual entspricht nämlich der Wert 16384 ( =2^14 ) standartgemäß 1g (16384 LSB/g (LSB = Least Significant Bit)). Folglich muss man um die Beschleunigung pro Bit zu ermitteln 9,81 durch 16384 dividieren. Das Ergebnis ist dann gleich 0,00059875. Dementsprechend muss der ermittelte Wert erst mit 0,00059875 multipliziert werden um die Beschleunigung in m/s^2 zu erhalten.

Um den Mikrocontroller frei, ohne Kabel bewegen zu können, entschloss ich mich die Daten über Bluetooth zu übertragen. Dazu verwendete ich das Bluetooth-Modul HC-05 RS232, welches über die Serielle Schnittstelle angeschlossen wird und folglich wie das PC-Terminal mit den Befehlen "print" und "input" angesteuert werden kann. Bei der Suche nach Bluetooth-Geräten wird das Modul als "HC-06" angezeigt. Das Passwort für das Pairing lautet standartgemäß "1234". (https://www.forum.g-heinrichs.de/viewto ... ?f=12&t=57)

Das fertige Programm für die X-Achse sieht dann so aus:

Code: Alles auswählen

$regfile = "attiny2313.dat"
$crystal = 4000000
$baud = 9600

Config Scl = Portb.7
Config Sda = Portb.5


'**********************************************************
'******************* Deklarationen ************************

Declare Sub Writei2c(byval Register As Byte , Byval Wert As Byte)
Declare Function Readi2c(byval Register As Byte)as Byte


Dim Xh As Byte
Dim Xl As Byte
Dim Tempi As Integer
Dim Tempsi As Single

Const Adresse = &HD0
Const Adresse2 = &HD1
Const Resleep = &H6B
Const Rexh = &H3B
Const Rexl = &H3C

'****************** Initialisierung ***********************

Ddrb = &B11111111
Ddrd = &B01110000
Portd = &B10001111

Waitms 3000


'**********************************************************
'******************** Hauptprogramm ***********************


  Call Writei2c(resleep , 0)
  Do
    Xh = Readi2c(rexh)
    Xl = Readi2c(rexl)
    Tempi = 256 * Xh
    Tempi = Tempi + Xl
    Tempsi = Tempi * 0.00059875
    Print Tempsi ; "m/s2"
    Waitms 50
  Loop



'**********************************************************
'******************* Unterprogramme ***********************

  Sub Writei2c(byval Register As Byte , Byval Wert As Byte)
    I2cstart
    I2cwbyte Adresse
    If Err = 0 Then
       I2cwbyte Register
       I2cwbyte Wert
     Else
       Print ; Wert ; "-" ; Register
    End If
    I2cstop
  End Sub


  Function Readi2c(byval Register As Byte) As Byte
    I2cstart
    I2cwbyte Adresse
    If Err = 0 Then
       I2cwbyte Register
       I2cstart
       I2cwbyte Adresse2
       I2crbyte Readi2c , Nack
     Else
        Print "E" ; Register
    End If
    I2cstop
  End Function
Natürlich kann man auch alle drei Achsen auslesen. Jedoch ist das Programm zu groß für den Speicher des Microkontrollers:

Code: Alles auswählen

$regfile = "attiny2313.dat"
$crystal = 4000000
$baud = 9600

Config Scl = Portb.7
Config Sda = Portb.5


'**********************************************************
'******************* Deklarationen ************************

Declare Sub Writei2c(byval Register As Byte , Byval Wert As Byte)
Declare Sub Beschleunigung_lesen(byval Reh As Byte , Byval Rel As Byte)
Declare Function Readi2c(byval Register As Byte)as Byte



Const Adresse = &HD0
Const Adresse2 = &HD1
Const Resleep = &H6B
Const Rexh = &H3B
Const Rexl = &H3C
Const Reyh = &H3D
Const Reyl = &H3E
Const Rezh = &H3F
Const Rezl = &H40

'****************** Initialisierung ***********************

Ddrb = &B11111111
Ddrd = &B01110000
Portd = &B10001111

Waitms 3000


'**********************************************************
'******************** Hauptprogramm ***********************


  Call Writei2c(resleep , 0)
  Do
    Call Beschleunigung_lesen(rexh , Rexl)
    Call Beschleunigung_lesen(reyh , Reyl)
    Call Beschleunigung_lesen(rezh , Rezl)
    Print ""
    Waitms 50
  Loop



'**********************************************************
'******************* Unterprogramme ***********************

  Sub Writei2c(byval Register As Byte , Byval Wert As Byte)
    I2cstart
    I2cwbyte Adresse
    If Err = 0 Then
       I2cwbyte Register
       I2cwbyte Wert
     Else
       Print ; Wert ; "-" ; Register
    End If
    I2cstop
  End Sub


  Function Readi2c(byval Register As Byte) As Byte
    I2cstart
    I2cwbyte Adresse
    If Err = 0 Then
       I2cwbyte Register
       I2cstart
       I2cwbyte Adresse2
       I2crbyte Readi2c , Nack
     Else
        Print "E" ; Register
    End If
    I2cstop
  End Function


  Sub Beschleunigung_lesen(reh As Bythe , Rel As Byte)
  Dim H As Byte
  Dim L As Byte
  Dim Tempi As Integer
  Dim Tempsi As Single
    H = Readi2c(reh)
    L = Readi2c(rel)
    Tempi = 256 * H
    Tempi = Tempi + L
    Tempsi = Tempi * 0.00059875
    Print Tempsi ; "m/s2" ; ";";
  End Sub