PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo ansteuerung-RN-Wissen



chrisuu
17.08.2009, 14:46
Hi,
vom RN-wissen Portal habe ich mal den Servo-Ansteuerungs-Code ausprobiert, jedoch zuckt der Servo nur wild rum. Habe F_CPU richtig definiert, eine extra Stromquelle für den servo(6V) und schon mehrere Servos ausprobiert. Alles ohne Erfolg; er Zuckt weiter nur rum.
Hier mal den Code den ich verwende

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 1000000UL
#define SERVOPIN 1
#define SERVOPORT PORTB
#define DDRSERVO DDRB

volatile unsigned char servopos;

void servo_init()
{
TIMSK|=(1<<OCIE2);
TCCR2 |= (1<<WGM21) | (1<<CS20);
OCR2 = F_CPU/100000;
DDRSERVO|=(1<<SERVOPIN);
sei();
}

ISR(TIMER2_COMP_vect)
{
static int count;
if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
else SERVOPORT|=(1<<SERVOPIN);
if(count<2000+servopos)count++;
else count=0;
}

int main(){
servo_init();
DDRD &= ~(1<<2); //für den Taster
DDRC |= (1<<5); // für die LED
while(1){
if(PIND & (1<<2)){ //wenn taster gedrückt:
PORTC |= (1<<5); // LED anschalten und-
servopos = 100; // servo mittelstellung

}
else {
PORTC &= ~(1<<5);//andernfalls LED ausschalten, und
servopos = 50; //servoposition aussen
}
}
return 0;

}
Wäre sehr dankbar wenn mir jemand ein Tip geben könnte woran es liegt und wie ich den Servo zum "laufen" bekomme.
mfg
ps: benutze internen 1mhz Takt auf dem Atmega8

radbruch
17.08.2009, 15:19
Hallo

So wird das nichts werden. Wenn der Servoimpuls 1ms dauern soll und er mit dem Wert 100 erzeugt werden soll, dann muss die ISR alle 10µs aufgerufen werden (100*10µs=1000µs=1ms). Das sind 100000 Aufrufe pro Sekunde!

TCCR2 |= (1<<WGM21) | (1<<CS20); //Prescale=1, CTC mode
OCR2 = F_CPU/100000; //alle 10µS ein IRQ
(solche Kommentare sind immer hilfreich und können auch mitkopiert werden!)

Bei Prescaler=1 und OCR2 =1000000/100000=10 hat die ISR genau 10 Kontrollertakte Zeit zur Ausführung (mit Aufruf der ISR, Prolog, Epilog...!) Da deine ISR länger braucht als 10 Takte gibt es einen Überlauf und das Timeing ist futsch.

Lösung:
Schnellerer Porzessortakt. Bei (internen) 8MHz hätten wird 80 Takte Zeit für die ISR. Oder kleinere Auflösung der Servopositionen. Bei 100µs-Zyklen hätten wir 100 Takte für die ISR. Allerdings gingen die Positionsangaben dann nicht von 50 bis 150 sondern nur von 5 bis 15.

btw: Um alle 20ms (nicht nach 20ms!) einen Impuls zu senden muss diese Zeile geändert werden (bei 100µs-Takt sollte hier 200 stehen):

if(count<2000)count++;

Gruß

mic

oberallgeier
17.08.2009, 15:22
... jedoch zuckt der Servo nur wild rum ...Den Code habe ich nicht angesehen - aber wildes Zucken klingt nach einem der Standardfehler: ist GND von der Servoversorgung mit GND vom Controller verbunden?

chrisuu
17.08.2009, 15:39
Durch die änderungen der Positionsangaben von 100 zu 10 bzw150 zu 15 geht die Drehung gut,
Die Stromversorgung vom Controller nehme ich nicht mehr da es scheint als ob das board nicht genug liefern könnte. Nehme jetzt ein extra Netzteil nur für den Servo. Ist das richtig so? Also GND des Servos ist nicht am Controller-board.

chrisuu
17.08.2009, 15:48
Jetzt gehts endlich, ich glaub ich hätte lieber nen paar Traubenzucker essen sollen.... Vielen Dank

radbruch
17.08.2009, 16:01
Hallo

Bei 5 bis 15er-Werten muss aber auch OCR2 mit 100 geladen werden und count mit 200 verglichen werden:

OCR2 = F_CPU/10000; bzw OCR2 = 100;

if(count<200)count++;

Ohne diese Änderung erhält das Servo einen Impuls den es als "drehe in Richtung kurzer Impuls" interpretiert. Zudem gibt es ohne diese Änderung weiterhin den ISR-Überlauf...

Zur Stromversorgung:

+ Kontroller an + Kontrollerspannungsquelle
- Kontroller an - Kontrollerspannungsquelle
+ Servo an + Servospannungsquelle
- Servo an - Servospannungsquelle
- Kontroller an - Servo

Das muss funktionieren.

Gruß

mic

chrisuu
17.08.2009, 16:11
Jop Danke, das mit der Stromversorgung klappt glaub ich. werde jetzt noch ein mit dem Programm rumprobieren und mal sehen was sich so aufbauen lässt =) ...

Pr0gm4n
27.08.2009, 17:44
Hallo,

es ist doch aber theoretisch bei 1 servo zum beispiel schon möglich den servo gleich mit VCC des Boards zu versorgen oder?

LG Pr0gm4n

Besserwessi
27.08.2009, 18:54
Viele Servos geben recht kräftige Störungen auf die Versorgungsspannung. Deshalb trennt man da gerne die Versorgung. Wenn die Spannung stabil genug ist, geht es auch die Versorgung von Servo und µC zusammenzuschalten.

Pr0gm4n
27.08.2009, 19:00
Hi,

macht es dann also sin beim betreiben von 10 servos und einem µC den µC an nen 9V-Block (mit spannungsregler etc.) zu hängen und ne extra spannungsreglerschaltung für die servos über steckernetzteil z.b.?

LG Pr0gm4n