Forum: Mikrocontroller und Digitale Elektronik Servo Problemm


von Joel (Gast)


Lesenswert?

Ich würde gerne an einem kleinen Rc Auto eine Kamera einbauen, und sie 
dann mit einem mini servo nach links und nach rechts schwenken.
Nun habe ich dieses mini servo:
http://www.cnchelicopter.com/servlet/the-RC-heli-Mini-servo/Categories

mit einem atmega8 und 4 Mhz verbunden.
1
#define F_CPU 4000000UL
2
 
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 
6
int main (void)
7
{
8
  DDRB = (1<<PB1);
9
 
10
  while( 1 ) {
11
 
12
  
13
    PORTB |= (1<<PB1);
14
    _delay_us( 1500 );    // in den 1500 steckt die Lageinformation
15
    PORTB &= ~(1<<PB1);
16
 
17
    _delay_ms( 18 );      // ist nicht kritisch
18
 
19
20
21
  }
22
 
23
  return 0;
24
}
Jetzt ist das Problem das das Servo, nicht immer in der selben Position 
endet.
Wenn ich Zb denn servo zu beginn mit der hand verstelle.
Oder.
Ich die Stromversorgung unterbreche und dann wieder schließe.
und diesen Vorgang mehrmals durchführe verstellt sich die Endposition 
beim gleichen signal vom Atmega8

Brauche ich ein anderes Servo ?


Die Kamera soll zu beginn (spannung angeschaltet)
geradeaus schwenken.

Bei betätigen eines Knopfes  nach links in eine bestimmte Position 
schwenken.
Bei betätigen eines Knopfes  nach rechts in eine bestimmte Position 
schwenken.

von B.Roll (Gast)


Lesenswert?

Dein Programm ist grottig. Sowas macht man mit einem Timer. Es gibt 
sogar einen Artikel hier auf der Seite, mit einem fertigen Programm!

LG, Björn

von Hubert G. (hubertg)


Lesenswert?

Bist du sicher das das richtig ist, ich habe das anders in Erinnerung.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Servo
http://www.rn-wissen.de/index.php/Servos

von Karl H. (kbuchegg)


Lesenswert?

Joel schrieb:

> mit einem atmega8 und 4 Mhz verbunden.

hast du die 4Mhz kontrolliert?


> Jetzt ist das Problem das das Servo, nicht immer in der selben Position
> endet.
> Wenn ich Zb denn servo zu beginn mit der hand verstelle.
> Oder.
> Ich die Stromversorgung unterbreche und dann wieder schließe.
> und diesen Vorgang mehrmals durchführe verstellt sich die Endposition
> beim gleichen signal vom Atmega8
>
> Brauche ich ein anderes Servo ?

Wenn dein µC das Servo ansteuert, kannst du dann das Servo mit der Hand 
verdrehen oder leistet es Widerstand?

Wenn es keinen Widerstand leistet, dann könnte zb das Signaltiming nicht 
stimmen. Höchst wahrscheinlich, weil die 4Mhz, die du im Code 
eingetragen hast, gelogen sind und dein Mega8 immer noch mit 1Mhz läuft.
Wie hast du denn das Servo an den µC angeschlossen?


Alle: Ja, das Programm ist grottig. Aber es reicht um erst mal 
festzustellen, ob das ganze überhaupt funktioniert oder nicht. Seine 
beschriebenen Symptome dürften auch mit dem grottigen Programm nicht 
auftreten.

von Joel (Gast)


Lesenswert?

1
#define SERVOPIN 7
2
#define SERVOPORT PORTD
3
#define DDRSERVO DDRD
4
5
volatile unsigned char servopos;
6
7
void servo_init()
8
{
9
  TIMSK|=(1<<OCIE2);
10
  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
11
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
12
  DDRSERVO|=(1<<SERVOPIN);
13
};
14
15
ISR(TIMER2_COMP_vect)
16
{
17
  static int count;
18
  if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
19
    else SERVOPORT|=(1<<SERVOPIN);
20
  if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
21
    else count=0;
22
};
Diesen Code habe ich auch schon getestet doch es geht einfach nicht.
Gilt der auch für ein atmega8?

von Karl H. (kbuchegg)


Lesenswert?

Joel schrieb:

> Diesen Code habe ich auch schon getestet doch es geht einfach nicht.

Noch mal:
Hast du deine 4MHz kontrolliert?

Es reicht nicht, in den Code einfach 4Mhz reinzuschreiben. Deswegen 
läuft der µC noch lange nicht mit 4Mhz.

Und wie ist dein Servo angeschlossen? Hast du eine Masseverbdinung vom 
Servo zum µC?

von Joel (Gast)


Lesenswert?

1
#define F_CPU 4000000UL
2
 
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 #define SERVOPIN 7
6
#define SERVOPORT PORTD
7
#define DDRSERVO DDRD
8
9
volatile unsigned char servopos;
10
11
void servo_init()
12
{
13
  TIMSK|=(1<<OCIE2);
14
  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
15
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
16
  DDRSERVO|=(1<<SERVOPIN);
17
};
18
19
ISR(TIMER2_COMP_vect)
20
{
21
  static int count;
22
  if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
23
    else SERVOPORT|=(1<<SERVOPIN);
24
  if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
25
    else count=0;
26
};
27
28
int main (void)
29
{
30
   servo_init();
31
  return 0;
32
}
Hier mein code ist der richtig?

Habe ein Qartz mit 4.000Mhz stehen.
Und es mit dem Atmega8 richtig angeschlossen.
(ich glaube sonst hätte sich der servo mit dem 1 code nicht bewegt.)

von Test (Gast)


Lesenswert?

Joel schrieb:
> Jetzt ist das Problem das das Servo, nicht immer in der selben Position
> endet.
> Wenn ich Zb denn servo zu beginn mit der hand verstelle.
> Oder.
> Ich die Stromversorgung unterbreche und dann wieder schließe.
> und diesen Vorgang mehrmals durchführe verstellt sich die Endposition
> beim gleichen signal vom Atmega8
>
> Brauche ich ein anderes Servo ?

abgesehen davon, ob das Programm nun genau 1500µs Pulse erzeugt oder 
nicht, es wird immer die gleiche Pulslänge erzeugen und der Servo sollte 
immer ziemlich genau (Stichwort Totzeit) an der gleichen Position 
landen.

Durch mehrfache Betätigung könnte er innen warm werden und dadurch durch 
eigene Regelabweichungen geringe andere Stellungen einnehmen.

Wie groß sind die Abweichungen?

Test: Nachdem der Servo nicht mehr in der ersten Stellung landet - 
Signal angeschlossen lassen - warten auf Abkühlung und der Servo sollte 
sich in winzigen Schritten seiner ersten, abgekühlten Stellung wieder 
nähern.

Da würde dann ein besserer Servo Abhilfe schaffen.

Es ist keine gute Idee das Servohorn von Hand zu verdrehen. Schädigt das 
Servogetriebe/lager

von Klaus T. (gauchi)


Lesenswert?

Test schrieb:
> abgesehen davon, ob das Programm nun genau 1500µs Pulse erzeugt oder
> nicht, es wird immer die gleiche Pulslänge erzeugen und der Servo sollte
> immer ziemlich genau (Stichwort Totzeit) an der gleichen Position
> landen.

Das sollte zwar in der Theorie stimmen, aber wenn der uC mit 1 MHz statt 
mit 4 läuft, werden aus den 1.5 ms plötzlich 6 ms, was weit ausserhalb 
des Regelbereichs liegen dürfte. Was das Servo dann macht, würde ich 
nicht unbedingt vorhersagen wollen.

Abgesehen davon wäre es eine interessante Frage, wie groß eigentlich die 
Abweichungen sind.

Nur weil ein Quarz dransteckt, muss der uC den nicht unbedingt 
benutzen...
Und nur weil es sich bewegt, muss es nicht korrekt angeschlossen sein, 
man hat auch schon von Wackelkontakten und Konsorten gehört.

von Karl H. (kbuchegg)


Lesenswert?

Joel schrieb:

> Habe ein Qartz mit 4.000Mhz stehen.
> Und es mit dem Atmega8 richtig angeschlossen.

Das heißt noch lange nichts.

HAST DU ES KONTROLLIERT?

(Nochmal frage ich nicht, dann kannst du dein Servo selbst zum laufen 
bringen)

von Karl H. (kbuchegg)


Lesenswert?

Klaus T. schrieb:

> Und nur weil es sich bewegt, muss es nicht korrekt angeschlossen sein,
> man hat auch schon von Wackelkontakten und Konsorten gehört.


Ich habe viele Servos, die beim Anlegen der Versorgunsspannung erst mal 
einen kleinen Hüpfer machen, ehe sie sich dann beim Eintreffen der 
ersten Signalpulse auf die Position stellen.


> Es ist keine gute Idee das Servohorn von Hand zu verdrehen. Schädigt
> das Servogetriebe/lager

Grundsätzlich richtig. Sollte man nicht machen.
Allerdings, wenn man nicht gerade mit 2 linken Händen an die Sache 
rangeht, kann man mal gegen den Servohebel drücken. Das merkt man 
sofort, ob das Servo dagegenhält oder ob es nachgibt. Hält es dagegen, 
dann hat es Pulse und wird angesteuert. Gibt es nach, dann hat es keine 
Ansteuerpulse. Zumindest keine verwertbaren.


(Ich glaube immer noch, dass sein µC nicht mit den 4Mhz läuft. Entweder 
das, oder er hat nur die Signalleitung verbunden und das Servo hängt 
masseseitig in der Luft)

von Klaus W. (mfgkw)


Lesenswert?

Joel schrieb:
> Hier mein code ist der richtig?

sei()?

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Joel schrieb:
>> Hier mein code ist der richtig?
>
> sei()?

Und die obligate Hauptschleife fehlt auch.

Aber grundsätzlich müsste sein Servo auch auf die erste Version mit den 
_delay_us() reagieren.
Wenn die 4Mhz stimmen, der Optimizer eingeschaltet ist, der Anschluss 
stimmt, die Stromversorgung nicht einbricht, dann kann da nichts mehr 
schief gehen. Ob das Servo dann tatsächlich in der Mitte steht oder 
leicht daneben, ist IMHO erst mal nicht so wichtig. Erst mal muss es 
überhaupt arbeiten.

von Uwe (Gast)


Lesenswert?

Wie sehen denn deine Fuse Bits aus bzw. weißt du was Fuse bits sind ?

von Carsten M. (carsten_m52)


Lesenswert?

Hallo,
Zu allem was hier schon steht (im besonderen Prüfen des echten Taktes) 
scheint auch der Compare Wert für den Timer nicht zu stimmen, wenn Du 
tatsächlich 10µS benötigst.
1
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
Nach meinem Kalkulator müssten da bei 4 Mhz -20- als Comparewert stehen 
und nicht 40 (F_CPU/100000)

Grüße Carsten

von Karl H. (kbuchegg)


Lesenswert?

@Joel

Wenn du nicht weißt, wie man mit einfachen Mitteln die Taktfrequenz des 
µC überprüfen kann, dann sags einfach. Aber überprüfen musst du sie! Das 
ist einer der Bausteine, ohne die gar nichts geht. Servoansteuerung ist 
eine reine Frage von korrekten Zeiten. Und da diese Zeiten letztendlich 
immer in irgendeiner Form mit der µC-Taktfrequenz verknüpft sind, muss 
letztere 100% stimmen. Sonst suchst du dir und wir hier uns einen Wolf 
an Problemen, die in Wirklichkeit keine sind.

von joel (Gast)


Lesenswert?

1
#define F_CPU 4000000UL
2
 #include <avr/interrupt.h>
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 #define SERVOPIN 7
6
#define SERVOPORT PORTD
7
#define DDRSERVO DDRD
8
9
volatile unsigned char servopos;
10
11
void servo_init()
12
{
13
  TIMSK|=(1<<OCIE2);
14
  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
15
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
16
  DDRSERVO|=(1<<SERVOPIN);
17
};
18
19
ISR(TIMER2_COMP_vect)
20
{
21
  static int count;
22
  if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
23
    else SERVOPORT|=(1<<SERVOPIN);
24
  if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
25
    else count=0;
26
};
27
28
int main (void)
29
{
30
     sei();
31
   servo_init();
32
   while(1)
33
   {
34
35
   }
36
  return 0;
37
}
So das ist mein verbesserter code.
Der Quartz ist 100% ein 4Mgz
Hier ein bild:
http://www.henri.de/images/articles/11103_9325b18f1f01ae44ced2485504615715_5.jpg

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:

> Der Quartz ist 100% ein 4Mgz

Du verstehst es immer noch nicht.

Ich glaub dir, dass auf deinem Quarz 4Mhz draufsteht.
Das ist nicht die Frage.

Die Frage lautet: Wird der Quarz vom µC auch BENUTZT?

Wenn du den Quarz einfach nur an den µC angebaut hast und keine 
Fuse-Bits umgestellt hast, dann wird er nämlich NICHT benutzt und dein 
µC läuft auch weiterhin mit 1Mhz.

Ist das wirklich so schwer zu verstehen?

von joel (Gast)


Lesenswert?

Zur Taktfrequenz:
Es kann entweder der interne oder die externe laufen.
Wenn ich denn Quartz aus der schaltung nehme arbeitet der Atmega nicht 
mehr.
Somit nehme ich an das es mit 4 Mhz arbeiten muss wenn ich ihn intern 
nicht noch teile.
Sehr sehr vielen dank für eure hilfe mit so schneller antworten habe ich 
gar nicht gerechnet.
Danke

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:
> Zur Taktfrequenz:
> Es kann entweder der interne oder die externe laufen.
> Wenn ich denn Quartz aus der schaltung nehme arbeitet der Atmega nicht
> mehr.

Gut. Das überzeugt mich.
(Schwere Geburt.
Der Grund warum ich darauf rumreite: Weil ca 80% aller Timingprobleme 
hier im Forum genau darauf zurückzuführen sind)

Nächster Punkt:
Wie hast du das Servo angeschlossen

  rot    Versorgungsspannung
  braun  Masse
  orange Da kommen die Pulse vom µC rein. Sicher, dass du am richtigen
         Pin abgreifst?

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:


> So das ist mein verbesserter code.

Schnelle Frage:
welchen Wert hat 'servopos'?

von joel (Gast)


Lesenswert?

Der Servo ist richtig angeschlossen, habe ihn ja auch schon zu laufen 
gebracht.Nur eben nicht in der richtigen Position.
Habe aber eben noch kontrolliert alles genau so wie du es beschrieben 
hast

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:
> Der Servo ist richtig angeschlossen, habe ihn ja auch schon zu laufen
> gebracht.

Wenn ich deine Beschreibung noch mal lese, dann lese ich heraus, dass 
dein Servo beim Anlegen der Versorgungsspannung einen Hüpfer macht. Das 
hat aber nichts mit 'zum Laufen gebracht' zu tun.
'Zum Laufen gebracht' müsste bedeuten, dass das Servo immer (im 
wesentlichen) die gleiche Position anfährt, egal wie du es vorher mit 
der Hand verdreht hast. Dieses Anfahren der Position muss auch schnell 
geschehen. Man hört richtiggehend, dass sich das Servo nicht einfach 
irgendwie dreht, sondern gezielt an seine Sollposition schnurrt.

von joel (Gast)


Lesenswert?

Mit meinen ersten code
1
#define F_CPU 4000000UL
2
 
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 
6
int main (void)
7
{
8
  DDRB = (1<<PB1);
9
 
10
  while( 1 ) {
11
 
12
  
13
    PORTB |= (1<<PB1);
14
    _delay_us( 1500 );    // in den 1500 steckt die Lageinformation
15
    PORTB &= ~(1<<PB1);
16
 
17
    _delay_ms( 18 );      // ist nicht kritisch
18
 
19
20
21
  }
22
 
23
  return 0;
24
}
Hat es geklappt.
Doch mit dem Timer code leider nicht mehr

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:

> Doch mit dem Timer code leider nicht mehr


Weil du 'servopos' keinen Wert zugeordnet hast. Damit ist der 0 und auf 
Pulse der Länge 0 (oder sehr sehr kurz) reagiert das Servo nun mal nicht 
mehr.

servopos müsste einen Wert von ca. 150 haben.

von joel (Gast)


Lesenswert?

Ok habe nun alles Kontrolliert der Intrrupt wird 100% ausgeführt.
Mit 150 als wert habe ich probiert doch der PD7 pin da macht sich 
nichts.
Hab sogar ein Oszilloskop in der Simulation

von joel (Gast)


Lesenswert?

NEIN ich habe denn Port jetzt als ausgang gesetzt jetzt erhalte ich 
zumindest ein sich verändertes signal ( hab ein osz dran gehalten)
Versuche jetzt es mal mit dem servo

von joel (Gast)


Lesenswert?

1
#define F_CPU 4000000UL
2
 #include <avr/interrupt.h>
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 #define SERVOPIN 7
6
#define SERVOPORT PORTD
7
#define DDRSERVO DDRD
8
9
volatile unsigned char servopos = 150;
10
11
void servo_init()
12
{
13
       
14
  TIMSK|=(1<<OCIE2);
15
  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
16
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
17
  DDRSERVO|=(1<<SERVOPIN);
18
};
19
20
 
21
22
int main (void)
23
{
24
   
25
   DDRD = 0xff;
26
   sei();
27
   servo_init();
28
   while(1)
29
   {
30
     
31
   }
32
  return 0;
33
}
34
35
ISR(TIMER2_COMP_vect)
36
{
37
   
38
  static int count;
39
  if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
40
    else SERVOPORT|=(1<<SERVOPIN);
41
  if(count<2000)count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
42
    else count=0;
43
};
hier der neue code

von joel (Gast)


Lesenswert?

ich bekomme ein kleinen Impuls doch am servo macht sich leider nichts

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:
> ich bekomme ein kleinen Impuls doch am servo macht sich leider nichts

Du hast doch ein Oszi (hättest du das mal früher gesagt :-)
Wie lang ist der Puls?

Er soll 1.5ms lang sein.

von joel (Gast)


Lesenswert?

Es ist 5 ms lang

von joel (Gast)


Lesenswert?

Wenn ich das genauer auslese so 4,2 ms

von STK500-Besitzer (Gast)


Lesenswert?

Ich wuerde sagen, dass es so um die 6ms sind.
Denn das hier passt nicht zusammen:

  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ

#define F_CPU 4000000UL

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:
> Es ist 5 ms lang

Das ist zwar länger als hier bei mir in der Simulation, aber:

Deine ISR ist zu lang. Die wird nicht in 10µs abgearbeitet.

Wenn ich den OCR Wert verdopple, kommen in der Simualtion die Zeiten 
richtig raus:
1
#define F_CPU 4000000UL
2
 #include <avr/interrupt.h>
3
#include <avr/io.h>
4
#include <util/delay.h>
5
 #define SERVOPIN 7
6
#define SERVOPORT PORTD
7
#define DDRSERVO DDRD
8
9
volatile unsigned char servopos = 75;
10
11
void servo_init()
12
{
13
       
14
  TIMSK|=(1<<OCIE2);
15
  TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
16
  OCR2 = F_CPU/50000;      //alle 20µS ein IRQ
17
  DDRSERVO|=(1<<SERVOPIN);
18
};
19
20
 
21
22
int main (void)
23
{
24
   
25
   DDRD = 0xff;
26
   sei();
27
   servo_init();
28
   while(1)
29
   {
30
     
31
   }
32
  return 0;
33
}
34
35
ISR(TIMER2_COMP_vect)
36
{
37
   
38
  static int count;
39
  if(count>servopos)
40
    SERVOPORT&=~(1<<SERVOPIN);
41
  else
42
    SERVOPORT|=(1<<SERVOPIN);
43
44
  if(count<1000)
45
    count++; // Die Impulse sollten alle 20ms gesendet werden! 6.2.11 mic
46
  else
47
    count=0;
48
};

von Karl H. (kbuchegg)


Lesenswert?

STK500-Besitzer schrieb:
> Ich wuerde sagen, dass es so um die 6ms sind.
> Denn das hier passt nicht zusammen:
>
>   TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
>   OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
>
> #define F_CPU 4000000UL

Warum soll das nicht passen?
Für 10µs stimmt das grundsätzlich schon.
Nur sind 10µs zu kurz für die ISR. Das schafft der Mega nicht.

von STK500-Besitzer (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> STK500-Besitzer schrieb:
>> Ich wuerde sagen, dass es so um die 6ms sind.
>> Denn das hier passt nicht zusammen:
>>
>>   TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
>>   OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
>>
>> #define F_CPU 4000000UL
>
> Warum soll das nicht passen?
> Für 10µs stimmt das grundsätzlich schon.
> Nur sind 10µs zu kurz für die ISR. Das schafft der Mega nicht.

bei 4MHz ergibt ein Vorteiler = 1 nur 2,5µs, nicht 10µs...

von joel (Gast)


Lesenswert?

ok warum kann ich den wert nicht ändern
1
int main (void)
2
{
3
   
4
   DDRD = 0xff;
5
   sei();
6
   servo_init();
7
   while(1)
8
   {
9
    _delay_ms(200);
10
  servopos += 10;
11
   
12
   }
13
  return 0;
14
}

von STK500-Besitzer (Gast)


Lesenswert?

ich würde die Geschichte eh per FastPWM machen.

von Karl H. (kbuchegg)


Lesenswert?

STK500-Besitzer schrieb:
> Karl Heinz Buchegger schrieb:
>> STK500-Besitzer schrieb:
>>> Ich wuerde sagen, dass es so um die 6ms sind.
>>> Denn das hier passt nicht zusammen:
>>>
>>>   TCCR2 |= (1<<WGM21) | (1<<CS20);  //Prescale=1, CTC mode
>>>   OCR2 = F_CPU/100000;      //alle 10µS ein IRQ
>>>
>>> #define F_CPU 4000000UL
>>
>> Warum soll das nicht passen?
>> Für 10µs stimmt das grundsätzlich schon.
>> Nur sind 10µs zu kurz für die ISR. Das schafft der Mega nicht.
>
> bei 4MHz ergibt ein Vorteiler = 1 nur 2,5µs, nicht 10µs...


wenn der Timer in 1 Sekunde bis 4000000 zählt, wie lang braucht er dann 
um bis 40 zu zählen (denn genau das ergibt dann F_CPU/100000)

     4000000        1
          40        x
    -------------------
               40
       x = ---------- = 0.00001 Sekunden oder 0.01 Millisekunden
            4000000                      oder eben 10 µs

Nur reichen 40 Takte nicht für einen Durchlauf durch die ISR

von Karl H. (kbuchegg)


Lesenswert?

joel schrieb:
> ok warum kann ich den wert nicht ändern

Heißt das, dein Servo stellt erst mal?


Den Wert kannst du natürlich ändern. Bedenke aber, dass der 
Wertebereich, in dem du dich bewegen kannst von 50 bis 100 geht. Mit 
einem Inkrement von 10 alle 200ms bist du da ganz schnell draussen.

von Karl H. (kbuchegg)


Lesenswert?

STK500-Besitzer schrieb:
> ich würde die Geschichte eh per FastPWM machen.

Würd ich auch.
Aber das ist dann wieder eine andere Geschichte. :-)

von STK500-Besitzer (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
>
>
> wenn der Timer in 1 Sekunde bis 4000000 zählt, wie lang braucht er dann
> um bis 40 zu zählen (denn genau das ergibt dann F_CPU/100000)
>
>      4000000        1
>           40        x
>     -------------------
>                40
>        x = ---------- = 0.00001 Sekunden oder 0.01 Millisekunden
>             4000000                      oder eben 10 µs
>
> Nur reichen 40 Takte nicht für einen Durchlauf durch die ISR

Wo bekommst du die 40 her?
...(1<<CS20) sorgt für einen ungeteilten Takt, oder nicht?

von Karl H. (kbuchegg)


Lesenswert?

STK500-Besitzer schrieb:
> Karl Heinz Buchegger schrieb:
>>
>>
>> wenn der Timer in 1 Sekunde bis 4000000 zählt, wie lang braucht er dann
>> um bis 40 zu zählen (denn genau das ergibt dann F_CPU/100000)
>>
>>      4000000        1
>>           40        x
>>     -------------------
>>                40
>>        x = ---------- = 0.00001 Sekunden oder 0.01 Millisekunden
>>             4000000                      oder eben 10 µs
>>
>> Nur reichen 40 Takte nicht für einen Durchlauf durch die ISR
>
> Wo bekommst du die 40 her?

Hier

  OCR2 = F_CPU/100000;      //alle 10µS ein IRQ

> ...(1<<CS20) sorgt für einen ungeteilten Takt, oder nicht?

Ja. Aber: CTC Modus! OCR2 ist TOP. D.h alle 40 Takte (*) ein Overflow.

(4 Mhz bedeutet einen Timertick alle 0.25µs, nicht 2.5µs. Du hast dich 
im Komma vertan)

* eigentlich 41. Aber lass uns nicht kleinlich sein :-)

von STK500-Besitzer (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:

> (4 Mhz bedeutet einen Timertick alle 0.25µs, nicht 2.5µs. Du hast dich
> im Komma vertan)

ja, das Komma war geraten.
Die Kommentaren sind fürn Popo.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.