Accelerometer steuert Pan/Tilt... Und der Arduino Crasht

Hallo zusammen

Ich hab folgendes Problem: Mein Sketch liest Werte von einem Accelerometer aus und soll sie an ein Pan/Tilt Modul weitergeben.

Der Code funktioniert auch genau so wie er soll, etwa eine oder zwei Minuten. Danach 'crasht' der Arduino.

Die Servos bewegen sich nicht mehr, und der Arduino friert ein.

  • Lösung: Ich kann über Putty den Com-Port ansprechen, dann 'rebooetet' sich der Arduino und geht wieder.

Ich kann ihn also ohne ein- ausstecken am PC (für Strom) wieder zum laufen kriegen, nur durch das Initialisieren einer Seriellen Verbindung. Er 'hört' also noch hin am USB-Ausgang, aber die Servos sind 'tot'.

Damit meine ich, dass die Servos sich überhaupt nicht bewegen. Normalerweise, wenn ich das Accelerometer nicht bewege wackeln die Servos leicht, da das Accelerometer, auch wenns ruig auf dem Tisch liegt, leichte Schwankungen von 1-2 Grad verzeichnet. Mit etwas Code lässt sich das vermeiden, in dem ich sage dass der Servo z.B. erst ab einem Delta von mehr als 2 Grad angesprochen werden soll. Hat sich aber zum Debuggen als nützlich erwiesen, genau das nicht zu tun.

Alalyse:

-Der Puffer/Cache wird nicht durch die Serielle Übertragung der Debug-Informationen überfüllt. Bevor ich die Bedingung eingebaut hab dass er nur jedes 30. Mal senden darf, hab ich den Seriellen Teil komplett auskommentiert, das Problem blieb bestehen.

  • Ich hab die Library im Verdacht für den Accelerometer. Kenn mich aber zu wenig aus was passiert beim Kompilieren. Nimmt er da die ganze Lib mit oder was passiert da? Andererseits ist die Lib von 2012, und das Bauteil wird sich nicht gross verändert haben in der Zeit...
  • Wenn ich die Servos ansteuere ist das nicht mit einem direkten Wert, sondern er muss noch rechnen. (90° +/- Accelerometer-Wert). Darf ich das nicht? Muss ich das vorher rechnen und die ferige Variable übergeben? Kanns sein dass er dadurch crasht?
    Prinzipiell stimmt die Rechnung, das Accelerometer gibt Maximalwerte von -63 bis +63 aus, und egal ob ich sie von den 90° Servo abziehe oder dazurechne bleib eich unter den maximalen 180° die der Servo machen kann. Das muss ich noch optimieren um den Servo optimal auszulasten, sit aber hier nicht der Punkt.

Also hier mein Setup:

- Arduino Uno R3
- Accelerometer MMA7455
- Bibliothek für Accelerometer: Google Code Archive - Long-term storage for Google Code Project Hosting.

... Und der Code:

#include <Wire.h> //Include the Wire library
#include <MMA_7455.h> //Include the MMA_7455 library
#include <Servo.h> //Include the Servo library
 

//Make an instance of MMA_7455
MMA_7455 accelerometer = MMA_7455();
//Variables for the values from the Accelerometer Ssensor
char xVal, yVal, zVal; 

//Servo Instances
Servo tiltservo;
Servo panservo;

int serialcount = 0;

void setup()
{
  //Activate Serial
  Serial.begin(9600);
  delay(1000);

  // Set the sensitivity For Accelerometer
  // 2 = 2g, 4 = 4g, 8 = 8g
  accelerometer.initSensitivity(2); 

  //Calibrate Offset of Accelerometer
  accelerometer.calibrateOffset(-1.5, 10.0, -11.0);
  
  //Attach Servo
  tiltservo.attach(9);
  panservo.attach(10);
  
}

void loop()
{
  //Read Values
  xVal = accelerometer.readAxis('x'); //Read out the 'x' Axis
  yVal = accelerometer.readAxis('y'); //Read out the 'y' Axis
  zVal = accelerometer.readAxis('z'); //Read out the 'z' Axis

  //Write Values to Servo
  tiltservo.write(90 + xVal);
  panservo.write(90 - yVal);


  //Write Serial Debug Info every 50th Cycle (500ms)
  if(serialcount <= 29){
    serialcount++;
  }
  else{
    Serial.print("X = ");
    Serial.print(xVal, DEC);
    Serial.print("   Y = ");
    Serial.print(yVal, DEC);
    Serial.print("   Z = ");
    Serial.println(zVal, DEC); 
    serialcount = 0;
  }
 
  
  delay(20);
  
}

Hat jemand ne Idee was ich falsch gemacht hab? Codemässig gehts nicht viel simpler. :blush: Und funktionieren tut's ja auch... Die Tatsache dass es erst nach 1-2 Minuten crasht lässt mich an überlaufende Caches denken. Bin ich ev. dort auf dem richtigen Weg?

johnnygueggu:
Hat jemand ne Idee was ich falsch gemacht hab?

Instabile Stromversorgung?

Wie werden die zwei Servos mit Strom versorgt?
Getrennt vom Arduino?
Oder hängst Du die Servos womöglich an den 5V Pin des Arduino?

Joa, die hängen am 5v des Arduino. Der hängt allerdings am PC, da kanner genug Saft ziehen, oder?
Oder müssen die Servos per Definition ne andere Stromquelle haben?

USB 2.0 macht maximal etwa 500mA laut Spezifikation:

Das ist nichts für Servos. Du solltest den Strom generell nicht über das Arduino Board leiten, sondern direkt an den Verbrauchern anschließen und nur die Masse verbinden.

johnnygueggu:
Joa, die hängen am 5v des Arduino. Der hängt allerdings am PC, da kanner genug Saft ziehen, oder?

Ein USB-Anschluss kann per Definition bis zu 500 mA liefern.

Viele Servos können aber schon einzeln deutlich mehr als 500 mA Strom ziehen.

Dann bricht die Spannung ein.

Dann macht der Controller was er will.

johnnygueggu:
Oder müssen die Servos per Definition ne andere Stromquelle haben?

Wenn das kleine "Mini" Servos der kleinsten Baugröße sind und Du sie einzeln ansteuerst, so dass immer nur ein Servo in Bewegung ist und der zweite dabei in Ruhe, sollte es mit USB-Versorgung von Arduino und Servo eigentlich hinhauen.

Bei starken Servos und wenn beide Servos gleichzeitig laufen, müßtest Du Dir mal die Spannung auf der 5V-Leitung auf einem Oszilloskop ansehen, ob die 5V wie ein Strich in der Landschaft stehen oder ob die Spannung zappelt.

Wenn Du kein Oszilloskop hast, müßtest Du mit der Stromversorgung der Servos eher auf Sicherheit gehen und die Servos an ein Batteriepack oder ein 5V-Netzteil hängen (dabei GND Servostromversorgung mit GND Arduinostromversorgung verbinden).

Mike60:
aktuelle Messung an den "Billigteilen" SG90 = 300mA pro Servo bei geringer Last (Pan/Tilt- Gelenk ohne zusätzliche Anbauten)

Wenn Du denkst, dass es nicht an der Servostromversorgung liegt:
Nimm die Servos aus Deiner Schaltung raus!

Stürzt das Programm dann immer noch ab, wenn die Servos gar nicht angeschlossen sind?

Bin ich jetzt total daneben?
Kann der Arduino pro PIN nicht max 40mah und für den Gesamtverbrauch hat der auch ne Limitierung. Dann wäre das wohl klar, warum der einfriert.
Kannst ja noch froh sein, das der nicht abgeraucht ist.