Servo mit MPU6050 ansteuern

Hallo zusammen,

Ich würde gerne eine Fahrerhausfederung für einen LKW im Maßstab 1:14 bauen. Als Board wollte ich einen Nano nutzen. Über einen MPU6050 sollte man ja die Bewegung messen können. 2 Servos sollte das Fahrerhaus bewegen und so die Federung simulieren. Das Problem ist, dass das Servo bei Bewegungen nachschwingen soll. Das kann man hier sehr gut sehen:

Könnt ihr ihr vielleicht einen Tipp geben, wie ich das am besten realisiert bekomme? Bin leider in Sachen Arduino noch nicht so fit, wie ich gerne wäre…

Vielen Dank im Voraus !

Viele Grüße
Sven

Hallo
dann hast du zwei Möglichkeiten:
die Fertigkeiten selber aneignen
oder
im weltweiten Netz nach dem Sketch suchen

Das Problem ist eher, dass du die Dynamik und die Bewegungen eines gefederten Fahrerhauses simulieren willst. Wenn du diese Bewegung hast, kannst du drangehen, diese Bewegung durch Servobefehle zu erzeugen.

Das einfachste Modell wäre sowas:
Masse.jpg

Da musst du nur Beschleunigung in 1 Richtung auswerten und hast nur 1 Bewegung, die dein Servo nachfahren muss. Wenn du das hast, ist dir klar, dass "Nachschwingen" selbst nicht dein Problem ist, sondern dass das Modell zu einfach ist, besonders, wenn du tatsächlich seitliche Kippbewegungen durch zwei unterschiedlich angesteuerte Servos simulieren willst, und wenn (Schwerpunkt oberhalb Drehachse) auch Vorwärts-Beschleunigungen zum Nicken führen.

Der Arduino ist noch der einfachste Teil, fürchte ich.

Masse.jpg

Du meinst also, ich sollte erstmal das Modell und die Mechanik erstellen. Dann einen Servobefehl so zusammenstellen, dass die Bewegung gut aussieht und diesen dann mit dem Sensor verknüpfen. Habe ich das richtig verstanden ?

Nein. Mit Modell meinte ich eher ein "mathematisches" Modell / Simulation.

Das berechnet laufend aus Beschleunigungswerten des Sensors und der aktuellen Lage und Geschwindigkeit der simulierten Kabine die neue Bewegung und neue Position der Kabine. Je nach simulierter Masse, simulierter Feder und Dämpfung wird dies das Überschwingen und Nachfedern der simulierten Fahrerkabine darstellen.

Diesen Wert dann jeweils in eine passende Servostellung umzurechnen, hängt natürlich von der Geometrie deines Modellautos ab.
Das kannst auch gerne zuerst bauen. Das Problem ist eher "einen Servobefehl so zusammenstellen, dass die Bewegung gut aussieht"

IMO ist wie oben skizziert das mechanische Modell sehr einfach zu realisieren. Du brauchst ~ 200g und weiche Federn + langer Hebelarm.

a) warum braucht es dazu überhaupt Elektronik? Warum kannst du nicht as Fahrerhaus so lagern, dass sich das Schwingen durch die Bewegung des Fahrzeugs ergibt?

b) Wenn ich das richtig sehe, gibts das eh fertig - warum das Rad neu erfinden?

Hallo,

evenuell kannst Du ja wirklich so vorgehen und das "experimentell" ermitteln. Im Wesentlichen handelt es sich bei einer Schwingung immer um eine gedämpfte Sinuskurve. Ich denke wenn Du da ein mathematisches Modell für aufstellen willst kommst Du vom Stöckchen zum Hölzchen. Irgendwie kommst Du ja von der aktuellen Lage des Lagesensors auf eine neue Position des Servos. Dabei must Du doch erst mal nur übers Ziel hinaus und dann wieder zurück. Wenn man das mit einem richtigen Regelkreis PI Regler lösen würde wäre der halt viel zu spitz eingestellt. Aber ich denke das ist viel zu kompliziert angesetzt.

Differenz berechnen zwischen Soll und Ist und das mit einem intergalaktischen Faktor versehen so das die Position 20% überfahren wird. Und das mehrfach bis die Differenz fast weg ist. Dann sollte so ein Schaukeln entstehen.

Heinz

warum braucht es dazu überhaupt Elektronik?

Berechtigte Frage.
Im Modellbau gibt es zwar einen Größenmaßstab (z.B. hier 1:14)
aber den dazu passenden Kraft- , Massen- und Zeitmaßstab zu realisieren, damit es “gut aussieht”,
ist nochmal eine zusätzliche Herausforderung.

Wie baust du ein Modell einer mechanischen Pendeluhr im Maßstab 1:10, deren Pendel trotzdem mit 1/1s Frequenz schwingt?

Bis man da Zusatzgewichte versteckt, verschiedene Federhärten und ??? ausprobiert, passt man schneller (und in beliebigem Bereich) ein paar Software-Parameter an.

Einen PID - Regler für Arduino gibt es ja “fertig”. So ähnlich stelle ich mir einen Dynamik-Simulator vor. Ob Suchen oder Selber Schreiben da besser ist, weiß ich nicht. Selbst wenn man was findet, wird man sich tief reinwühlen müssen.

Wie baust du ein Modell einer mechanischen Pendeluhr im Maßstab 1:10, deren Pendel trotzdem mit 1/1s Frequenz schwingt?

Die Federkraft aka Gravitation bleibt bei der Pendeluhr gleich, egal welcher Maßstab. Deshalb wird das gute Teil ja auch mit passendem Gewicht+Feder gebaut, damit's stimmt. Wie Masse und Federkraft eine Schwingungsdauer ergeben steht im Physikbuch - oder hier schwingungsdauer masse federkraft at DuckDuckGo

Es ist übrigens eine Illusion zu glaube, das ist in Software schneller umgesetzt. In einer Stunde Werkstatt hast du das ganze System gebaut, verschiedene Federn + Massen getestet und ausprobiert. Beim Programmieren bist du grad' mal bei den Bugfixes angelangt, damit du in den nächsten Tagen eine sinnvolle Bewegung simulieren kannst.

Wie Masse und Federkraft eine Schwingungsdauer ergeben steht im Physikbuch

Musst du also beim Bespiel Pendeluhr-Modell eine Feder irgendwo einbauen, wo im Original gar keine ist.
Dann kannst du auch einen Motor einbauen, der ein frei schwingendes Pendel nur simuliert.

Aber ich gebe dir recht: Mit gut ausgerüsteter Werkstatt ist ein geübter und begabter Modellbauer oft schneller als ein Programmierer, der am Ende nur eine Handy App erstellt auf der eine Animation zu sehen ist, anstelle eines echten Teils.

Lös' dich von "Pendeluhr" und bleib bei "Pendel", dann ist's einfacher :slight_smile:
Aber um bei Pendeluhr zu bleiben: die Drehpendeluhr funktioniert ohne Gravitation mit Torsionsfeder + rotierende Masse, z.B. hier: Uhrensuche - Im Modellbau nimmst du als Torsionsfeder einfach eine Kugelschreiberfeder, je nach Phantasie/Können mit Achse in der Mitte oder um eine Achse gewickelt und Muttern (M12 oder was auch immer im Hause ist) als Masse.

Hallo zusammen,

würde das Thema gerne nochmal aufgreifen. Ich bin Modellbauer. Diese Bewegung bekommt man nicht mit Federn hat. Die Masse muss durch ein Servo simuliert werden. Ich habe nun einen Code gefunden und auch getestet. Das ganze läuft öffentlich, sodass jeder mitarbeiten kann. Die Servos reagieren wunderbar auf die Bewegungen und werden auch entsprechend angesteuert. Nun fehlt nun noch das nachwippen. Das könnte man wohl über einen PID einstellen. Habe dazu auch mal ein Video bei Youtube gesehen, in dem genau dieser “nachwipp” Effekt zu sehen war.

Leider blicke ich beim Thema PID nicht wirklich durch. Ich wüsste nicht, wie ich den PID Regler in das Programm implementieren könnte. :confused:

Hier das aktuelle Programm:

// 4 Channel "Micro RC" Receiver with 4 standard RC Servo Outputs (used as active suspension)
// ATMEL Mega 328P TQFP 32 soldered directly to the board, 8MHz external resonator, (tested on a Pro Micro 8MHz)
// MPU-6050 gyro / accelerometer


/* This code is still very quick and dirty!
 *  MPU-6050 code based on the work of Joop Brokking, no library required!
 *  8MHz is a bit on the weak side, servo lag may occure
 *  This simulation shows an active truck cabin suspension, using 4 servos
 */  

const float codeVersion = 0.1; // Software revision (see)

//
// =======================================================================================================
// BUILD OPTIONS (comment out unneeded options)
// =======================================================================================================
//

#define DEBUG // if not commented out, Serial.print() is active! For debugging only!!

//
// =======================================================================================================
// INCLUDE LIRBARIES
// =======================================================================================================
//

// Libraries
#include <Wire.h> // I2C library (for the MPU-6050 gyro /accelerometer)
#include <Servo.h>

// Tabs (header files in sketch directory)
#include "MPU6050.h"
#include "helper.h"

//
// =======================================================================================================
// PIN ASSIGNMENTS & GLOBAL VARIABLES
// =======================================================================================================
//

// Create Servo objects
Servo servoFL;
Servo servoFR;
Servo servoRL;
Servo servoRR;

// Pin assignment
#define SERVO_FL_PIN 4 // Front left servo pin
#define SERVO_FR_PIN 5 // Front right servo pin
#define SERVO_RL_PIN 6 // Rear left servo pin
#define SERVO_RR_PIN 7 // Rear right servo pin

//
// =======================================================================================================
// MAIN ARDUINO SETUP (1x during startup)
// =======================================================================================================
//

void setup() {

#ifdef DEBUG
  Serial.begin(115200);
  delay(3000);
#endif


  // Servo pins
  servoFL.attach(SERVO_FL_PIN);
  servoFR.attach(SERVO_FR_PIN);
  servoRL.attach(SERVO_RL_PIN);
  servoRR.attach(SERVO_RR_PIN);

  // MPU 6050 accelerometer / gyro setup
  setupMpu6050();


}

//
// =======================================================================================================
// WRITE SERVO POSITIONS
// =======================================================================================================
//

void writeServos() {

    servoFL.write(constrain((90 + along / 50 - across / 50 - vertical / 50), 45, 135)); // 45 - 135° (front left)
    servoFR.write(constrain((90 - along / 50 - across / 50 + vertical / 50), 45, 135)); // 45 - 135° (front right)
    servoRL.write(constrain((90 - along / 50 - across / 50 - vertical / 50), 45, 135)); // 45 - 135° (rear left)
    servoRR.write(constrain((90 + along / 50 - across / 50 + vertical / 50), 45, 135)); // 45 - 135° (rear right)
     
  
}
// =======================================================================================================
// SUSPENSION CALCULATIONS
// =======================================================================================================
// 

void calculateSuspension() {
  
  // Read sensor data
  readMpu6050Data();

}

//
// =======================================================================================================
// MAIN LOOP
// =======================================================================================================
//

void loop() {

  // Calculate suspension
  calculateSuspension();

  // Write the servo positions
  writeServos();
  
}

Hallo

lese noch mal #7

Heinz

Also bei einer Abfrage den Wert immer vergleichen und in Schritten runtersetzen bis es gleich ist ? Wie mache ich das hier in diesem speziellen Fall, da hier ja gleich 3 Werte abgefragt werden ?

Hallo,

bei dem Sensor hast Du ja 3 Achsen, irgendwie musst Du die da auf 2 Achsen umrechnen. Ich hab auch keine Vorstellung davon wie man das machen kann. Denke man muss man da tief in die Vectorgeometrie einsteigen. Irgendwann wirst Du aber dann ja für die 4 Servos neue Sollwerte haben, das wären dann die auf die die Servos fahren müssten damit der Sensor in der gewünschten Lage ist. Dafür wird man was finden.

Du solltest das erst mal mit einer Achse probieren. Wenn Da jetzt bei rauskommt das Deine neue Position z.B 150grad sein soll und die aktuelle ist z.B 100 Grad. Dann müsstets Du eigendlich ja 50 grad fahren. Allerdings wurde man ja 150 als neue Position an den Servo geben. Da würde dann aber nichts schaukeln. Man muss also erst mal überfahren. Wenn Du z.B mit einer Schrittkette nacheinander 4 unterschiedliche Sollwerte nach der Gleichung an fährts dann schaukelt das ertwas hin und her

neuePos=aktuellPos + (Zielpos-aktuellPos)*1,4

Zahlenbeispiel
100+(150-100)*1.4 =170
170+(150-170)*1,4=142
142+(150-142)*1,4=153
auf sollwert 150 fahren

Du wirst ja auch eine Servo lib brauchen bei der Du die Geschwindigkeit vorgeben kannst. Gut wäre halt noch wenn die auch die aktuelle Position zurück liefert. Dann kannst Du damit (alle4 pos erreicht) auf den nächsten Schritt schalten.

Also das ist jetzt mal nur ins Grobe gedacht

Heinz

Hallo Heinz,

vielen Dank für Deine Ausführungen. Dann werde ich das erstmal so mit einem Servo ohne Sensor testen und mich dann Stück für Stück weiter einarbeiten.

Habe das jetzt mal probiert. Ich denke aber, dass ich da einen Fehler gemacht habe - Bekomme auch eine Fehlermeldung.

// =======================================================================================================
// WRITE SERVO POSITIONS
// =======================================================================================================
//

void writeServos() {

  int aktuellPos = (constrain((90 + along / 50 - across / 50 - vertical / 50), 45, 135)); // 45 - 135° 
  int zielPos = (constrain((110 + along / 50 - across / 50 - vertical / 50), 45, 135)); // 45 - 135°
  int neuePos=aktuellPos + (zielPos-aktuellPos)*1,4

    servoFL.write(neuePos);
    servoFR.write(neuePos);
    servoRL.write(neuePos);
    servoRR.write(neuePos);

svenloeffler:
Bekomme auch eine Fehlermeldung.

Warum hältst Du die geheim?

Gruß Tommy

exit status 1
expected unqualified-id before numeric constant

Das ist die Fehlermeldung