Tuesday, March 29, 2016

DC motor speed and direction control with PIC18F4550 microcontroller


DC motor control with PIC18F4550 and H-Bridge
The microcontroller PIC18F4550 has two CCP modules CCP1 and CCP2, the CCP1 module is implemented as a standard CCP module with Enhanced PWM capabilities. These include the provision for 2 or 4 output channels, user-selectable polarity, dead-band control and automatic shutdown and restart.
The Enhanced PWM mode provides additional PWM output options for a broader range of control applications. The module is a backward compatible version of the standard CCP module and offers up to four outputs, designated P1A through P1D.
This topic shows how to use the enhanced PWM as a Full-Bridge Mode to control DC motor speed and direction.
In Full-Bridge Output mode, four pins are used as outputs; however, only two outputs are active at a time. In the Forward mode, pin P1A is continuously active and pin P1D is modulated. In the Reverse mode, pin P1C is continuously active and pin P1B is modulated.
P1A, P1B, P1C and P1D outputs are multiplexed with the PORTC<2>, PORTD<5>, PORTD<6> and PORTD<7> data latches. The TRISC<2>, TRISD<5>, TRISD<6> and TRISD<7> bits must be cleared to make the P1A, P1B, P1C and P1D pins outputs.
The motor speed is controlled when the PWM duty cycle changes.
An H-Bridge circuit is used to reverse motor terminals which gives us the ability to change rotation direction.
Related topics:
DC motor speed control with PIC18F4550 and CCS PIC C
PIC18F4550 ADC example with CCS PIC C compiler
PIC18F4550 PWM example using CCS PIC C

DC motor control with PIC18F4550 microcontroller circuit:
The following circuit schematic shows project circuit.
PIC18F4550 DC motor speed and direction control circuit CCS PIC C
PORTB internal weak pull-ups are enabled.
There are 3 pushbuttons in the circuit 2 of them to choose rotation direction and the other one stops the motor. The two LEDs indicate rotation direction, if Direction 1 button is pressed the motor moves in the first direction and LED 1 on and the same thing for Direction 2 button and LED 2. The motor speed is controlled from potentiometer connected to RA0 (analog channel 0). The microcontroller PIC18F4550 reads analog data from channel 0 and use the digital value to set the PWM duty cycle.
The PWM frequency is 500Hz.
The basic elements of the H-bridge are the four MOSFETs (2 N-type and 2 P-type).
PIC18F4550 microcontroller internal oscillator is used and set to 8MHz.
DC motor control with PIC18F4550 CCS PIC C code:
PIC18F4550 Timer2 is configured to generate a PWM frequency of 500Hz and the microcontroller runs with its internal oscillator at 8MHz.
The microcontroller PIC18F4550 reads RA0 analog value and stores the digital value on variable (i), this variable is used to set the PWM duty cycle.
// Dc motor control with PIC18F4550 CCS PIC C code
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

#include <18F4550.h>
#device ADC = 10
#fuses NOMCLR INTRC_IO
#use delay(clock = 8000000)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)

unsigned int16 i ;
void main(){
  setup_oscillator(OSC_8MHZ);            // Set internal oscillator to 8MHz
  port_b_pullups(TRUE);                  // Enable PORTB pull-ups
  output_b(0);                           // PORTB initial state
  set_tris_b(7);                         // Configure RB0, RB1 & RB2 as inputs
  output_c(0);                           // PORTC initial state
  set_tris_c(0);                         // Configure PORTC pins as outputs
  output_d(0);                           // PORTD initial state
  set_tris_d(0);                         // Configure PORTD pins as outputs
  setup_adc(ADC_CLOCK_DIV_8);            // Set ADC conversion time to 8Tosc
  setup_adc_ports(AN0);                  // Configure AN0 as analog input
  set_adc_channel(0);                    // Select channel AN0
  setup_timer_2(T2_DIV_BY_16, 250, 1);   // Set PWM frequency to 500Hz
  delay_ms(100);                         // Wait 100ms
  while(TRUE){
    i = read_adc();                      // Read from AN0 and store in i
    set_pwm1_duty(i);                    // Set pwm1 duty cycle
    delay_ms(10);                        // Wait 10ms
    if(input(PIN_B0) == 0){              // If RB0 button pressed
      if(input(PIN_B3) == 0){            // If direction 1 not already selected
        output_b(0);                     // Both LEDs OFF
        setup_ccp1(CCP_OFF);             // CCP1 OFF
        output_c(0);                     // PORTC pins low
        output_d(0);                     // PORTD pins low
        delay_ms(100);                   // Wait 100ms
        setup_ccp1(CCP_PWM | CCP_PWM_FULL_BRIDGE);
                                         // Configure CCP1 as a PWM output forward
        output_high(PIN_B3);             // RB3 LED ON
        }}
    if(input(PIN_B1) == 0){              // If RB1 button pressed
      if(input(PIN_B4) == 0){            // If direction 2 not already selected
        output_b(0);                     // Both LEDs OFF
        setup_ccp1(CCP_OFF);             // CCP1 OFF
        output_c(0);                     // PORTC pins low
        output_d(0);                     // PORTD pins low
        delay_ms(100);                   // Wait 100ms
        setup_ccp1(CCP_PWM | CCP_PWM_FULL_BRIDGE_REV);
                                         // Configure CCP1 as a PWM output reverse
        output_high(PIN_B4);             // RB4 LED ON
        }}
    if(input(PIN_B2) == 0){              // If RB2 button pressed
      setup_ccp1(CCP_OFF);               // CCP1 OFF
      output_b(0);                       // Both LEDs OFF
      output_c(0);                       // PORTC pins low
      output_d(0);                       // PORTD pins low
      }
   }
}

DC motor control with PIC18F4550 video:
The following video shows more about this project with hardware circuit.
Reference:
Microchip PIC18F4550 datasheet.