Hallo ihr,
ich möchte die Bewegung eines Servos in den Hintergrund verbannen, sodass sie unabhänig durchgeführt, egal was der Code gerade noch so ausführt und das sich beide Programmteile sich nicht gegenseitig behindern.
Die meiste Zeit ist ein Servo ja dabei zu warten. Da dachte ich mir, in der Zeit könnte ich ja den eigentlichen Code ausführen.
Ich möchte also in einen Timerinterrupt springen, den Servo ansprechen und dann wieder in das Hauptprogramm.
Ich habe erstmal eine Test"skizze", fast schon eher einen Testtreiber geschrieben, um das ganze erstmal auszuprobieren.
Da Timer0 fürs Delay etc. benutzt wird und Timer1 fürs PWM, dachte ich mir, wäre es dann einzig sinnvolle den Timer2 zu währen. Mit seinen 8 bit läuft er ziemlich schnell über und selbst einem Prescaler von 1024 ist es immer noch etwas zu häufig.
Ich habe die etwas unschöne Lösung gewählt, dass nur jeder 16 (oder in der Realanwednung dann später 32.) Timer Interrupt den Servo ansteuert. Gibt es eine Lösung um das Problem zu umgehen?, Kann man irgendwie doch den Timer1 nehmen, oder aber die Frequenz auf 1MHz herunterregeln? Nebenbei spart das nicht Strom? Das Projekt soll auf Batterie betrieben werden.
Ich habe es so erstmal mit etwas lesen, den Servo so zum laufen gebracht. Leider verhält sich der Servo im Rücklauf etwas merkwürdig. Der Vorlauf funktioniert anscheinend ohne Probleme. Allerdings stockt der Servo im Rücklauf in regelmäßigen Abständen (5 Mal). Auf mich wirkt es so, als ob der Servo, vielleicht an machen stellen, sich sogar in die falsche Richtung bewegt und dadruch eine Art zucken entsteht.
Wisst ihr, wie man auch dieses Problem umgehen kann. Betreibt man den Servo normal (sequenzielles Programm) verhält er sich sich normal.
Den Code bin ich euch ja noch schuldig beglieben:
#include <Servo.h>
#define circle 15 //only move servo in ever (circle+1)-st interrupt
#define SERVO 6
Servo servo;
volatile int timer2Counter; //Timer-Variable
volatile int i = 60;
volatile boolean sweep = 0;
volatile uint8_t wait = 0;
void setup() {
servo.attach(SERVO);
Serial.begin(2400);
noInterrupts();
TCCR2A = 0; //delete all bits
TCCR2B = 0; //delete all bits
timer2Counter = 0;
TCNT2 = timer2Counter;//preload timer
TCCR2B |= (1 << CS10);
TCCR2B |= (1 << CS12);//Sets Prescaler to 1024
TIMSK2 |= (1 << TOIE2);// enables timer overflow interrups
interrupts();
}
ISR(TIMER2_OVF_vect) {
TCNT2 = timer2Counter;
if (wait != circle)//only move servo everly (circle+1)st interrupt
++wait;
else { //going to move servo
if (sweep == 0 ) {//moving forth
if (i == 120)//start backsweep next time
sweep = 1;
servo.write(i);
++i;
}
else {//backsweep
--i;
servo.write(i);
delay(20);
if (i == 60)//start forthsweep next time
sweep = 0;
}
wait = 0;//start new counting, for which interrupt moves servo
}
}
void loop() {
if (wait == circle) {//testroutine
Serial.print(wait);
Serial.print(" ");
Serial.print(sweep);
Serial.print(" ");
Serial.println(i);
}
}
Vielen Dank und Liebe Grüße!