Society of Robots - Robot Forum
Software => Software => Topic started by: junior000 on January 13, 2008, 07:02:35 AM
-
hi i am using a pic 18f4550 microcontroller.
can anyone post source code for controlling a servo motor.
-
Which language are you using?
-
i am using c language...c18 compiler
and the microcontroller is 18f4550
-
All the servo code is doing is the following
Pause 150 milliseconds ( to make it center)
make the servo signal high
make it low
Loop it 3 times
-
include the standard "Delays.h" into the top of your code
then something like:
include <pic.h>
include<Delays.h>
//////////////////////////
//add fuse bit settings here
/////////////////////
define SERVO1 PortDbits.rd0 // connect servo to rdo
TRISD = 0b00000000;
SERVO1 = 0; //make sure servo port start low
void move_servo(unsigned int duty);
void main(){
while(1){
move_servo(163); //163 is value for center at 10Mhz - adjust as necessarry
//at 10mhz 200 is 45deg left and 125 is 45 degrees right
//double these values for 20Mhz
//you could try using something to convert degrees into the timing units
//if you like
}
}
void move servo(unsigned int duty){
SERVO1=1;
Delay10TCx(duty); //delay 10 instruction cycles for each int +1 value
Delay10TCx(duty);
SERVO2=2;
Delay100TCx(200); //delay 20000 instruction cycles
Delay100TCx(200);
}
I'm currently working with the PIC18 series so if you get stuck with anything I will probably be able to help.
One quick tip: Always keep the LVP fuse bit as off if possible because this causes erratic behaviour including erasing your code if you touch the top of the PIC?
-
Pause 150 milliseconds ( to make it center)
make the servo signal high
make it low
Loop it 3 times
or like this:
make the servo signal high
Pause 150 milliseconds ( to make it center)
make it low
Loop it 3 times
-
or like this:
make the servo signal high
Pause 150 milliseconds ( to make it center)
make it low
Loop it 3 times
oops I made a mistake, yeah thats what I meant......
-
Here is my idea which uses timers allow a servo from every digital I/O pin.I am assuming the MCU is running at 12MIPs (12 instructions per uS)
The position of the servos are stored in an array of integers. Each element in the array is 0-100, 0 being -90o degrees, 100 being +90o. The number really represents how many 10s of microseconds more than 1 millisecond you want the pulse to last.
EG servoPosArray[4] = 25 means that the pin controlling servo 4 would give out pulses that are 1ms + 25*10 uS = 1.25 mS long.
1) Turn on all of the I/O pins.
2) Delay for 1ms.
3) Set a timer going.
4) Set up a while loop like this -
while(1) {
if (servoPosArray[1] < (timer0.value/120)) //Has enough time passed to turn off pin controlling servo 1?
pinForServo1 = 0;
if (servoPosArray[2] < (timer0.value/120)) //Has enough time passed to turn off pin controlling servo 2?
pinForServo2 = 0;
if (servoPosArray[3] < (timer0.value/120)) //Has enough time passed to turn off pin controlling servo 3?
pinForServo3 = 0;
...
if (servoPosArray[n] < (timer0.value/120)) //Has enough time passed to turn off pin controlling servo n?
pinForServon = 0;
if((timer0.value/120) > 110) //Every pin should have been turned off by this time. But there is probably some better way to exit the loop.
break;
}
Then all of the I/O pins will be turned off.
5) Now you have about 20ms to do stuff like receive inputs and change the servo position values accordingly.
6) Start again.
That code won't work if you compile it, i just guessed with some of the terms, but it should be understandable. Its a kinda half pseudocode :D
-
yep....its helpfull...tnx:-)