PDA

View Full Version : ESC control with PIC16f877A



chintoo
04-22-2011, 06:53 PM
Hello everyone!
This is the first time i'm dealing with brushless motors. I plan to control it using a PIC (16f877A is what i have with me). I got the esc from http://www.nex-robotics.com/products/quadrotor/25a-bldc-motor-driver.html . Now, when i tried it the first time the ESC did give some beeps but didn't drive the motor. But it has stopped responding altogether now. The code i'm using is here:


#include <htc.h>

__CONFIG(CP_OFF & DEBUG_OFF & WRT_OFF &CPD_OFF & LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_LP) ;

//DEFINE CRYSTAL FREQ
#define _XTAL_FREQ 32768


void main(void)
{ CMCON = 7;
PORTB = 0; //RESET PORTB PINS
TRISB = 0b11111100; //RB1:RB0 AS OUTPUTS

RB0 = 0;
RB1 = 1; //working LED On

PORTC = 0; //set RC2 for PWM
TRISC2 = 0;
PR2 = 0b10100000; //50.88Hz PWM @32.768kHz
T2CON = 0b00000100; //T2 on with 1:1 prescaler
CCPR1L = 0b00001000; //1msec pulse width
CCP1CON = 0b00001100; //set PWM

while(1)
{
if(0 == RB2)
{ CCPR1L = 0b00001100; //set pulse width = 1.5msec
RB1 = 0;
}
else
{ CCPR1L = 0b00001000; //stop bldc
RB1 = 1;
}
}
}

The code has been compiled using hitech-picc
I've checked using a simple LED at CCP1 (RC2) and it brightens up when RB2 is grounded ('working LED' at RB1 is switched off at the same event). I also checked the servo connector of the ESC which gives the 5V output as expected.
Anything i'm doing wrong?
Also, how do i check if the esc is still working and has not gone bad? (i dont have a radio)

Hoping to get a quick solution so that i can do something worthwhile this long weekend!

chintoo

allbits
04-22-2011, 07:27 PM
Interfacing with the microcontroller:
If you are driving the BLDC motor driver with the microcontroller then give out 1mS pulse
width at 50-60Hz at the beginning which corresponds to zero throttle. Turn on the BLDC
motor driver. Wait for about a second. Give 1mS pulse width at 50-60Hz which corresponds
to zero throttle. Wait for 5 seconds. Now you can change pulse width between 1mS to 2mS at
50-60Hz to control throttle of the BLDC motor.


This is from the product manual, which is at

http://www.nex-robotics.com/images/downloads/25A%20BLDC%20Motor%20Driver%20Product%20Manual%202 011-02-10.pdf

Hope you have gone through that. 16F877a cannot give you refresh rates at 50Hz, if you are using PWM. Use timer interrupts. Dont use the CCP modules. Once you have generated the wave, check it with an oscilloscope. Then interface with the controller.

chintoo
04-22-2011, 07:53 PM
Thanks allbits
I did check the manual before starting. I plan to use timer interrupts too. Just couldn't try it out yet.
And as far as capability of 877A for generating 50Hz signal is concerned, I think you missed out the cryctal freq. i'm operating the 877A is. I'm doing it at 32.768kHz. i checked the online pwm calculator too to cross check.
And, i dont have an oscilloscope. For that, i plan to work around by using another PIC to check the output from CCP1.

chintoo
04-25-2011, 11:16 PM
@all
bhaio!
koi hai jawaab dene wala??
i thought of getting some good help here! :(
anyways, any work arounds to check the esc?? (i think the PIC code is working fine)

confused
chintoo

allbits
04-25-2011, 11:31 PM
I did check the manual before starting. I plan to use timer interrupts too. Just couldn't try it out yet.
And as far as capability of 877A for generating 50Hz signal is concerned, I think you missed out the cryctal freq. i'm operating the 877A is. I'm doing it at 32.768kHz. i checked the online pwm calculator too to cross check.
And, i dont have an oscilloscope. For that, i plan to work around by using another PIC to check the output from CCP1

Were waiting for your plans to finish, and to see the results of your plans.

If you have a servo motor, connect it and see if the servo is moving acording to the pulse.
I have not worked with a 32khz crystal along with a ccp module. Anyways, 1-2 ms at 50 Hz is a difficult signal with a ccp because the duty cycle is too low, so the amount of resolution available will be less for a frame of 1ms. Anyways do the math and double check the pulse out. Some DMMs have frequency and duty cycle readout , check the waveform with that.

chintoo
04-30-2011, 01:52 AM
Hey allbits!
thanks for the reply and sorry for the late rep. was busy through the week. anyway, unfortunately enough, i dont have a servo motor or an oscilloscope and have not been able to output the readings on the lcd! all going haphazardly for me!
As far as the PWM resolution is concerned, its (log(32768/55)/log(2)) = 9bits approx. which is good enough (?)
I've been trying to send the readings from the second pic to pc by serial port (i have a virtual rs-232 on my laptop, http://probots.co.in/index.php?main_page=product_info&cPath=67&products_id=212)
i took up the usart files from HiTech PICC samples to test it. Have got no clue whats happening!
Is it possible that the usb-serial converter i'm using supports only one way comm. i'e PC to PIC??

This PIC has been not better than just blinking LEDs for me!
x-(

edit- i checked at http://www.embeddedrelated.com/groups/piclist/show/9797.php . I'm getting echo from male db9 on usb -to-serial and max232 5V side. PIC code prob then! :(

chintoo
05-01-2011, 11:29 PM
Got it working!
:) just too happy!
thanks allbits... Finally i figuered things out with the PICkit2 logic tool. I told you i'm new... so didn't know something like this even existed. anyways, its all working!
thanks again...

chintoo

CHulla
08-20-2012, 09:56 PM
Hi chintoo
can you share the code that worked?

chintoo
08-22-2012, 08:59 AM
CHulla
it's been long since i last played with controllers. Will have to dig-out the code from the backup i made. will try.

chintoo
08-22-2012, 02:22 PM
here you go... (I've added comments for easy understanding)



/*
** Code for generation of PWM for motor esc
** PIC16F877A, HiTech PICC 9.81
** April, 2011
*/


#include <htc.h>

__CONFIG(CP_OFF & DEBUG_OFF & WRT_OFF &CPD_OFF & LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_LP) ;

//DEFINE CRYSTAL FREQ
#define _XTAL_FREQ 32768

//INITIALISE VARIABLES
//int i;

void main(void)
{ CMCON = 7;
PORTB = 0; //RESET PORTB PINS
TRISB = 0b11111100; //RB1:RB0 AS OUTPUTS

RB0 = 0;
RB1 = 1; //working LED On

PORTC = 0; //set RC2 for PWM
TRISC2 = 0;
PR2 = 0b10010100; //54.98Hz PWM @32.768kHz
T2CON = 0b00000100; //T2 on with 1:1 pre and post scaler
CCPR1L = 0b00001000; //1msec duty cycle
CCP1CON = 0b00001100; //set PWM and write 2-lsb of duty cycle

while(1)
{
if(0 == RB2)
{ CCPR1L = 0b00001100; //drive bldc
RB1 = 0;
}
else
{ if ((0 == RB2)&&(0 == RB3))
{ CCPR1L = 0b00001111; //drive hard!
RB1 = 0;
}
else
{ CCPR1L = 0b00001000; //stop bldc
RB1 = 1;
}
}
}

}