www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit Servo an einem Atmega8


Autor: Niko (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.
  DDRC=255;  //PORTC als Ausgang, PC0-PC3 mit PullUp (Startzustand)
  PORTC=15;

  while(1)
  {
    if(x==0) PORTC=0; else
    if(x==1) PORTC=255;
  }

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

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
while(1)
{
  if(x==0) OCR1A=Links; else
  if(x==1) OCR1A=Mitte; else
  if(x==3) OCR1A=Rechts;
}
oder
while(1)
{
  if(x==0) 
    OCR1A=Links;
  else if(x==1) 
    OCR1A=Mitte; 
  else if(x==3) 
    OCR1A=Rechts;
}
oder sogar
while(1)
{
switch(x){ 
  case 0:
    OCR1A=Links;
    break;
  case 1: 
    OCR1A=Mitte; 
    break;
  case 3: 
    OCR1A=Rechts;
    break;
  default:
    OCR1A=Standard;
}

Autor: Niko D. (niko)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Bünger (pbuenger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Niko D. (niko)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Niko D. (niko)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Niko D. (niko)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.