Hi,
inzwischen hab ich es hingebekommen mit den 0.1ms!
Um den Servo(den von Robotikhardware) ganz nach links zu bewegen brauch ich 6 Takte = 0.6ms undnach rechts die 20 Takte = 20ms!
ist das normal??
Gruß Michi
Druckbare Version
Hi,
inzwischen hab ich es hingebekommen mit den 0.1ms!
Um den Servo(den von Robotikhardware) ganz nach links zu bewegen brauch ich 6 Takte = 0.6ms undnach rechts die 20 Takte = 20ms!
ist das normal??
Gruß Michi
Das ist auch etwa das, was ich brauche. Man müßte natürlich die Zeitdifferenzen durch die Maschinenbefehle berücksichtigen, die vom Timer --> Pulseoff noch verstreichen. Aber was soll's. irgendeine Zahl ist links und eine andere ist rechts. Von der objektiven Zeit hab ich ja nix.
Hi Picnick,
mit den Takten mein ich die Interrupts also nach 6 Interrupts 6ms usw.!
Ja die Befehle verbrauchen sxchon ein paar Takte aber die will ich jetzt mal hinterrücklings lassen!
Mein aktueller Code:
ich kann jetzt zwar wenn ich jetzt den Servo nach links stellen will einfach vor dem alles was nach case 5: kommt ein // setzen damit er nach linkns fährt, aber will jetzt dass ich einfach sag z.B. Servo 90 und er fährt zur Mittelstellung!! da muss ich wohl noch ein paar Funktionen einsetzen!!Code:
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <math.h>
volatile unsigned char servowert;
volatile unsigned char puls;
volatile unsigned char zaehler;
int set_servo(volatile uint8_t pos)
{
servowert = (pos/180) + 1;
}
int main(void)
{
zaehler = 0;
sei();
DDRB = (1<<PB0);
PORTB = (1<<PB0);
//Timer0 Prescaler 64
//1600000Mhz hat der µC
//0.0000000625s zischen den Takten
//mit Prescaler: 0.000004s zischen den Takten
//0.0001s/0.000004s = 25
//Preloadwert: 231 <= 256-25
//Zeit zwischen Interrupt 0.1ms
//1ms = 10 Takte
//1.5ms = 15 Takte
//2ms = 20 Takte
//20ms = 200Takte
//da erster Takt = 0
//nach 9 Takten low
//nach 199 Takten high!
TCCR0 = (1<<CS01)|(1<<CS00);
TCNT0 = 231;
TIMSK |= (1 << TOIE0);
for(;;)
{
}
}
SIGNAL(SIG_OVERFLOW0)
{
switch(zaehler)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: //Links
case 6:
case 7:
case 8:
case 9: //1ms
case 10:
case 11: //Mitte
case 12:
case 13:
case 14:
case 15://1.5ms
case 16:
case 17:
case 18:
case 19: //2ms //rechts
PORTB |= (1<<PB0);
zaehler++;
break;
case 199:
zaehler = 0;
break;
default:
PORTB &= ~(1<<PB0);
zaehler++;
break;
}
TCNT0 = 231;
}
Gruß Michi
Hi Leute!
Ich bin auch gerade dabei eine Servoansteuerung zu proggen.
Komme bei einer Ansteurung von 1-2ms allerdings bei weitem nicht an die Endanschläge.
Habe kein Oszi kann also nicht die exakten Zeiten messen.
Wie sind eure Erfahrungen so?
(Ich nutze billig Servos)
Von der Hardware her nutze ich:
Atmega8 mit 16Mhz.
Prescaler 64 -> TCNT0 mit 6 initialisiert = 1ms
Um den rechten Rand zu erreichen muss ich TCNT0 mit 255-160 initialisieren.
Um den linken Rand zu erreichen müsste ich TCNT0 mit 255 - 580 inititalisieren, was ich durch mehrfaches aufrufen erreiche.
Ist bei meiner Rechnung etwas falsch, oder ist das normal?
mfG
Batti
Allen noch einen frohen Feiertag!
Hi,
als bei mir variieren die Zeiten auch! bei dem Servo von www.robotikhardware.de bentötige ich um den Servo nach ganz links zu drehen 0,6ms und nach rechts 20ms!
Ich denk mal sowas ist normal wegen den Fertigungstoleranzen!
Gruß Michi
Danke Michi!
Hab mir schon sowas gedacht...
Trotzdem wundert es micht, da ja auch die Fernsteuerungsanlagen mit den billig Dingern zurecht kommen müssen...
mfg
Batti
Hallo leute,
ich habe diesen Thread genau gelesen und versucht auch alles so zu machen wie du (michaelb)! Aber leider passiert bei mir gar nix!
Vielleicht noch was zu meinem Aufbau: ich hab meinem Servo an einem Mega32 und nicht am PortB sonder am PORTD.7 (Pin21)! Ich hab euch auch mal meinen Code mitgepostet, wo ich alles geändert habe wovon ich denke, dass ich es ändern muss! Ich hoffe ihr habt eine Idee warum es bei mir nicht geht!
Danke für eure AntwortenCode:#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <math.h>
volatile unsigned char servowert;
volatile unsigned char puls;
volatile unsigned char zaehler;
int set_servo(volatile uint8_t pos)
{
servowert = (pos/180) + 1;
}
int main(void)
{
zaehler = 0;
sei();
DDRD = (1<<PD7);
PORTD = (1<<PD7);
//Timer0 übernimmt die Highphase
//muss 1ms sein also 25 Takte bei einem Prescaler von 64
puls = 6;
TCCR0 = (1<<CS21) | (1<<CS20);
TCNT2 = (255-puls);
TIMSK = (1<<TOIE2);
for(;;)
{
}
}
SIGNAL(SIG_OVERFLOW2)
{
if(zaehler == 0)
{
PORTD &= ~(0<<PD7);
TCNT2 = (255-puls);
zaehler++;
}
else if ( (zaehler > 0 ) && (zaehler < 20 ) )
{
TCNT2 = (255-puls);
zaehler++;
}
else
{
TCNT2 = (255-puls);
zaehler = 0;
PORTD = (1<<PD7);
}
}
Matic
Hi,
ich finde in deinem Code folgende Fehler:
>TCNT2 durch TCNT0 erstetzen da du den Timer0 benutzen tust!
>puls = 6 wie kommt du darauf? Ersetz das mal durch puls = 25
>warum setzt du das Bit TOIE2? Für Timer0 brauchst du doch TOIE2!
ok wenn du den Timer2 nutzen willst dann brauchst du schon TCNT2 und TOIE0 aber dann muss du die entsprechenden Bits im TCCR2 setzen statt im register TCCR0! wenn du nämlich diese Bits nicht setzen tust dann arbeitet der Timer gar nicht!!
Gruß Michi
Hi,
so jetzt habe ich endlich zeit gehabt um deine Fehler zu korrigieren:
Aber leider tut sich immer noch nichts! Ich weiß nicht woran es liegen kann! Naja vielleicht könnt ihr ja was im Quellcode finden! Danke für eure hilfe!Code:#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <math.h>
volatile unsigned char servowert;
volatile unsigned char puls;
volatile unsigned char zaehler;
int set_servo(volatile uint8_t pos)
{
servowert = (pos/180) + 1;
}
int main(void)
{
zaehler = 0;
sei();
DDRD = (1<<PD7);
PORTD = (1<<PD7);
//Timer0 übernimmt die Highphase
//muss 1ms sein also 25 Takte bei einem Prescaler von 64
puls = 25;
TCCR2 = (1<<CS21) | (1<<CS20);
TCNT2 = (255-puls);
TIMSK = (1<<TOIE0);
for(;;)
{
}
}
SIGNAL(SIG_OVERFLOW2)
{
if(zaehler == 0)
{
PORTD &= ~(0<<PD7);
TCNT2 = (255-puls);
zaehler++;
//PORTB = (0<<PB0);
}
else if ( (zaehler > 0 ) && (zaehler < 20 ) )
{
TCNT2 = (255-puls);
zaehler++;
}
else
{
TCNT2 = (255-puls);
zaehler = 0;
PORTD = (1<<PD7);
}
}
matic
Hi matic,
also ich hab folgende Fehler gefunden:
>ändere das:
in dasCode:TCCR2 = (1<<CS21) | (1<<CS20);
um damit du den Prescaler von 64 hast!!! Datenblatt lesen!Code:TCCR2 = (1<<CS22);
>das
kann nicht stimmen!!Code:TIMSK = (1<<TOIE0);
das muss:
heißen den du verwendest ja den Timer2!Code:TIMSK = (1<<TOIE2);
TOIE2 = Timer Overflow Interrupt Enable für den Timer2!
Gruß Michi