Society of Robots - Robot Forum
Software => Software => Topic started by: superchiku on April 03, 2008, 10:45:37 AM
-
i decided to use the delay cycles method for my servo manupulation since the hardware timers can never give me exact 1-2 ms delay, but it seems that no matter how much i turn the loop , it never goes below a voltage o/p of 0.87 v : i mean i am not able to get complete blinking of the led , it just glows low so iam not able to calculate the exact delay for 1-2 ms for my servo , my code is like this
# include<avr/io.h>
# include<stdio.h>
int main()
{
unsigned long int a,b;
DDRC=_BV(0);
while(1)
{
PORTC=0x01;
a=600000000;
while(a>0)
{
b=600000000;
while(b>0)
{
b=b-1;
}
a=a-1;
}
PORTC=0x00;
a=600000000;
while(a>0)
{
b=600000000;
while(b>0)
{
b=b-1;
}
a=a-1;
}
}
return(0);
}
u see the values of the variables i have set for a and b , but still no blinking iam using atmega16 mcu with 8mz internal oscillator . PLZZZ HELP
-
Did you set the direction registers correctly? The only time that happened for me is when I forgot to set the DDR register and the pin was floating.
BTW, you won't be able to notice a 2 ms delay and the led will just look slightly dull in color.
-
man those mistakes are made by beginners didnt u see the code its clearly written DDRC|=_BV(0)
-
man those mistakes are made by beginners didnt u see the code its clearly written DDRC|=_BV(0)
yeah I saw that later. Maybe it is working and you just can't perceive a 500hz signal.
It only glows faintly because it is at half duty cycle I suspect.
-
well so what do u recommend i do
-
If you don't have a scope, you probably can't read exactly the frequency you have.
I've been using 16 bit timers with interrupts. In the handler just compute the cycles you need for 1 ms and set that as the delay till next interrupt, and increment a global counter every interrupt. It is really accurate for me.
To set the delay, just load the timer register with 2^16-(number of cycles to delay) and wait for the interrupt.
-
i was thinking of following that procedure but u see by that i cnat get exact 1 ms , so thats the problem and also even if i give that much no of cycles still after giving that much pulse , i have to delay another 20 ms for the serco to be off , how do i do that
-
Your hardware timer should be just as accurate as delay cycles, since they run off the same clock. I don't have AVR code handy, but I got some PIC C code. You should be able to figure out what to do.
Sample code attached.
This was running at 4MHz on a pic (/4 = 1ms per instruction). If you're running at 8MHZ on the avr, the 16 bit timer isn't long enough, so have the 16 bit timer count 1ms, and use another variable to keep track of the current time in ms.
Here is the gist of it
void interrupt(void)
{
if(PIR1&1) //timer1 overflow
{
if(state==1) //it was high
{
PORTC=0; //bring it to low
state=0;
time=45535+pulseLength;
TMR1L=Lo(time);
TMR1H=Hi(time);
state=0;
}
else
{
PORTC=1;
time=65535-pulseLength;
TMR1L=Lo(time);
TMR1H=Hi(time);
state=1;
}
PIR1=(PIR1&0b11111110);
}
}
-
well ill try ur method using avr's harware timer and see wat happens
-
You can also make the servo move by using delays without hardware timers, just Turn the ports on, delay for 1ms, turn ports off, delay for 19ms.
-
take a look at the arduino servo library how it uses the timer to time the servo so you'll get an ideea maybe you want to implement it in your mega16 or better yet take a look at lary barello c code for mega16
-
iam really getting problems controlling this servo is the wiring correct?