Hallo zusammen,
bei meinem Projekt 4 DC Motoren gleichmässig antreiben hab ich zwei Gyroskope (MPU6050) verbaut. Ich hab die auch schon mit einer eigenen Klasse grob in meine Steuerung eingebaut (Code folgt).
Ich hatte erst einmal die Möglichkeit die ganze Steuerung überhaupt zu testen und da hat sich der Arduino immer wieder "aufgehängt", ich bin mir sehr sicher, dass einer der Gyroskope den µC blockiert. Da ich da draußen im Funkloch Deutschland bin, hab ich da kein Internet und muss deswegen etwas "vorarbeiten".
Ich könnte zwar einfach die Gyroskope noch mal auskommentieren, aber morgen hätte ich ein paar Stunden Zeit was zu machen, da will ich dann die Gyroskope (zum nivilieren) auch mit einbauen, wenn noch Zeit übrig ist.
Bei meinen Tests daheim hab ich schon festgestellt, dass die Libary MPU6050 (https://github.com/ElectronicCats/mpu6050/) scheinbar als Standardeinstellung synchrone Kommunikation hat. I²C selber ist ja ein asynchroner Bus, also müsste sich das ja ändern lassen.
Da ich selber aber weder viel Ahnung von I²C, noch MPU6050 oder C++ hab, wollte ich hier um Hilfe fragen.
Ich hab mir die Lib (https://github.com/ElectronicCats/mpu6050/blob/master/src/MPU6050.cpp) schon durchgeschaut und hab mir zwei Zeilen rausgeschrieben:
- 834
MPU6050::setWaitForExternalSensorEnabled()
- 1404
MPU6050::setInterruptDrive()
Ich würde es jetzt mal blöd verstehen, dass ich mit ersterem deaktiviere, dass der Code blockiert wird, wenn auf eine Antwort gewartet wird und bei zweiteren wird bei einer Antwort ein Interrupt aktiviert...? Ja, Nein, Vielleicht? Ich hab keine Ahnung..
Meine Gyro-Klasse:
gyroskop.h
#pragma once
#include "Wire.h"
#include "MPU6050.h"
class Gyroskop
{
private:
// Members
MPU6050 _gyro;
uint8_t _address;
int16_t _ax, _ay, _az; // actuel Values Accel
int16_t _gx, _gy, _gz; // actuel Values Motion
int16_t _y_offset; // Offset of y accel for balance
int16_t _z_offset; // Offset of z accel for balance
static const int16_t _y_tolerance = 250; // Tolerance for y balance
static const int16_t _z_tolerance = 250; // Tolerance for z balance
static const byte _count_last_values = 50; // How many Values for average
int16_t _last_y[_count_last_values] = {0}; // last y Values
int16_t _last_z[_count_last_values] = {0}; // last z Values
byte _num_last_value = 0; // last posistion in array
int16_t _y_real; // real average y accel
int16_t _z_real; // real average z accel
int16_t _y; // y accel with offset
int16_t _z; // z accel with offset
public:
// Comands
Gyroskop(uint8_t address);
void begin();
void run();
// Setter
void setYOffset(int16_t offset);
void setZOffset(int16_t offset);
// Getter
int16_t getYValue();
int16_t getYRealValue();
bool getYOkay();
bool getYLeftUp();
int16_t getZRealValue();
int16_t getZValue();
bool getZOkay();
bool getFrontUp();
};
gyroskop.cpp
#include "gyroskop.h"
Gyroskop::Gyroskop(uint8_t address)
{
_address = address;
_gyro = MPU6050(address);
}
void Gyroskop::begin()
{
Wire.begin();
Serial.print("Initializing Gyroskop Sensor ");
Serial.print(_address);
Serial.println();
_gyro.initialize();
Serial.print("Testing device connection ");
Serial.print(_address);
Serial.println();
Serial.print(_gyro.testConnection() ? "Gyro connection successful " : "Gyro connection failed ");
Serial.print(_address);
Serial.println();
}
void Gyroskop::run()
{
_gyro.getMotion6(&_ax, &_ay, &_az, &_gx, &_gy, &_gz);
_last_y[_num_last_value] = _ay;
_last_z[_num_last_value] = _az;
_num_last_value = (_num_last_value < _count_last_values) ? (_num_last_value + 1) : 0;
long y_sum;
long z_sum;
int16_t y_min = 20000;
int16_t y_max;
int16_t z_min = 20000;
int16_t z_max;
byte counter_y;
byte counter_z;
for (byte i = 0; i < _count_last_values; i++)
{
if (_last_y[i] != 0)
{
y_sum += _last_y[i];
y_min = (y_min > _last_y[i]) ? _last_y[i] : y_min;
y_max = (y_max < _last_y[i]) ? _last_y[i] : y_max;
counter_y++;
}
if (_last_z[i] != 0)
{
z_sum += _last_z[i];
z_min = (z_min > _last_z[i]) ? _last_z[i] : z_min;
z_max = (z_max < _last_z[i]) ? _last_z[i] : z_max;
counter_z++;
}
}
_y_real = (y_sum - y_min - y_max)/(counter_y - 2);
_z_real = (z_sum - z_min - z_max)/(counter_z - 2);
_y = (_y_real - _y_offset);
_z = (_z_real - _z_offset);
}
void Gyroskop::setYOffset(int16_t offset)
{
_y_offset = offset;
}
void Gyroskop::setZOffset(int16_t offset)
{
_z_offset = offset;
}
int16_t Gyroskop::getYValue()
{
return _y;
}
int16_t Gyroskop::getYRealValue()
{
return _y_real;
}
bool Gyroskop::getYOkay()
{
bool return_ = false;
if ((_y < _y_tolerance)
&& (_y > _y_tolerance * -1))
{
return_ = true;
}
return return_;
}
bool Gyroskop::getYLeftUp()
{
bool return_ = false;
if (_y >= _y_tolerance)
{
return_ = true;
}
return return_;
}
int16_t Gyroskop::getZValue()
{
return _z;
}
int16_t Gyroskop::getZRealValue()
{
return _z_real;
}
bool Gyroskop::getZOkay()
{
bool return_ = false;
if ((_z < _z_tolerance)
&& (_z > _z_tolerance * -1))
{
return_ = true;
}
return return_;
}
bool Gyroskop::getFrontUp()
{
bool return_ = false;
if (_z >= _z_tolerance)
{
return_ = true;
}
return return_;
}
Kann mir jemand auf die Sprünge helfen, ob ich da in der richtigen Richtung oder komplett auf'm Holzweg bin..?
Bzw. wäre es für meinen "einfachen" Fall auch einfacher, wenn ich nicht die MPU6050 lib nutze, sondern nur selbst direkt die Sensoren ausles und des asynchron gestalte?
Vielen Dank und
liebe Grüße
Fipschen