Unipolar Stepper Motor Control From IR Remote Control Using PIC18F4550

This project shows how to control a 5V unipolar stepper motor from IR remote control uses NEC protocol with PIC18F4550 microcontroller. This controller controls the stepper motor speed and direction of rotation.
If you want to see how to drive the unipolar stepper motor using PIC18F4550 microcontroller read the following topic:Unipolar Stepper Motor Control From IR Remote Control Using PIC18F4550Interfacing unipolar stepper motor with PIC18F4550 microcontroller
And if you want to see how to decode IR remote control with NEC protocol see the following topic:
Extended NEC IR remote control decoder with PIC18F4550 microcontroller
To drive the unipolar stepper motor we need ULN2003 (ULN2004) Darlington transistor array or L293D motor driver as described in the previous topic.
The IR remote control used in this project is shown below:Unipolar Stepper Motor Control From IR Remote Control Using-PIC18F4550PIC18F4550 microcontroller internal oscillator is used.
Remote controlled unipolar stepper motor using PIC18F4550 CCS C code:
External interrupt is used to read IR remote control signals.

Β PIC18F4550 microcontroller internal oscillator is used.
Remote controlled unipolar stepper motor using PIC18F4550 CCS C code:
External interrupt is used to read IR remote control signals.
//Β RemoteΒ controlledΒ stepperΒ motorΒ usingΒ PIC18F4550Β CCSΒ CΒ code
//Β http://ccspicc.blogspot.com/
//Β [email protected]

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

short Direction;
unsigned int8 step_number = 0, speed_delay = 2;
unsigned int32 remote_code;
#INT_TIMER1                                  // Timer1 interrupt ISR
void timer1_isr(void){
Β Β remote_codeΒ =Β 0;
Β Β clear_interrupt(INT_TIMER1);
Β Β disable_interrupts(INT_TIMER1);
}
#INT_EXT                                     // External interrupt ISR
void ext_isr(void){
Β Β unsigned int8 count = 0, i;
Β Β unsigned int32 ir_code;
Β Β // Check 9ms pulse (remote control sends logic high)
Β Β while((input(PIN_B0) == 0) && (count < 200)){
Β Β Β Β count++;
Β Β Β Β delay_us(50);}
Β Β if( (count > 199) || (count < 160))        // NEC protocol?
Β Β Β Β return;                          
Β Β countΒ =Β 0;
Β Β // Check 4.5ms space or repeated code
Β Β while((input(PIN_B0)) && (count < 100)){
Β Β Β Β count++;
Β Β Β Β delay_us(50);}
Β Β if( (count > 99) || (count < 30))          // NEC protocol?
Β Β Β Β return;
Β Β // Check repeated code
Β Β if(count < 60){
Β Β Β Β countΒ =Β 0;
Β Β Β Β while((input(PIN_B0) == 0) && (count < 14)){
Β Β Β Β Β Β count++;
Β Β Β Β Β Β delay_us(50);}
Β Β Β Β if( (count > 13) || (count < 8))         // NEC protocol?
Β Β Β Β Β Β return;
Β Β Β Β if((remote_code == 0x40BF50AF) || (remote_code == 0x40BF906F))
Β Β Β Β set_timer1(0);
Β Β }
Β Β // Read message (32 bits)
Β Β for(i = 0; i < 32; i++){
Β Β Β Β countΒ =Β 0;
Β Β Β Β while((input(PIN_B0) == 0) && (count < 14)){
Β Β Β Β Β Β count++;
Β Β Β Β Β Β delay_us(50);}
Β Β Β Β if( (count > 13) || (count < 8))         // NEC protocol?
Β Β Β Β Β Β return;                          
Β Β Β Β countΒ =Β 0;
Β Β Β Β while((input(PIN_B0)) && (count < 40)){
Β Β Β Β Β Β count++;
Β Β Β Β Β Β delay_us(50);}
Β Β Β Β if( (count > 39) || (count < 8))         // NEC protocol?
Β Β Β Β Β Β return;                           
Β Β Β Β if( count > 20)                          // If space width > 1ms
Β Β Β Β Β Β bit_set(ir_code,Β (31Β -Β i));Β Β Β Β Β Β Β Β Β Β Β Β // Write 1 to bit (31 - i)
Β Β Β Β else                                     // If space width < 1ms
Β Β Β Β Β Β bit_clear(ir_code,Β (31Β -Β i));Β Β Β Β Β Β Β Β Β Β // Write 0 to bit (31 - i)
Β Β }
Β Β if((ir_code == 0x40BF50AF) || (ir_code == 0x40BF906F)){
Β Β Β Β set_timer1(0);
Β Β Β Β clear_interrupt(INT_TIMER1);
Β Β Β Β enable_interrupts(INT_TIMER1);}
Β Β if(ir_code == 0x40BFA05F){
Β Β Β Β speed_delay++;
Β Β Β Β if(speed_delay > 20) speed_delay = 20;
Β Β Β Β return;}
Β Β if(ir_code == 0x40BF609F){
Β Β Β Β speed_delay--;
Β Β Β Β if(speed_delay < 2) speed_delay = 2;
Β Β Β Β return;}
Β Β remote_codeΒ =Β ir_code;Β 
}
void stepper(int8 step){
Β Β if(Direction == 0){
Β Β Β Β switch(step){
Β Β Β Β Β Β case 0:
Β Β Β Β Β Β Β Β output_d(0b00000011);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 1:
Β Β Β Β Β Β Β Β output_d(0b00000110);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 2:
Β Β Β Β Β Β Β Β output_d(0b00001100);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 3:
Β Β Β Β Β Β Β Β output_d(0b00001001);
Β Β Β Β Β Β Β Β break;
Β Β Β Β }
Β Β }
Β Β if(Direction == 1){
Β Β Β Β switch(step){
Β Β Β Β Β Β case 0:
Β Β Β Β Β Β Β Β output_d(0b00001001);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 1:
Β Β Β Β Β Β Β Β output_d(0b00001100);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 2:
Β Β Β Β Β Β Β Β output_d(0b00000110);
Β Β Β Β Β Β Β Β break;
Β Β Β Β Β Β case 3:
Β Β Β Β Β Β Β Β output_d(0b00000011);
Β Β Β Β Β Β Β Β break;
Β Β Β Β }
Β Β }
}
void main(){
Β Β setup_oscillator(OSC_8MHZ);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Set internal oscillator to 8MHz
Β Β setup_adc_ports(NO_ANALOGS);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Configure AN pins as digital
Β Β set_tris_b(1);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Configure RB0 as digital input pin
Β Β port_b_pullups(TRUE);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Enable PORTB internal pull-ups
Β Β output_d(0);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // PORTD initial state
Β Β set_tris_d(0);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Configure PORTD pins as outputs
Β Β setup_timer_1(T1_INTERNALΒ |Β T1_DIV_BY_4);Β Β Β // Timer1 configuration
Β Β enable_interrupts(GLOBAL);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Enable global interrupts
Β Β enable_interrupts(INT_EXT_H2L);Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β // Enable external interrupt
Β Β while(TRUE){
Β Β Β Β output_d(0);
Β Β Β Β while(remote_code == 0x40BF40BF){
Β Β Β Β Β Β DirectionΒ =Β 0;
Β Β Β Β Β Β stepper(step_number);
Β Β Β Β Β Β step_number++;
Β Β Β Β Β Β if(step_number > 3) 
Β Β Β Β Β Β Β Β step_numberΒ =Β 0;
Β Β Β Β Β Β delay_ms(speed_delay);
Β Β Β Β }
Β Β Β Β while(remote_code == 0x40BF807F){
Β Β Β Β Β Β DirectionΒ =Β 1;
Β Β Β Β Β Β stepper(step_number);
Β Β Β Β Β Β step_number++;
Β Β Β Β Β Β if(step_number > 3) 
Β Β Β Β Β Β Β Β step_numberΒ =Β 0;
Β Β Β Β Β Β delay_ms(speed_delay);
Β Β Β Β }
Β Β Β Β while(remote_code == 0x40BF50AF){
Β Β Β Β Β Β DirectionΒ =Β 0;
Β Β Β Β Β Β stepper(step_number);
Β Β Β Β Β Β step_number++;
Β Β Β Β Β Β if(step_number > 3) 
Β Β Β Β Β Β Β Β step_numberΒ =Β 0;
Β Β Β Β Β Β delay_ms(speed_delay);
Β Β Β Β }
Β Β Β Β while(remote_code == 0x40BF906F){
Β Β Β Β Β Β DirectionΒ =Β 1;
Β Β Β Β Β Β stepper(step_number);
Β Β Β Β Β Β step_number++;
Β Β Β Β Β Β if(step_number > 3) 
Β Β Β Β Β Β Β Β step_numberΒ =Β 0;
Β Β Β Β Β Β delay_ms(speed_delay);
Β Β Β Β }
Β Β }
}

For more detail:Β Unipolar Stepper Motor Control From IR Remote Control Using PIC18F4550


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

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