Da ich die Neigung von meinem Auto feststellen und entsprechend auswerten will ("Der kippt! Halt an, Junge!") hab ich mir ein Gyro-Modul gekauft, genaugenommen drei Stück für nen 10er:
https://www.amazon.de/PEMENOL-3-Ach...ŽÕÑ&keywords=MPU-6050+Modul+3-Achsen-Gyroskop
das ganze wird über den I2C-Bus angeschlossen und läuft auf 3,3V. Ich spare mir daher den Schaltplan, es sind ja nur 4 Kabel:
Gyro: Arduino:
VCC > 3,3V
GND > GND
SCL > A5 (auf dem Nano)
SDA > A4 (auf dem Nano)
Bei einem normalen Arduino sind SCL und SDA extra als Pin vorhanden, beim Nano muss man A4 und A5 nehmen.
Tja, und nu? Kurz googlen und man findet z.B. diese Seite hier:
https://www.mschoeffler.de/2017/10/...mpu-6050-breakout-board-with-the-arduino-uno/
Der Herr Schoeffler hat sich da schon was fertiges ausgedacht, damit kann man also super arbeiten. Im Beispielcode gibt er alle Werte einfach auf der seriellen Schnittstelle aus.
Ich habe das mal auskommentiert und das Script erweitet, um zwei LEDs (an D5 und D6) entsprechend der Neigung des Y-Werts zu dimmen.
Der Sensor gibt einen Wert zwischen -16.000 und +16.000 aus, 0 ist dabei "waagerecht" - bei meinem Sensor ist der wert etwa bei 500. Entweder ist mein Haus schief oder das soll so, das schwankt sowieso alles etwas.
Für die LEDs berechne ich einfach per Dreisatz den Wert von 0-255 abhängig vom Wert des Sensors, jeweils abhängig von der Neigung nach links oder rechts.
Der Sketch dazu sieht dann so aus:
Das sieht dann im Video so aus:
Das kann man jetzt weiterspinnen und z.B. eine Warn-LED ansteigend leuchten und am Ende wild blinken lassen oder die Blinker anschalten oder auch ein Ton-Signal ausgeben.
Wichtig ist natürlich, den Kipp-Wert des Fahrzeugs zu ermitteln und die Schwellwerte entsprechend anzupassen.
Da der Gyro ja alle drei Achsen im Raum überwacht, kann man also neben Seitenneigung auch die Neigung in Fahrtrichtung prüfen, also wie steil der Hang sein darf.
Und für die Basher unter uns könnte man natürlich die Unterbodenbeleuchtung anschalten, wenn die Karre gerade im Backflip ist. So als Idee
Der Gyro muss übrigens nicht kalibriert werden. Egal in welcher Position ich den anschalte, da kommt in gleicher Lage immer der gleiche Wert raus.
https://www.amazon.de/PEMENOL-3-Ach...ŽÕÑ&keywords=MPU-6050+Modul+3-Achsen-Gyroskop
das ganze wird über den I2C-Bus angeschlossen und läuft auf 3,3V. Ich spare mir daher den Schaltplan, es sind ja nur 4 Kabel:
Gyro: Arduino:
VCC > 3,3V
GND > GND
SCL > A5 (auf dem Nano)
SDA > A4 (auf dem Nano)
Bei einem normalen Arduino sind SCL und SDA extra als Pin vorhanden, beim Nano muss man A4 und A5 nehmen.
Tja, und nu? Kurz googlen und man findet z.B. diese Seite hier:
https://www.mschoeffler.de/2017/10/...mpu-6050-breakout-board-with-the-arduino-uno/
Der Herr Schoeffler hat sich da schon was fertiges ausgedacht, damit kann man also super arbeiten. Im Beispielcode gibt er alle Werte einfach auf der seriellen Schnittstelle aus.
Ich habe das mal auskommentiert und das Script erweitet, um zwei LEDs (an D5 und D6) entsprechend der Neigung des Y-Werts zu dimmen.
Der Sensor gibt einen Wert zwischen -16.000 und +16.000 aus, 0 ist dabei "waagerecht" - bei meinem Sensor ist der wert etwa bei 500. Entweder ist mein Haus schief oder das soll so, das schwankt sowieso alles etwas.
Für die LEDs berechne ich einfach per Dreisatz den Wert von 0-255 abhängig vom Wert des Sensors, jeweils abhängig von der Neigung nach links oder rechts.
Der Sketch dazu sieht dann so aus:
(Der rote Krams ist das von mir)// (c) Michael Schoeffler 2017, http://www.mschoeffler.de
#include "Wire.h" // This library allows you to communicate with I2C devices.
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data
char tmp_str[7]; // temporary variable used in convert function
char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
sprintf(tmp_str, "%6d", i);
return tmp_str;
}
void setup() {
// Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}
void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
Wire.requestFrom(MPU_ADDR, 7 * 2, true); // request a total of 7*2=14 registers
// "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
accelerometer_x = Wire.read() << 8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
accelerometer_y = Wire.read() << 8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
accelerometer_z = Wire.read() << 8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
temperature = Wire.read() << 8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
gyro_x = Wire.read() << 8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
gyro_y = Wire.read() << 8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
gyro_z = Wire.read() << 8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
/*
// print out data
Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
// the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]
Serial.print(" | tmp = "); Serial.print(temperature/340.00+36.53);
Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
Serial.print(" | gZ = "); Serial.print(convert_int16_to_str(gyro_z));
Serial.println();
*/
// delay
// delay(1000);
// Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
// Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
// Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
// Serial.print(" | aY_raw = "); Serial.print(accelerometer_y);
// Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
// Serial.println();
// LEDs je nach Y-Schräglage dimmen
//----------------------------------------------------------
// Spielraum des Sensors für Y-Kanal ist ca. 100-500, wenn er hochkant (also die Platine) im Breadboard steckt und dieses flach aufliegt.
// Wird der Sensor geneigt, gehen die Ausschläge bis ca +/-16500, bei 45 Grad ist er bei ca -12.000 und +10.500, zum Test wird 16.000 benutzt
// LEDs werden erst ab +/- 1.000 angesteuert (Spielraum für den Ruhepunkt)
int Y_Value = 0; // Neigungswert
int Y_Max = 16500; // Standard für Maximalwert der Neigung
int LED_ID = 0; // welche LED entsprechend angesteuert werden soll
int LED_ID_Off = 0; // welche LED entsprechend nicht angesteuert werden soll
bool show_Y = false; // Schalter, ob Neigung per LED angezeigt werden soll
int LED_Value_Int;
int DeadZone=1500; // Ruhepunkt
// Neigung nach rechts
if (accelerometer_y > DeadZone)
{
Y_Value = accelerometer_y;
LED_ID = 5; // LED an Pin 5 für rechts
LED_ID_Off=6; // Welche LED nicht leuchten soll
show_Y = true;
Y_Max = 16500;
}
// Neigung nach links
if (accelerometer_y < (DeadZone*-1))
{
Y_Value = accelerometer_y * -1; // negativen Wert invertieren
LED_ID = 6; // LED an Pin 6 für links
LED_ID_Off=5; // Welche LED nicht leuchten soll
show_Y = true;
Y_Max = 16000;
}
// Neigung über Ruhepunkt, LED ansteuern
if (show_Y == true)
{
// Serial.print(" | neigung! ");
float LED_Value;
LED_Value = (255 / (float(Y_Max) - DeadZone)) * float(Y_Value-DeadZone); //PWM-Wert ermitteln (Y_Value und Y-Max minus Ruhewert, dann per Dreisatz Wert von 0-255 ermitteln)
LED_Value_Int = (int)(LED_Value + .5); // Float in Int umwandeln und kaufmännisch runden
if(LED_Value_Int>255)
LED_Value_Int=255;
analogWrite(LED_ID, LED_Value_Int);
analogWrite(LED_ID_Off, 0);
}
else
{
analogWrite(5, 0);
analogWrite(6, 0);
}
}
Das sieht dann im Video so aus:
Das kann man jetzt weiterspinnen und z.B. eine Warn-LED ansteigend leuchten und am Ende wild blinken lassen oder die Blinker anschalten oder auch ein Ton-Signal ausgeben.
Wichtig ist natürlich, den Kipp-Wert des Fahrzeugs zu ermitteln und die Schwellwerte entsprechend anzupassen.
Da der Gyro ja alle drei Achsen im Raum überwacht, kann man also neben Seitenneigung auch die Neigung in Fahrtrichtung prüfen, also wie steil der Hang sein darf.
Und für die Basher unter uns könnte man natürlich die Unterbodenbeleuchtung anschalten, wenn die Karre gerade im Backflip ist. So als Idee
Der Gyro muss übrigens nicht kalibriert werden. Egal in welcher Position ich den anschalte, da kommt in gleicher Lage immer der gleiche Wert raus.