Society of Robots - Robot Forum
Electronics => Electronics => Topic started by: superchiku on April 03, 2008, 01:28:23 PM
-
i really got a big problem controlling my servo , ill say whatevr ihave done with it
connected power to red wire,
ground to brown wire,
signal to orange wire
the code of my program is like this (it is going to take the servo to 90 degrees)
#include <avr/io.h> //for 8mhz internal oscillator controlling servo by centering it
#include <avr/interrupt.h>
unsigned int i=0;
int main (void)
{
DDRC |= (1 << 7); // Set LED as output
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
sei(); // Enable global interrupts
TCCR1B |=(1<<CS12); // Start timer at Fcpu/256
for(;;);
}
ISR(TIMER1_COMPA_vect)
{
if(i==1)
{
PORTC&=~(1<<7);
OCR1A=625;//give 20ms delay after the servo is given no signal
i=0;
}
if(i==0)
{
PORTC|=(1<<7);
OCR1A=47;//bring servo to the centre by giving nearly 1.5 ms delay
i=1;
}
}
my problem is that the servo only twitches when i turn on the mcu if i keep turning thhe mcu on and off, the servo twitches from left to right and from right to left, Please tell me what is the problem...
-
It sounds like a timing issue.
Shouldn't the delay when i==1 be 580cycles(18.5ms) because you already delayed 1.5ms before? I don't know if that actually matters, but it is the only thing I can think of.
-
well i tried that too , it just doesnt work is my wiring correct
-
sorry man your programming is chinese for us regular programmers that is why i said i should get back to basic there anyone understands even without commenting
-
well man i really need to control the servo coz without that my project is doomed , even if i use a simpler code like this it still only twitches and doesnt give required rotation , plzz rectify coz ive never controlled servos bfore..
#include<avr/io.h>
#include<util/delay.h>
int main(void)
{ DDRC|=_BV(7);//set pin7 of portc as o/p
while(1)
{
PORTC=0x10; //turn on pin7
_delay_us(1100); //delay 1.1ms to bring the servo to extreme left
PORTC=0x00;//turnoff pin7
_delay_us(1100);//delay another 1.1ms
_delay_ms(19); //delay 19 ms for giving out 50 hz frequency
}
return(0);
}
-
first what is the pin number for the port c where the servo is connected I mean not the device pin number but which one of the 8 pins of the port is it then in the while true loop you have a 1.1 ms delay for the on time of the pulse then another 1.1 ms for off time and another 19 ms off time this is wrong you should have only one 1.1 ms on time and one 18.9 off time to total 20 ms cycle when you tell me exactly the pin number i'll let you know if there are other problems or not
-
its pin no 7 of port c pllz try to see if there are errors
-
I made some minor changes to your code because I can't find a PC7 on the ATMega8, but it works.
I tried this on an ATMEGA8@16MHz (external crystal) controlling a hitachi HS-325HB servo at 5V.
#include<avr/io.h>
#include<util/delay.h>
int main(void)
{ DDRC|=_BV(0);//set pin0 of portc as o/p
while(1)
{
PORTC|=1<<PC0; //turn on pin0
_delay_us(1100); //delay 1.1ms to bring the servo to extreme left
PORTC&=~(1<<PC0);//turnoff pin0
_delay_ms(19); //delay 19 ms for giving out 50 hz frequency
}
return(0);
}
-
szhang responded to your question a lot nicer than I could have done it
PORTC=0x10; //turn on pin7
now I have a question: is 0x10 the same thing as 0b10000000 ? as far as I know, pin 7 of port C is the last bit of the 8 bit port (it starts at 0,1,2,...,7, for a total of 8 bits) perhaps this was your mistake... I allways use binary or decimal instead of hex cause it's getting confusing
-
oops that was the mistake it should be 0x80 coz 8 in decimal equals 1000 in binary and 0=0000 could u test this code with the revised values of port c also can u plzz test anothr code which i have made which will rotate the servo from left to right and right to left
#include <avr/io.h> //for 8mhz internal oscillator controlling servo by centering it
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 8000000
int main (void)
{
DDRD |= _BV(5); // Set PORTD5 as output
DDRC =0x01;
TCCR1B |= (1 << WGM13); // phase and frequency correct mode
ICR1=10000;
TCCR1A|=(1<<COM1A1);//clear oc1a when upcounting and set Oc1a while downcounting
TCCR1B |=(1<<CS11); // Start timer at Fcpu/8
PORTC=0X01;
while(1)
{
for(OCR1A=500:OCR1A<=1000;OCR1A++)
{
_delay_ms(1);
}
return(0);
}
just change ur internal clock to 8mhz and jtag disable with atmega16 plzz do try the code
-
i got the problem , the problem was with the servos my servo requires a pulse of 0.5 to 2.6 ms ,now it works cool ,just i need to add a bigger capacitor to the circuit, the servo draws a lot of current and the led bcomes dim while the servo is rotating
-
my servo requires a pulse of 0.5 to 2.6 ms
what kinda servo is that?
i have the hitec hs-322hd and its range is 0.690 to 2.385 ms
where did you add the bigger cap? at the input (power) ,right?
-
yes yes and also added a capacitor across the vcc and gnd of the servo