PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo "zuckt" nur



KingTobi
24.08.2008, 21:29
Hi

Also ich versuche einen Servo ein meinem myAVR Board zu betreiben.
Als Beispiel habe ich den Code aus dem RN-Wissen Artikel genommen und er sieht jetzt wie folgt aus:


#include <avr/io.h> // I/O Port definitions
#include <avr/interrupt.h> // Interrupt macros

#define F_CPU 4000000
#define SERVOPIN 7
#define SERVOPORT PORTD
#define DDRSERVO DDRD

volatile unsigned char servopos;

void servo_init()
{
TIMSK|=(1<<OCIE2);
TCCR2 |= (1<<WGM21) | (1<<CS20); //Prescale=1, CTC mode
OCR2 = F_CPU/100000; //alle 10µS ein IRQ
DDRSERVO|=(1<<SERVOPIN);
};

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(void)
{
DDRD = 0xFF;
PORTD = 0x00;

sei();
servo_init();

servopos=120;

while(1)
{

}
return 0;
}

Nur leider macht er bis auf wie verrückt "zucken" nichts.
Was hab ich falsch gemacht?

gruß
Tobi

Edit:
So, habs nun doch noch selbst hinbekommen.
Das Beispiel für BASCOM hat mich fehlgeleitet, dort steht man soll einen Wert zwischen 50 und 150 eingeben, bei C ist es aber ein Wert zwischen 0 und 100.
Und zum zucken... der Servo ist sehr alt, vielleicht kommt es ja davon.

radbruch
24.08.2008, 22:00
Hallo

Läuft das myAVR-Board wirklich mit 4MHz? Ich finde auf die Schnelle keine Angaben darüber in der myAVR-Doku (myAVR Board 1.5 LPT (http://www.myavr.info/download/techb_myavr_board_lpt.pdf), myAVR Board 2.0 USB (http://www.myavr.info/download/techb_myavr_board_usb.pdf). Welches Board ist es genau? Versuch mit anderem Pin/Servo auch erfolglos?

In der ISR sollte count mit einem Startwert belegt werden:
static int count=0;

Der Impuls soll alle 20ms wiederholt werden, nicht nach 20ms:
if(count<2000)

Gruß

mic

KingTobi
24.08.2008, 22:03
Hi

Danke für deine Antwort, kam nur leider zeitgleich mit meinem Edit.
Es handelt sich um das myAVR USB 2.07.
Ich hab per Fusebit auf den internen 4MHz Oszilator gestellt.
Naja, morgen nochmal mit nem neuen Servo testen, ich hoffe das das zucken dann weg ist.

KingTobi
25.08.2008, 16:59
Hi

Mal ne Frage:
Warum ist der Winkel um den sie der Servo dreht von 0 - 50 deutlich größer als der Winkel von 50 - 100??

gruß

fhs
25.08.2008, 17:33
Hallo,

Deine ISR dauert auch bei der Optimierungsstufe -Os und F_CPU=4MHz deutlich über 10μs (nämlich etwa 19μs); also wird während der Ausführung der ISR das OCF2 Bit erneut gesetzt, die ISR nach dem Rücksprung erneut angesprungen usw. Bei F_CPU = 4 MHz wirst Du nicht umhin kommen,
--- entweder OCR2 so zu setzen, dass die ISR nur etwa alle 30μs ausgeführt wird, oder
--- die ISR deutlich zu kürzen, oder
--- die Erzeugung des PWM Signals grundsätzlich zu ändern!

Gruß

Fred

PS: Korrigiert: Natürlich OCF2 anstelle von TOV2!

fhs
25.08.2008, 17:41
Hallo,

...Warum ist der Winkel um den sie der Servo dreht von 0 - 50 deutlich größer als der Winkel von 50 - 100??...
diese Frage kapiere ich nicht. Um den ganzen Servo-Bereich zu umfassen, willst Du alle 20 ms einen Impuls erzeugen, der zwischen 0,9 ms und 2,1 ms lang ist (alternativ: 1,0 ms ... 2,0 ms).

Gruß

Fred

KingTobi
25.08.2008, 17:59
Hi

Das Programm oben ist nicht mehr ganz aktuell. Ich arbeite jetzt mit einem Takt von 8MHz.
Die "wichtigen" Programmteile sind aus dem RN-Wissen Artikel über Servos.
Mit dem Bild ist vielleicht besser zu erkennen was ich meine

Hubert.G
25.08.2008, 20:48
Wenn 0 ein Impuls von 1ms ist, 50 dann 1,5ms und 100 2ms dann ist dein Servo nicht linear.

oberallgeier
26.08.2008, 11:45
Hallo alle,

... Frage:
Warum ist der Winkel um den sie der Servo dreht von 0 - 50 deutlich größer als der Winkel von 50 - 100??Ich verstehe Deinen Code nicht so richtig. Denn :

'Wobei 100 die Mitte ist. 50 ist der linke bzw. rechte Anschlag und 150 der entsprechend andere. Das steht aber unter dem BASCOM Codebeispiel ! ! ! Unter dem C-Code heißt es doch:

servopos beinhaltet die aktuelle Dauer des Signals in 1/100ms ... das heißt also, dass Du mit 0 jenseits des einen Anschlags bist, eben bei einer Signallänge 0 ms (na ja, Signaldauer ist gerade mal ein bisschen Verwaltungsaufwand durch die ISR, das sind schon ein paar Maschinenzyklen), mit 50 immer noch über dem Anschlag - nämlich bei 50*1/100 ms =0,5 ms und mit 100 eher gerade am Servoanschlag - 100*100 ms = 1 ms. Sie Dir dazu die Zeichnung an (https://www.roboternetz.de/wissen/index.php/Servos#Ansteuerung). Dann würde Dein Servo aber an einem Ende etwas zucken . . . . . . . weil er mit "0" und "50" über den Anschlag hinausfahren möchte.

Nach meinen Servokenntnissen ist der Servo bei "100" an einem Anschlag, bei "150" in der Mitte (150 * 1/100ms = 1,5 ms) und bei "200" am andren Anschlag (200 * 1/100 ms = 2 ms). Denn:

... D.h. 1ms ist ganz links und 2ms ist ganz rechts ...

KingTobi
26.08.2008, 11:52
@oberallgeier
Kann es sein das du nur meinen ersten Post gelesen hast?

oberallgeier
26.08.2008, 12:46
Könnte natürlich sein. Aber es war nicht nachtschlafene Zeit und ich bin sicher, daß ich den Thread komplett gelesen hatte - kann sein, dass ich etwas überlesen habe. Aber ich finde die Stelle nicht, aus der hervorgeht, dass Dein Wert "0" einen Impuls von etwa 1 ms Dauer erzeugt.

WENN Du einen offset anbringst der zu groß ist, dann könnte es nämlich sein, dass "50" nicht mehr die Mitte ist, sondern etwas "mehr" und dass

... der Winkel um den sie der Servo dreht von 0 - 50 deutlich größer (ist) als der Winkel von 50 - 100 ...
Oder?