mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Digital-Servo Futaba S3151 am ATMega48


Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte gerne einen Digital-Servo Futaba S3151 mit einem ATMega48 
betreiben. Der µC und der Servo hängen an der selben 5V-Spannungsquelle.
Das Steuerkabel ist direkt mit dem Port PB1 (OC1A / Pin 13) verbunden.
Den µC betreibe ich mit 16MHz (Quarz).

Ich habe es mit folgendem Programm versucht, aber nix tut sich:
void servo_init()
{

  TCCR1B = 0x00;
  TCCR1B = (1<<CS11) | (1<<WGM13);
   ICR1  = 20000; 
  TCCR1A = (1<<COM1A1) ;
  OCR1A  = 1222;  //default position  1,222ms = -25°
}


int main()
{

DDRB = 0b00000010;

servo_init();

while (1)
{
delay_ms(1000);
OCR1A  = 1778; // 1,778ms = 25°

delay_ms(1000);
OCR1A  = 1222;  // 1,222ms = -25°

}
}

Folgende Fragen habe ich dazu:

- Kann man den Servo direkt mit dem µC verbinden oder muss ich einen 
Widerstand (4,7K; ähnlich wie bei der Ansteuerung eines BC548C) 
zwischenschalten?

- Die "Low Fuse"-Einstellung ist standardmäßig auf "Divide clock by 8 
internally" und "Int. RC Osc. 8MHz; Start-Up time PWRDWN/RESET: 6 CK/14 
CK + 65 ms". Letztere habe ich geändert auf "Ext. Full-swing Crystal; 
Start-Up time PWRDWN/RESET: 16 CK/14 CK + 65 ms". Korrekt??

- Ist er Timer TCCR1A richtig eingestellt?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel L. schrieb:

> - Kann man den Servo direkt mit dem µC verbinden

ja

> - Die "Low Fuse"-Einstellung ist standardmäßig auf "Divide clock by 8
> internally" und "Int. RC Osc. 8MHz; Start-Up time PWRDWN/RESET: 6 CK/14
> CK + 65 ms". Letztere habe ich geändert auf "Ext. Full-swing Crystal;
> Start-Up time PWRDWN/RESET: 16 CK/14 CK + 65 ms". Korrekt??

Sieht richtig aus.
Überprüfe es, indem du eine LED mittels _delay_ms im 1 Sekunden Takt 
blinken lässt. Wenn deine F_CPU Angabe mit der tatsächlichen Taktrate 
übereinstimmt, dann blinkt die LED auch mit 1 Sekunde. Ansonsten bei 4 
Mhz zb 4 mal so schnell oder 4 mal so langsam. etc. Auf jeden Fall: mit 
freiem Auge und ohne Messgerät erkennbar abweichend von 1 Sekunde.

> - Ist er Timer TCCR1A richtig eingestellt?

Lass mich das Datenblatt und deine Berechnung checken.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was steckt hinter der Idee, eine Phase/Frequency korrekte PWM zu 
benutzen? Ich wüsste jetzt auf Anhieb nicht, wie die die Dinge 
vereinfachen würde.

Modus 14 wäre zb ein guter Modus. Fast PWM mit Top Wert in ICR1

Aber abgesehen davon sollte auch der Phase/COrrect Mode gehen. Deine 
Berechnung scheint richtig zu sein und auch an der Pin Einstellung kann 
ich nichts entdecken.

Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Überprüfe es, indem du eine LED mittels _delay_ms im 1 Sekunden Takt
> blinken lässt. Wenn deine F_CPU Angabe mit der tatsächlichen Taktrate
> übereinstimmt, dann blinkt die LED auch mit 1 Sekunde. Ansonsten bei 4
> Mhz zb 4 mal so schnell oder 4 mal so langsam. etc. Auf jeden Fall: mit
> freiem Auge und ohne Messgerät erkennbar abweichend von 1 Sekunde.

Habe den Test gemacht. LED geht regelmäßig nach einer Sekunde an und 
wieder aus. Scheint taktmäßig alles OK zu sein.

Folgenden Code habe ich dazu verwendet:
void delay_ms(int ms) 
{

  TCCR0B |= (1<<CS01) | (1<<CS00) ;
  int i ;
  for(i=0; i<ms; i++) {

    while(TCNT0<16) ;
    TCNT0=0;
  }
  TCCR0B=0;
}

int main()
{

DDRC = 0b00100000;

while (1) 
{
  PORTC |= (1<<PC5) ;
  delay_ms(1000);
  PORTC &= ~(1<<PC5) ;
  delay_ms(1000);
}

}

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte auch mal ein billiges Digitalservo auf dem Steckbrett mit 
Controller + Batterieversorgung betrieben : Das Servo oszillierte und 
drehte sich von einem Anschlag zum anderen obwohl ein konstanter 
PWM-Wert ausgegeben wurde - mit einem Analogservo funktionierte es.
Erst eine gesonderte Akkuversorgung für das Digitalservo hat geholfen - 
Digitalservos brauchen wesentlich mehr Spitzenstrom, so dass die 
Spannungsversorgung zusammenbricht (was in meinem Fall das Servo aber 
nicht den Controller gestört hat).

Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sven schrieb:
> Ich hatte auch mal ein billiges Digitalservo auf dem Steckbrett mit
> Controller + Batterieversorgung betrieben : Das Servo oszillierte und
> drehte sich von einem Anschlag zum anderen obwohl ein konstanter
> PWM-Wert ausgegeben wurde - mit einem Analogservo funktionierte es.
> Erst eine gesonderte Akkuversorgung für das Digitalservo hat geholfen -
> Digitalservos brauchen wesentlich mehr Spitzenstrom, so dass die
> Spannungsversorgung zusammenbricht (was in meinem Fall das Servo aber
> nicht den Controller gestört hat).

Servo und µC werden von der selben Batterie (5V) versorgt. Im übrigen 
habe ich den Servo an einem Robbe R137F Empfänger getestet, welcher auch 
nur eine 4,8V-Versorgung hat. Test war OK.

Ich tippe mal auf einen Programmfehler.

Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was bedeutet exakt die "Low Fuse"-Einstellung "Divide clock by 8
internally"??  Zumal ja im TCCR1B mit (1<<CS11) ein Prescaler von 8 
eingestellt wird. Habe ich dann keine 16Mhz mehr sondern nur 2 MHz?

Autor: 8AF6lUf8OT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn F_CPU 16e6 ist und dein delay_ms(1000) eine Sekunde, sollte das 
nicht die Ursache sein.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Häät ich mal bloss dein Delay-Progamm kontrolliert.

Das macht nicht das, was du denkst.

Ein einfaches Testprogramm hätte so ausgesehen
#define F_CPU 1600000
 
#include <avr/io.h>
#include <util/delay.h>
 
#define LED_PORT    PORTC
#define LED_DDR     DDRC
#define LED_PIN     PC5
 
int main()
{
  LED_DDR |= (1<<LED_PIN);
 
  while( 1 ) {
    LED_PORT ^= (1<<LED_PIN);
    _delay_ms(1000);
  }
}

je weniger künsteln, desto besser. Je weniger Fehlermöglichkeiten, desto 
besser (dein Timer-Testprogramm hat keinen Vorteiler von 1024, wie alle 
angenommen haben, sondern einen Vorteiler von 64)

Wenn du die CKDIV8 Fuse mitlrweile nicht ausgeschaltet hast, wrst du 
damit nämlich merken, dass die 1 Sekunde keineswegs stimmt.

Dein µC läuft mit 2 Mhz, durch die interne Teilung durch 8. Die muss 
abgeschaltet werden.

Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo das ist es. Ich habe die "Low Fuse"-Einstellung "Divide clock by 8
internally" heraus genommen und schupps stimmen die Delay-Zeiten nicht 
mehr, aber dafür bewegt sich der Servo. ;-)
Ich ändere eigentlich nie die Low Fuse, daher meine Nachfrage.
Werde mal den Teiler neu einstellen.

Autor: Axel L. (ligonap)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Durch die Änderung der "Low Fuse" läuft der ATMega48 nun mit 16MHz. Der 
Delay-Timer musste ich dann auch ändern. Nun läuft alles so wie es soll. 
Dank an alle, die mir geholfen haben.


void delay_ms(int ms) 
{

  TCCR0B |= (1<<CS02) | (1<<CS00) ;
  int i ;
  for(i=0; i<ms; i++) {  

    while(TCNT0<8);  
    TCNT0=0; 
  }
  TCCR0B=0; 
}


void servo_init()
{

  TCCR1B = 0x00;
  TCCR1B = (1<<CS11) | (1<<WGM13);
   ICR1  = 20000; 
  TCCR1A = (1<<COM1A1) ;
  OCR1A  = 1270;  // Servo Startposition
}


int main()
{

DDRB = 0b00000010;

servo_init();

while (1)
{
delay_ms(1000);
OCR1A  = 1880; // Erste Position

delay_ms(1000);
OCR1A  = 1270; // Zweite Position

}
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für diese delays brauchst du doch keinen Timer verschwenden!

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.