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:
Interfacing 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:
Project circuit schematic is shown below.
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | // Remote controlled stepper motor using PIC18F4550 CCS C code #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); } } } |
Remote controlled unipolar stepper motor using PIC18F4550 video:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.