PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] MPU6050 Initialisieren mit dem Netduino



Robo-Hero
07.10.2012, 11:36
Hallo Zusammen,

seit längeren sitze ich schon an diesem Sensor. Mit dem Arduino funktioniert der Sensor mit der fertigen Code von https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050. Was mir jedoch zu schaffen macht, ist eine Lösung für Netduino zu schreiben.
Für die I2C Verbindung habe ich mir bereits eine Klasse zurecht geschrieben. Ursprünglich habe den Code von der Netduino Seite und habe den auf meine Bedürfnisse angepasst. Es funktioniert bereits auch schon mit dem BMA020 Sensor.

Die I2C Verbindung


public class I2C_Connector
{
private I2CDevice.Configuration _Config;
private I2CDevice _Device;

/// <summary>
/// Initialisiert die Klasse
/// Konfiguration wird angelegt und
/// die entsprechende Klasse I2CDevice wird initialisiert
/// </summary>
/// <param name="address">Adresse zur Hardware</param>
public I2C_Connector(byte address)
{
// Adresse und Taktfrequenz übergeben
_Config = new I2CDevice.Configuration(address, 400);
_Device = new I2CDevice(_Config);
}

public I2C_Connector(byte address, int clockRateKHz)
{
// Adresse und Taktfrequenz übergeben
_Config = new I2CDevice.Configuration(address, clockRateKHz);
_Device = new I2CDevice(_Config);
}

public bool IsConnected()
{
// Noch nicht fertig
return false;
}

/// <summary>
/// Sendet den Inhalt des Byte Array zur Hardware
/// </summary>
/// <param name="writeBuffer">Byte Array</param>
public int Write(byte[] writeBuffer)
{
try
{
// Byte Array übergeben für das ertellen einer Transaction
I2CDevice.I2CTransaction[] writeTransaction = new I2CDevice.I2CTransaction[]
{
I2CDevice.CreateWriteTransaction(writeBuffer)
};

// Sende die Daten an die Hardware. TimeOut bei 1 Sekunde
int written = this._Device.Execute(writeTransaction, 1000);


// Prüfe ob alle daten gesendet wurden, ansonsten Exception ausführen
if (written != writeBuffer.Length)
{
//throw new Exception("Es konnten keine Daten an das Modul gesendet werden.");
Debug.Print("Es konnten keine Daten an das Modul gesendet werden.");
}

return written;
}
catch(ArgumentException ex)
{
Debug.Print(ex.ToString());
}

return 0;
}

/// <summary>
/// Ruft mit den Adressen im Buffer die Werte ab
/// </summary>
/// <param name="readBuffer">Byte Array mit Adressen für den Abruf entsprechender Daten</param>
public byte[] Read(byte[] readBuffer)
{
// Erstelle ein Transaction zum Lesen mit übergabe des Byte Array
I2CDevice.I2CTransaction[] readTransaction = new I2CDevice.I2CTransaction[]
{
I2CDevice.CreateReadTransaction(readBuffer)
};

// Lese die Daten von der Hardware. TimeOut von einer Sekunde
int read = this._Device.Execute(readTransaction, 1000);

// Prüfe, ob die Daten gesendt wurden
if (read != readBuffer.Length)
{
//throw new Exception("Es konnte nicht vom Modul gelesen werden.");
Debug.Print("Es konnte nicht vom Modul gelesen werden.");
}

return readBuffer;
}
}


Schreiben (oder auch Senden genannt) geht, oder zumindest sieht das so aus.
Das die Verbindung nicht geht, sehe ich immer wenn ich die Methode "Read(byte[] readBuffer)" aufrufe.

Letzter Vorgang den ich versucht habe war folgendes:


I2C_Connector i2c = new I2C_Connector(0x68, 400);

byte[] ba = i2c.Read(new byte[] { MPU6050_R.PWR_MGMT_1 });


Aber egal was ich auch nehme, ich kann vom Sensor Modul nicht lesen.
Nach einem brauchbaren Code in C# und einem kürzeren Beispiel in C/C++ habe ich schon seit Tagen gesucht, aber nichts gefunden. Wäre allerdings nicht das erstmal, dass ich nach den Falschen Begriffen suche... :confused:

Was ich dazu bereits lese ist, die PDF zu dem Sensor. Leider ist das Englisch etwas komisch, jedoch das wesentliche fehlt, eine Beschreibung wie man den Sensor Initialisiert. Im Grunde stehen nur die Adressen und dessen Beschreibung vor.

Geht man nach dem Beispiel, dass bereits für den Arduino vorliegt, wird beim Initialisieren als erstes der Status des Moduls abgefragt (MPU6050_RA_PWR_MGMT_1 = 0x6B), was ich auch in meinem letzten Code Beispiel zeige. Danach wird erst die Konfiguration des Sensors vorgenommen.


Grüße von
Robo-Hero

Robo-Hero
10.10.2012, 19:22
Ein kleiner Nachtrag:
Kurz danach habe ich festgestellt, dass ich das mit dem Power Management falsch verstanden habe. Anders als bei dem BMA020 Sensor, ist es erforderlich beim Initialisieren das Power Management, Gyroskope und Beschleunigungssensor einzustellen. Dazu habe ich folgende Methode geschrieben:



public void Initialize()
{
// Power Management 1
// Hier wird der Temperatur Sensor nur abgestellt
_I2C.Write(new byte[] { MPU6050_R.PWR_MGMT_1, 0x08 }));


// FullScaleGyroRange
_I2C.Write(new byte[] { MPU6050_R.GYRO_CONFIG , 0x00 });


// FullScaleAccelRange
_I2C.Write(new byte[] { MPU6050_R.ACCEL_CONFIG, 0x00 });


// Power Management 1
// Aus dem Sleep Modus holen
ErrorStatus(_I2C.Write(new byte[] { MPU6050_R.PWR_MGMT_1, 0x50 }));
}


Allerdings habe ich wohl nicht nicht das richtige Setting für den Sensor herausgefunden. Entweder kommt nur "0" oder das Ergebnis ergibt keinen Sinn. Zuerst würde ich gerne konstant Daten erhalten, und vielleicht ergibt sich dann das andere.




Initialisiere den Beschleunigungs- und Gyrosensor MPU-6050
Status: OK
Status: OK
Status: OK
Status: OK
Verbindung testen:
Status: OK
-----------------------------------------------------------------------
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:255 Z:31612 Gyro: X: 12527 Y: 52991 Z: 26885
Acceleration: X: 10352 Y:20660 Z:47104 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:80 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 26624 Y:0 Z:0 Gyro: X: 0 Y: 255 Z: 31612
Acceleration: X: 4400 Y:61390 Z:65385 Gyro: X: 10352 Y: 20660 Z: 47104
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0
Acceleration: X: 0 Y:0 Z:0 Gyro: X: 0 Y: 0 Z: 0

--- // ---


An der Stelle weiss ich nun nicht weiter. Ich hatte schon an den I2C Takt gedacht, aber das machte keinen Unterschied.
Vielleicht hat hier jemand einen Ansatz, woran das liegt.


Grüße von
Robo-Hero

Robo-Hero
05.02.2013, 12:02
Abschluss.

Inzwischen habe ich mein Anliegen gelöst und das lesen der Sensor Daten funktioniert nun einwandfrei. Mein Fehler lag nicht beim initialisieren sondern vor dem lese Vorgang (Zuvor nicht gepostet).

In meiner Methode zum Einlesen der Daten, habe ich nur den Lesevorgang, jedoch vorher kein Adress byte für die erste Achse gesendet.


public SensorData GetSensorData()
{
byte[] registerList = new byte[14];
registerList[0] = MPU6050_Registers.ACCEL_XOUT_H;
registerList[1] = MPU6050_Registers.ACCEL_XOUT_L;
registerList[2] = MPU6050_Registers.ACCEL_YOUT_H;
registerList[3] = MPU6050_Registers.ACCEL_YOUT_L;
registerList[4] = MPU6050_Registers.ACCEL_ZOUT_H;
registerList[5] = MPU6050_Registers.ACCEL_ZOUT_L;
registerList[6] = MPU6050_Registers.TEMP_OUT_H;
registerList[7] = MPU6050_Registers.TEMP_OUT_L;
registerList[8] = MPU6050_Registers.GYRO_XOUT_H;
registerList[9] = MPU6050_Registers.GYRO_XOUT_L;
registerList[10] = MPU6050_Registers.GYRO_YOUT_H;
registerList[11] = MPU6050_Registers.GYRO_YOUT_L;
registerList[12] = MPU6050_Registers.GYRO_ZOUT_H;
registerList[13] = MPU6050_Registers.GYRO_ZOUT_L;
// Der entscheidene Schreibvorgang. Erst nachdem ich dies
// eingetragen habe, kamen die daten Konstant wie ich es erwarte.
_I2C.Write(new byte[] { MPU6050_Registers.ACCEL_XOUT_H });
_I2C.Read(registerList);
return new SensorData(registerList);
}


Vielleicht hilft das den einen oder anderen weiter, mit dem Sensor weiter zu arbeiten. ;)

Da ich auch einigermaßen die Doku rauf und Runter durchgelesen habe, dürfte ich sicherlich einige Fragen beantworten können.

Grüße von
Robo-Hero

PS: Hier ist der Link zu meinem Blogpost, über dem Sensor MPU6050 nud Netduino.
http://meineweltinmeinemkopf.blogspot.de/2013/01/mpu6050-sensor-auslesen-mit-dem-netduino.html