Hallo,
Ich habe ein Programm zur Kontrolle eines Servos an einem Atmega8
geschrieben (siehe Anhang).
Die Kontrolle des Servos funktioniert, die UART-Verbindung geht auch,
aber ich kann die Stellung des Servos nicht über den UART (oder
sonstwie) verändern.
Sobald ich dem Atmel ein Zeichen sende (0,1 oder 2) zuckt der Servo
zwar, aber sonst passiert nichts. Wenn ich dem Servo wiederholt z.B. '0'
sende, bewegt er sich zitternd um ein paar Grad nach Links, aber sobald
ich aufhöre die Zeichen zu senden geht er wieder in die Mittelstellung.
Bei meinen zahlreichen Versuchen den Fehler zu finden, bin ich außerdem
auf folgendes gekommen:
Wenn ich über den UART nicht die Position des Servos verändern möchte,
sondern lediglich die LEDs an PORTC ein- oder ausschalten will, so
funktioniert das nur, wenn der Code für den Servo auskommentiert ist.
1
DDRC=255;//PORTC als Ausgang, PC0-PC3 mit PullUp (Startzustand)
2
PORTC=15;
3
4
while(1)
5
{
6
if(x==0)PORTC=0;else
7
if(x==1)PORTC=255;
8
}
Wenn der Servo aktiviert ist tritt das gleiche Phänomen wie zuvor auf
(Die LEDs flimmern nur kurz auf und werden dann wieder in den
Startzustand versetzt).
Das Problem tritt auch dann auf, wenn der Servo nicht angeschlossen ist,
also bin ich mir sicher, dass es nicht an zu hohem Stromverbrauch des
Servos liegt.
lg
Niko
Ist in Mode 14 nicht ICR1 TOP?
Und wieso machst du die UART-Abfrage interrupt gesteurt? Kannst doch
direkt in der while-Schleife einbinden.
Wer hat dir die Schreibweise in C beigebracht? Ist ja furchtbar
Was ist besser lesbar?
Danke für deine Antwort,
Timmo H. wrote:
> Ist in Mode 14 nicht ICR1 TOP?
Ja, ICR1 ist Top (bei mir 20000) und mit OCR1A verändere ich die
Pulsweite, oder ist das falsch?
> Und wieso machst du die UART-Abfrage interrupt gesteurt? Kannst doch> direkt in der while-Schleife einbinden.
In der while-Schleife sind später andere Dinge vorgesehen, und was
spricht gegen einen Interrupt?
Wenn ich direkt in der Schleife vom UART lese, ändert sich auch nichts.
> Wer hat dir die Schreibweise in C beigebracht? Ist ja furchtbar> Was ist besser lesbar?
Meiner Meinung nach ist meine Schreibweise die leichter lesbare, aber
das ist wohl Ansichtssache.
lg Niko
Lass mal nachrechnen:
Du hast einen Quartz von 12MHz und an der PWM einen Vorteiler von 8. Das
gibt eine Auflösung von 666ns. Wenn Du nun in ICR1 20000 schreibst,
erhältst Du eine Frametime von 13ms statt üblicherweise 20ms. Damit
können einige Servos schon Probleme haben.
Die OCR-Werte schreibst Du mit 350, 1730 und 3100, was einer Pulsdauer
von 0,2ms 1,1ms und 2,0ms entspricht. Die letzten beiden Werte sind
brauchbar, aber mit den 0,2ms kann kein Servo was anfangen.
Üblich sind folgende Zeiten: 0,9ms / 1,5ms / 2,1ms mit einer Frametime
von 20ms.
Gruß,
Peter
Peter Bünger wrote:
>Wenn Du nun in ICR1 20000 schreibst, erhältst Du eine Frametime von 13ms>statt üblicherweise 20ms. Damit können einige Servos schon Probleme haben.
Ich hab es jetzt auf 30000 geändert, das dürfte den 20ms entsprechen
> Die OCR-Werte schreibst Du mit 350, 1730 und 3100, was einer Pulsdauer> von 0,2ms 1,1ms und 2,0ms entspricht. Die letzten beiden Werte sind> brauchbar, aber mit den 0,2ms kann kein Servo was anfangen.
Meiner kann damit was anfangen (Robbe S3003)! Die Werte passen alle,
jedenfalls kann ich mit Werten zwischen ~300 und ~3000 alle Positionen
des Servos anfahren ohne das er Probleme macht.
Danke
Niko
Irgendetwas läuft da komplett falsch...
Ich habe jetzt mal testweise den Prescaler auf 1024 gesetzt und in der
Endlosschleife lasse ich PORTC, an dem LEDs hängen, hochzählen.
Man sieht jetzt deutlich, dass jedes Mal wenn der PWM-Generator PB1
umschaltet der Controller resettet wird (PORTC zählt wieder ab 0). woran
kann das liegen?
Kann es sein, dass ich noch irgendwo eine ISR definieren muss, weil der
default Interrupt Vektor ja den Controller resettet?
Wenn es hilft, poste ich gerne den Code und/oder ein Video.
Danke für eure Hilfe
Ich habe das Problem gerade beheben können.
Der Fehler war ein Hardwarebedingt: Der PWM-Pin PB1 ist bei meinem Board
auf den Reset PIN-gejumpert (fälschlicherweise).
Seit dem Entfernen des Jumpers, funktioniert alles wie erwartet!
Danke für eure Mithilfe
Niko