Joystick controlled DC motor with PIC16F877A

This topic shows how to control speed and direction of rotation of two DC motors using 2-axis joystick (PS2 joystick) and PIC16F877A microcontroller.

The PS2 Joystick consists of two potentiometers (one for the X-axis and the other for the Y-axis) and a push-button. With one potentiometer we can control the speed and rotation direction of a DC motor.

Hardware Required:

  • PIC16F877A microcontroller
  • PS2 Joystick
  • L293D motor driver IC  — datasheet
  • 2 x 12V DC motor
  • 8 MHz crystal oscillator
  • 2 x 22pF ceramic capacitors
  • 10k ohm resistor
  • 12V source
  • 5V source
  • Breadboard
  • Jumper wires

The L293D motor dirver IC is quadruple half-H drivers chip which allows to drive two motors in both directions, and with the two PWM modules on the PIC16F877A microcontroller we can easily control the rotation speed of the two motors. (PWM: Pulse Width Modulation).

As mentioned above the PIC16F877A microcontroller has two CCP (Capture/Compare/PWM) modules which can generate two independent PWM signals (but with the same frequency). The speed of a DC motor can be controlled with the variation of the duty cycle of the PWM signal. The output pins of PWM1 and PWM2 are RC2 and RC1 respectively.

Joystick controlled DC motor with PIC16F877A circuit:
The following image shows the circuit schematic diagram of this example.

PIC16F877A joystick controlled DC motor circuit

(All grounded terminals are connected together)

The L293D driver has 2 VCCs: VCC1 is +5V and VCC2 is +12V (same as motor nominal voltage). Pins IN1/IN3 and IN2/IN4 are the control pins where (IN1 and IN2 for motor 1; IN3 and IN4 for motor 2):

IN1/IN3 IN2/IN4 Function
L H Direction 1
H L Direction 2
L L Fast motor stop
H H Fast motor stop

The joystick board has 5 terminals: GND, +5V, VRX, VRY and SW where:
GND and +5V are power supply pins
VRX is the X-axis potentiometer output
VRY is the Y-axis potentiometer output
SW is the push button terminal (the other terminal is connected to GND).
The outputs of the X-axis and Y-axis potentiometers are connected to analog pins AN0 and AN1 respectively. The switch pin (SW) is not used in this example.

PWM1 pin (RC2) is connected to EN1,2 pin (#1) and PWM2 pin (RC1) is connected to EN2,3 pin (#9) of the L293D. The other L293D pins which are IN1, IN2, IN3 and IN4 are connected to RD0, RD1, RD2 and RD3 respectively.
Motor 1 rotation speed is controlled by PWM1 and its direction of rotation is controlled by pins IN1 and IN2. If IN1 and IN2 are zeroes the motor stops, if IN1 = 1 and IN2 = 0 the motor rotates in the one direction, if IN1 = 0 and IN2 = 1 the motor rotates in the other direction.
The same thing for motor 2 with pins PWM2, IN3 and IN4.

In the circuit there are two power supply sources, 5V and 12V. The 5V supplies most of the circuit including the microcontroller whereas the 12V supplies one pin of the L293D (VCC2). The 12V power supply source depends on the motor nominal voltage, for example if the motor nominal voltage is 5V, VCC2 pin should be connected to +5V source.

Joystick controlled DC motor with PIC16F877A CCS C code:
Timer2 module is configured to generate PWM signals of 3.9 KHz with a resolution of 9 bits :
setup_timer_2(T2_DIV_BY_4, 127, 1);
Where: T2_DIV_BY_4 is Timer2 prescaler (prescaler = 4)
127 is Timer2 preload value
1 is Timer2 postoscaler (not used in calculations)
The PWM frequency can be calculated using the following equation:

PWM Period = [(PR2) + 1] * 4 * TOSC * (TMR2 Prescale Value)

Where the PWM frequency = 1/ PWM period
PR2: Timer2 preload value
TOSC = 1/MCU frequency (in this example MCU frequency = 8MHz)
The resolution of the PWM signal can be calculated using the following equation:

        log[4(PR2 + 1)]
Resolution  =  ————————      bits

With a 9-bit resolution the duty cycle of each PWM signal can vary in the interval [0, 511].

CCS C code:

The video below shows a simple hardware circuit of this example:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.