CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

16F684 DC motor control help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

16F684 DC motor control help
PostPosted: Sat Jun 02, 2012 11:42 am     Reply with quote

Hello

Hardware: 16F684

I have 2 buttons and I would like to give PWM, EN (Enable) and DIR(direction) to a motor driver to control the direction of my DC motor. What I want to do is from the buttons to give Start/Stop and change direction of the motor rotation.
What I want to is to capture also from a Hall Sensor the impulses given from the motor magnet (read the rotations period).
I have finished the schematic for all of this the only problem remains the programming of the PIC. I have looked thru the internet for examples and ways to do this. Found some and programing it thru CCSc in C made me thinks is the easiest way to do it.

This is what i wrote so far for my code. Still searching to add new things like debouncing or else. If someone has some ideeas the help would be welcomed.

The Start/Stop button is located on A0 pin
Direction button on A1
Enable output on C0
Direction output on C1
and PWM output on CCP1

Code:

#include <16F684.h>
#fuses HS,NOWDT,NOPROTECT

#INT_EXT             
void INT0isr() {
   output_low(PIN_C0);      
}

void main() {   
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_125KHZ);
        setup_timer_2(T2_DIV_BY_1, 127, 1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(40);

while( TRUE ) {
    if (input(PIN_A1) == 0) output_high(PIN_C1);
      else output_low(PIN_C1);
       {    
   if (input(PIN_A0) == 1) output_high (PIN_C0);
         }
   }
}


Last edited by ciudatelul on Sun Jun 03, 2012 2:00 am; edited 1 time in total
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Jun 02, 2012 3:13 pm     Reply with quote

Quote:
The Start/Stop button is located on A0 pin
Direction on A1
Enable on C0
Direction on C1
and PWM on CCP1

You've got direction twice. I presume you mean:-

Direction button on A1.
Direction control on C1.

How are you then using C1 to control the direction?
Can we assume you've got an appropriate power driver for the motor?

Code:
   if (input(PIN_A0) == 1) output_high (PIN_C0);
Why not use an else to stop the motor, rather than the interrupt.

Why do you need C0 as an enable output?
Can't you simply turn the PWM on and off?

You made need a fuse to tell the system you're using the internal oscillator.

Code:
   setup_oscillator(OSC_125KHZ);
Why are you using such a low frequency clock?

Code:
   setup_timer_2(T2_DIV_BY_1, 127, 1); 
And then PWMing your motor at ~1kHz.
The noise from the PWM will be dreadful.

Mike
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 1:59 am     Reply with quote

Yes it's correct. A1 is for the button and C1 is for control of the direction.
The motor driver is an appropriate one (L9904). It has 1 input for PWM, 1 for Enable and 1 for direction.

The direction is changed by input high or input low on the driver pin.
The PWM freq I wanted to apply is of 20 kHz.
The motor driver has 1 pin of Enable and I wanted to control the on/off of the motor by controlling the input on that pin.

I have added for the use of internal OSC
Code:

#fuses HS,NOWDT,NOPROTECT,INTRC_IO

And using the microchip reference manual for CCP module
http://ww1.microchip.com/downloads/en/DeviceDoc/31014a.pdf
i set up the internal osc at 8 MHz and here is the code for PWM and some minor modification

Code:
#include <16F684.h>
#fuses HS,NOWDT,NOPROTECT,INTRC_IO
#use delay( internal=8M )

#INT_EXT             
void ext_isr() {
   EXT_INT_EDGE(H_TO_L);
      output_low(PIN_C0);      
}

void main() {   
      enable_interrupts(INT_EXT);
      enable_interrupts(GLOBAL);
      setup_oscillator(OSC_8MHZ);
        setup_timer_2(T2_DIV_BY_1, 99, 1);
      setup_ccp1(CCP_PWM);
      set_pwm1_duty(200L);
while( TRUE ) {
    if (input(PIN_A1) == 0) output_high(PIN_C1);
      else output_low(PIN_C1);
delay_ms(10);
       {    
   if (input(PIN_A0) == 1) output_high (PIN_C0);
delay_ms(10);
         }
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 8:21 am     Reply with quote

Comments:

1) Only select _one_ oscillator. Currently you have two - HS, and INTRC_IO. This is invalid, and will give unexpected results.
2) Do some reading on PWM. Higher frequency, allows smaller magnetics/capacitors, but increases switching losses, and requires higher current to drive the FET gates. 1KHz, is too low for a DC motor (noise), but 20KHz, is pushing the other end of the range, risking heating problems. Look at using the sort of frequencies other people use for the same application (most of them know what they are doing).
3) Remember that anything inductive, has significant energy when it is switched off. You have got trap diodes on your FETs?.
4) Worse though anything mechanical like a motor, also has significant mechanical energy present, which acts like a generator, when you switch off the FETs. Remember your trap circuitry needs to handle this, and you need to allow time, ramping the drive down, not just thumping it on/off, when you want to change direction.

Best Wishes
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 9:09 am     Reply with quote

Oh. Thank for the reply.
I modified and selected one oscilator.
The schematic i made is inspired from this kind of circuit . The motor driver(L9904) is a full bridged one. It suports PWM freq up to 30 KHz with FET`s that have trap diodes. Anyway i believe that for a small DC motor smaller freq would do to and i will change it. I still have to add some things in my code but still i get stuck . Anyway i apreciate any comments and help given it makes me understand better what i do and what i have to do .
Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 9:32 am     Reply with quote

I know the L9904, is rated to operate to 30KHz max, _but_ that is a chip limit, which in practice, is limited by the drive current into the FET's. Remember as FET's get bigger, their input capacitance rises. You need to sit down and look at your specific FET's, and what their input capacitances are, and what switching time this will give within the limits of the drive capability of the IC, and the total current this will require. Unless you are using very small FET's you may be surprised at how slow the switching becomes, and hence how much the power losses rise.
Don't rely on the internal diodes in the FET as 'trap diodes', _unless_ you specifically choose FET's that have proper diodes built in. _All_ FET's behave as diodes when reverse biased, _but_ the diodes this gives have much lower ratings than the FET itself, poor recovery times, and quite severe losses. Only a few very specifically designed FET's actually have separate diode structures deliberately built in (Hitachi for example do a range like this), and relying on the internal diodes, when they are not designed for the job, is a very quick way to kill your FET's....

Best Wishes
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 10:56 am     Reply with quote

The FET that I'm using is IRFR4104.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 1:09 pm     Reply with quote

Working above 20kHz is not, of itself, a problem. The great advantage is that it's ultrasonic. Hard switching power supplies at the kW level have routinely operated ultrasonically for over quarter of a century. The size reduction more than offsets the higher silicon losses. Getting ALL the right components in place is not trivial, but it can, and is done.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 2:40 pm     Reply with quote

Have a look at AN-944 from IR, about the drive requirements - depends on the actual voltage you are driving.
These look quite nice FET's, but the internal diodes have a fairly large forward voltage, so if significant generation takes place as you switch off the drive, there may be significant heating here. They are though properly rated for use as the inductive overshoot diodes.
Agree wholeheartedly about power drive being possible at high frequencies (last project involving this, I did a few months ago, was over 80KW, switching at 150KHz - with a PIC), but it is common to underestimate how complex good driving actually 'is', and just how important this is for efficiency/reliability....

Best Wishes
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 1:59 am     Reply with quote

Some updates on the code.
To release the energy stored on the motor. PWM and EN must be on 1. so i set up on intrerupt to set the PWM to full duty cycle and EN 1 for 0.5 second. After that to put EN on 0 and restore the PWM duty cycle. Direction don`t matter. The motor driver will see PWM 1 / EN 1 what will make GL1(gatelow1) and GL2 (gatelow2) enabled and release energy stored on GND.
Code:

#include <16F684.h>
#fuses NOWDT,NOPROTECT,INTRC_IO
#use delay( internal=8M )

#INT_EXT             
void ext_isr() {
   set_pwm1_duty(668L);   
delay_ms(500);
   EXT_INT_EDGE(H_TO_L);
      output_low(EN);   
   delay_ms(100);
   set_pwm1_duty(334L);
}

void main() {   
      enable_interrupts(INT_EXT);
      enable_interrupts(GLOBAL);
      setup_oscillator(OSC_8MHZ);
        setup_timer_2(T2_DIV_BY_1, 166, 1);
      setup_ccp1(CCP_PWM);
      set_pwm1_duty(334L);
while( TRUE ) {
    if (input(PIN_A1) == 0) output_high(DIR);
      else output_low(DIR);
delay_ms(10);
       {    
   if (input(PIN_A0) == 1) output_high (EN);
delay_ms(10);
         }
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 4:24 am     Reply with quote

It sounds as if you may be talking about braking here.

Now, if this is what you want, then 'great'. However there are other alternatives. Basically your choices are:
1) Brake. Here you switch the drivers, so that either both the top drives, or both the bottom drives are 'on', which decelerates the motor quickly. This is what is needed if you are trying to control 'position' on the final system. However downside is the high loads on the motor/gearbox.
2) Freewheel. Here you cut the PWM drive, and allow some time for the motor to coast to a stop.
3) Ramped deceleration. Here you take time to slow the motor down at a rate that is smooth and comfortable. Advantage nice smooth operation.

Now both 2, & 3, are alternatives, according to what you want to do. In both cases some of the energy is dumped back into the supply rail, via the diodes in the FETs. However the amount involved is less, the more time you take to slow the motor. If you listen to things like modern washing machines, they do this from the spin, taking several seconds to let the drum slow down. Improves reliability, makes the kit sound nicer, etc. etc.. They also do the same when starting, slowly accelerating to full speed. Given the amount of energy actually 'in' the flywheel of the washing drum with water etc., in it, this is a much nicer approach.

If you want fast response, then braking is the way to go, but be aware of the electrical & mechanical shocks both fast acceleration, and deceleration can introduce.

Best Wishes
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 4:39 am     Reply with quote

Is a good idea to decelerate. The problem is i don't have the hardware built so i can`t figure out how it will work in real. Its a project for school and didn't had that much time to built it. Anyway I have added to change the pwm once 100 ms before breaking. I don't know if it is correct.

Code:

#include <16F684.h>
#fuses NOWDT,NOPROTECT,INTRC_IO
#use delay( internal=8M )

#INT_EXT             
void ext_isr() {
   set_pwm1_duty(222L);
delay_ms(100);
   set_pwm1_duty(133L);
delay_ms(100);
   set_pwm1_duty(66L);
delay_ms(500);
   set_pwm1_duty(668L);   
delay_ms(10);
   EXT_INT_EDGE(H_TO_L);
      output_low(EN);   
   delay_ms(100);
   set_pwm1_duty(334L);
}

void main() {   
      enable_interrupts(INT_EXT);
      enable_interrupts(GLOBAL);
      setup_oscillator(OSC_8MHZ);
        setup_timer_2(T2_DIV_BY_1, 166, 1);
      setup_ccp1(CCP_PWM);
      set_pwm1_duty(334L);
while( TRUE ) {
    if (input(PIN_A1) == 0) output_high(DIR);
      else output_low(DIR);
delay_ms(10);
       {    
   if (input(PIN_A0) == 1) output_high (EN);
delay_ms(10);
         }
   }
}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 11:13 am     Reply with quote

Your original post
Quote:
only problem remains the programming of the PIC.


Now you're saying
Quote:
The problem is i don't have the hardware built


I suggest you get hardware built, then you'll find out what the REAL problems are.

Mike
ciudatelul



Joined: 02 Jun 2012
Posts: 7

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 11:15 am     Reply with quote

I don't have time to finish it till i have to give the project, this is why i asked some help . Anyway i will continue to finish it afterwards. Thanks for the help.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group