ich habe eine einfache Testschaltung mit meinem Arduino Mega, einem Servo und einer Lichtschranke aufgebaut. Durch Betätigen der Lichtschranke soll sich der Servo in seiner Position um 90 Grad drehen, und dann wieder zurückstellen. Das Ganze funktioniert eigentlich soweit, nur habe ich noch zwei Probleme:
Während ich ein Programm auf den Arduino übertrage, bewegt sich der Servo irgendwie - ich vermute, dass während des Übertragens das Potential der Servo-Ansteuerungsleitung nicht konstant gehalten wird?
In regelmäßigen Abständen (ca. alle 30 Sekunden) fängt der Servo für ca. 5 Sekunden zu "zittern" an, also er führt ganz schnelle Bewegungen hin und her aus (ca. 10 Grad um seine Ruhelage).
Ich habe schon viel versucht, aber leider keine Antworten bzw. Lösungen für diese Probleme gefunden - vor allem das zweite hat mir schon viel Kopfzerbrechen bereitet. Zur Servosteuerung verwende ich die Servo.h Library, der Ausgang für die Servoansteuerung ist als solcher deklariert und mittels attach()-Befehl dem Servo zugeordnet. Ich sende sonst keine Befehle an den Servo, die eine Positionsänderung hervorrufen würden.
Mit einem anderen "kleineren" Testprogramm funktioniert der Servo einwandfrei, ohne dass er zu zittern anfängt. Das richtige Programm (wo er zittert) ist bereits ein ziemlich großes, da das fertige Programm ein Display bekommen soll und ich hierfür schon einiges programmiert habe (ich denke es würde keinen Sinn machen, den ganzen Code hier zu posten).
Da hat Martin recht.
Wenns nur ein Servo ist, dann kann man das auch zu Fuß ansteuern, ohne Lib.
Ich hatte mir da mal eine einfache Funktion geschrieben:
int ServoPin = 8;
int winkel = 90;
void setup(){
Serial.begin(115200);
pinMode(ServoPin, OUTPUT);
}
void loop(){
while (Serial.available() >0){ // wartet auf Winkeleingabe im Seriellen Monitor
winkel = Serial.parseInt();
Serial.print("Winkel = ");Serial.println(winkel);
}
_Servo(winkel);
}
/*************************************************************************************************
** _Servo() **
**************************************************************************************************
** muß in der loop stehen (ohne DELAY!) sollte alle 20ms aufgerufen werden! **
** gibt >= alle 20ms einen Servopuls am Servopin aus **
** wenn pulseabstand > 20ms ist, wird das Servo langsamer. **
** based on Two-Servo-Test by 'jurs' for German Arduino Forum **
** **
** **
** Input: Winkel **
** Output: **
** genutzte Globale Variablen: **
**************************************************************************************************/
void _Servo(int _angle)
{
const int pulseabstand = 20; // Definition der Kenngrößen
const int Servo_minpulse = 800; // der Servoansteuerung
const int Servo_maxpulse = 2400;
const int Servo_minW = 20; // kleinster und größter Winkel
const int Servo_maxW = 160;
// berechnen der Geradengleichung des Servos
const float m = ((Servo_maxpulse - Servo_minpulse)*1.0/(Servo_maxW - Servo_minW)*1.0);
const int b = Servo_minpulse - m * Servo_minW;
static unsigned long lastRefresh;
if (millis()-lastRefresh < pulseabstand) return; // noch keine 20 ms vergangen
lastRefresh = millis(); // Zeit des erfolgten Refresh merken
_angle = constrain(_angle, Servo_minW, Servo_maxW); // Stellwinkel begrenzen
int pulselength = _angle * m + b;
//Serial.print("Winkel = ");Serial.print(_angle);Serial.print(" Puls: ");Serial.println(pulselength);
noInterrupts();
digitalWrite(ServoPin,HIGH); // Ersten Refresh-Impuls starten
delayMicroseconds(pulselength);
digitalWrite(ServoPin,LOW);
interrupts();
} // end _Servo