PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo am Attiny45



Chandler
22.03.2014, 12:15
Hallo,
ich habe einen Attiny45 und möchte damit einen Servomotor ansteuern. Leider habe ich absolut keine Ahnung, wie ich da vorgehen soll. Auch das Datenblatt verstehe ich da nicht so ganz.
Ich bin leider noch ein Anfänger in Mikrocontroller, daher auch diese Probleme. Die PWM sollte an PB0 des Controllers generiert werden.
Wäre über jeden Tipp dankbar.

Chandler

Dieser Code ist hat eigentlich noch keine Auswirkung, aber so oder so ähnlich sollte es hinterher aussehen.


#define F_CPU 1000000UL

#include <avr/io.h>
#include <util/delay.h>


int main (void)
{
DDRB = 0b100111;
PORTB = (1<<PB3) | (1<<PB4);

// Servo auf Mittelstellung fahren

while( 1 ) {
if( !(PINB & (1<<PINB3)) ) {
// Servo nach links drehen
}
if ( !(PINB & (1<<PINB4)) ) {
// Servo nach rechts drehen
}
}
return 0;
}


Kann mir jemand einen hinweis geben, sodass ich das auf mein Problem anwenden kann?

oberallgeier
22.03.2014, 12:41
Hallo Chandler

willkommen im Forum.


... ich ... möchte ... einen ...motor ansteuern ...Was für einen Servomotor? Schrittmotor, Gleichstrommotor mit Bürste, brushless Motor aber vermutlich einen Modellbauservo? Nenn bitte mal wenigstens die Bauform, evtl. auch die Typenbezeichnung. Spannung, etc.


... Attiny45 ... möchte ... einen Servomotor ansteuern ... Dieser Code ... hat ... keine Auswirkung ...WENN Du einen Modellbauservo ansteuern möchtest, dann schau doch mal diesen ganzen Abschnitt durch (klick).

(http://www.rn-wissen.de/index.php/Servos)

Chandler
22.03.2014, 18:02
Hi und danke für die Antwort. Habe mir das angeguckt und das meiste (also wie ein Servo) funktioniert war mir klar.
Und ja, es handelt sich um ein Modellbau-Servo. Wusste gar nicht, dass es so viele verschiedene gibt.

Aber wirklich weiter gekommen bin ich noch nicht.


#define F_CPU 1000000UL

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


#define SERVOPIN 0
#define SERVOPORT PORTB
#define DDRSERVO DDRB

volatile unsigned char servopos;

void servo_init()
{
TIMSK |= (1<<OCIE1A);
TCCR0A |= (1<<WGM01) | (1<<CS00);
OCR0A = F_CPU/100000;
DDRSERVO|=(1<<SERVOPIN);
}

ISR(TIMER1_COMPA_vect)
{
static int count;
if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
else SERVOPORT|=(1<<SERVOPIN);
if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
else count=0;
}

int main (void)
{
DDRB = 0b100111;
PORTB = (1<<PB3) | (1<<PB4);

// Servo auf Mittelstellung fahren

while( 1 ) {

if( !(PINB & (1<<PINB3)) ) {
// Servo nach links drehen
}

if ( !(PINB & (1<<PINB4)) ) {
// Servo nach rechts drehen
}
}
return 0;
}


bei servo_init wird die PWM erzeugt. da Bin ich mir nicht ganz sicher, ob ich das so richtig geändert habe (benutze einen Attiny45). ISR(TIMER1_COMPA_vect) weiss ich gar nicht was das macht und habe auch nichts geändert. Beim Kompilieren gibt es aber schon einmal keinen Fehler. Trotzdem bewegt sich mein Servomotor kein stück.

Wie gebe ich jetzt die von der PWM die Pulsweite und die Periodenweite an? Da bin ich noch nicht ganz schlau draus geworden.

gruß

oberallgeier
22.03.2014, 18:56
... bei servo_init wird die PWM erzeugt ... ISR(TIMER1_COMPA_vect) weiss ich gar nicht was das macht und habe auch nichts geändert ...Macht nix, wenn Du das nicht weiß. Aber leider weiß Dein Controller deswegen/Deinetwegen dann auch nur, dass es die Funktion servo_init() gibt. Aber er weiß nicht, dass er die auch aufrufen soll. Musst Du ihm sagen/schreiben. Und danach noch Interrupts erlauben. Sonst funktionierts immer noch nicht. Und irgendwie sind bei mir (auch bei den 8Beinern) alle Datenrichtungsbits definiert - auch die, die es nicht gibt. Sonst weiß der Controller schon wieder etwas nicht das er irgendwie konfigurieren soll. Und servopos muss auch einen Wert haben - damit der Puls weiß, wie lange er werden soll.

Wsk8
22.03.2014, 21:41
Wie siehts allgemein mit Programmierkenntnissen aus??

Dein Code kann so auch nicht funktionieren. Du rufst die Init-Routine nicht auf und die ist auch noch falsch. Einmal sprichst du Timer0 an und dann wieder Timer1.

Und schon einmal darüber nachgedacht, direkt den PWM-Modus vom Timer zu verwenden anstatt SoftPWM?

mfg

Chandler
23.03.2014, 08:01
Hi,
dass stimmt natürlich. Die Init habe ich nicht aufgerufen. also in der main-Funktion kommt am Anfang noch die Zeile

servo_init();
Mit PWM habe ich bisher nur mit Arduino gemacht (dort ist es ja sehr einfach). Daher habe ich bei Mikrocontrollern noch nciht so wirklich ahnung davon. Ich weiss auch nicht genau, was timer0 oder timer1 ist und habe auch dazu keine wirkliche beschreibung gefunden. Die Teile
void servo_init und ISR(TIMER1_COMPA_vect) habe ich von der Seite, die mir Oberallgeier genannt hat. Da waren aber befehle drinn, die ich in dem datenblatt vom attiny45 niergends finden konnte (z.B. TCCR2). Daher habe ich es so gut wie möglich versucht, es auf meinen controller anzuwenden.
Aber auch, wenn ich die servo_init-Funktion in der main-Funktion aufrufe, passiert nichts. Dies mag aber auch daran liegen, dass ich (ich weiss leider nicht wo und wie) zwei verschiedene Teimer aufrufe.

Eine andere Frage wäre jetzt noch, was der Unterschied zwischen der PWM-Modus vom Timer und der SoftPWM ist.

Chandler