DC Motor control with rotary encoder and PIC MCU | mikroC Projects

This post shows how to control DC motor speed and direction of rotation using PIC16F887 microcontroller, rotary encoder and L293D motor driver chip.
The compiler used in this project is mikroElektronika mikroC PRO for PIC.

In this example I used the rotary encoder shown in the following image:

The rotary encoder has 5 pins: GND, + (+5V or 3.3V), SW (push button), DT (pin B) and CLK (pin A).
As an addition to the rotary encoder there is a push button and three pull up resistors for pins SW, DT and CLK of 10k ohm each. With the three pull-up resistors, the normal state of each terminal is logic high.
The rotary encoder generates (when rotating) two square waves on pins A (CLK) and B (DT) with 90° out of phase as shown in the figure below:

DC Motor control with rotary encoder and PIC16F887 circuit:
Project circuit schematic diagram is shown in the following image.

(All grounded terminals are connected together)

The circuit is supplied with two power sources, one with voltage of 5V which supplies the PIC16F887 microcontroller, the rotary encoder board and the L293D driver IC (VCC1), and the second source with voltage of 12V which supplies the L293D chip (VCC2) (therefore the DC motor). The DC motor nominal voltage is 12V.

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

IN1

IN2

Function

L

H

Direction 1

H

L

Direction 2

L

L

Fast motor stop

H

H

Fast motor stop

The PIC16F887 generates a PWM signal on pin RC2 (#17) using CCP1 module (CCP: Capture/Compare/PWM), this pin is connected to EN1,2 pin of the L293D chip. IN1 and IN2 pins are connected to RD0 and RD1 respectively (they can be reversed).

The rotary encoder push button terminal is connected to pin RB2, with this button we can change the direction of rotation of the motor. CLK and DT pins are connected to RB0 and RB1 respectively.

In this project the PIC16F887 microcontroller uses its internal oscillator @ 8 MHz, MCLR pin is configured as an input pin.

DC Motor control with rotary encoder and PIC16F887 C code:
The following C code is for mikroC PRO for PIC compiler, it was tested with version 7.2.0.

Rotary encoder pushbutton (connected to RB2) and the control lines (connected to RD0 and RD1) are defined in the code as shown below:

C

1

2

3

4

5

6

// define rotary encoder button pin connection

#define SW RB2_bit

// define motor control pins

#define IN1 RD1_bit

#define IN2 RD0_bit

Internal weak pull-up is enabled for pin RB2, the following lines are used for that:

C

1

2

3

// enable RB1 internal pull up

NOT_RBPU_bit=0;// clear RBPU bit (OPTION_REG.7)

WPUB=0x04;// WPUB register = 0b00000100

PORTB interrupt-on-change is enabled for pins RB0 and RB1 which are respectively connected to CLK and DT pins of the rotary encoder. This interrupt detects falling and rising of the two lines: