Maker Pro
Maker Pro

PIC12f1501 used to turn a servo

wingnut

Aug 9, 2012
255
Joined
Aug 9, 2012
Messages
255
Hi all

Could you maybe tell me why the following code (which compiles fine) will not rotate the servo.

Below is the code.

//1501Servo
#define _XTAL_FREQ 16000000
#include <xc.h>

#pragma config CLKOUTEN = OFF
#pragma config WDTE = OFF // or control in software - SWDTEN
#pragma config PWRTE = OFF
#pragma config CP = OFF
#pragma config BOREN = OFF
#pragma config MCLRE = OFF
#pragma config FOSC = INTOSC

#pragma config STVREN = ON
#pragma config LPBOR = OFF
#pragma config BORV = LO
#pragma config LVP = OFF
#pragma config WRT = ALL // we don't need self write
#include <stdlib.h>
#include <stdint.h>

void main(void)
{
int n;
TRISA = 0; // PORTA as Ouput Port
do
{
for( n=0; n<50 ;n++)
{
PORTA = 0xff; //switch pin on for 2 ms
__delay_ms(2);
PORTA = 0; //switch pin off for 18 ms
__delay_ms(18);
}
for(uint8_t n=0; n<50;n++)
{
PORTA = 0xff;
__delay_ms(18); // switch pin on for 18 ms
PORTA = 0; // switch pin off for 2 ms
__delay_ms(2);
}

}while(1);
}

A LED attached to the output pins alternately brightens and darkens, each brightening and darkening taking one second each.

When I connect the data lead of the servo to the pin in place of the LED, nothing happens.

I think I have the correct frequency of 50HZ for the servo which is an analog Turnigy TG9.

The servo purrs but it does not rotate rhythmically clockwise and anti-clockwise as expected.

Thank you
 
Last edited:

Arouse1973

Adam
Dec 18, 2013
5,178
Joined
Dec 18, 2013
Messages
5,178
Looking again at your code you are switching on for 18 ms and off for 2 ms, this is wrong. You only need one loop. If you want to make it go back and forth you need to try this. Set out for 1 ms on delay 18 ms .....do 50 times, set out for 1.5 ms on delay 18 ms....do 50 times, set out for 2 ms on delay 18 ms do 50 times and then repeat.

Adam
 

wingnut

Aug 9, 2012
255
Joined
Aug 9, 2012
Messages
255
Looking again at your code you are switching on for 18 ms and off for 2 ms, this is wrong. You only need one loop. If you want to make it go back and forth you need to try this. Set out for 1 ms on delay 18 ms .....do 50 times, set out for 1.5 ms on delay 18 ms....do 50 times, set out for 2 ms on delay 18 ms do 50 times and then repeat.

Adam

Thank you very much Adam and all.

You are quite right about having the small pulse widths with a 18ms low period between. I was mistaken thinking that a close to 100% duty cycle was required to rotate it the other way.

My other mistake was not knowing that its default frequency is 500 000Hz.

And lastly, I needed a better battery pack than my 4 ageing AA batteries to power both PIC and servo. It was browning out, resetting and shivering without the better power supply.

Its working great now.

Thanks once again all for such prompt help. :)

Here is the working code.
It does not use PWM.
The PIC12f1501 has 8 pins, and the data cable can be attached to any one of the 5 A register pins.

//1501Servo
#define _XTAL_FREQ 500000
#include <xc.h>

#pragma config CLKOUTEN = OFF
#pragma config WDTE = OFF // or control in software - SWDTEN
#pragma config PWRTE = OFF
#pragma config CP = OFF
#pragma config BOREN = OFF
#pragma config MCLRE = OFF
#pragma config FOSC = INTOSC

#pragma config STVREN = ON
#pragma config LPBOR = OFF
#pragma config BORV = LO
#pragma config LVP = OFF
#pragma config WRT = ALL // we don't need self write
#include <stdlib.h>
#include <stdint.h>

void main(void)
{
int n;
TRISA = 0; // PORTA as Ouput Port
do
{
for( n=0; n<50 ;n++)
{
PORTA = 0xff; //switch pin on for 1 ms
__delay_ms(1);
PORTA = 0; //switch pin off for 19 ms
__delay_ms(19);
}
for( n=0; n<50 ;n++)
{
PORTA = 0xff;
__delay_ms(2); // switch pin on for 2 ms
PORTA = 0; // switch pin off for 18 ms
__delay_ms(18);
}

}while(1);
}
 
Last edited:

Bluejets

Oct 5, 2014
6,922
Joined
Oct 5, 2014
Messages
6,922
General rule of thumb.
Do not power micro and servo from the same supply.
 
Top