Bipolar Full H Bridge Stepper Motor Control
Full H Bridge Stepper Motor Demo software
Simple demo playing binary control lookup tables for dual full h bridge with driver.
http://en.wikipedia.org/wiki/H_bridge
Information
This demo requires a dual full h bridge (with mosfet driver, if separate mosfets are used) Not an integrated motor control IC
Inputs and Outputs
Input p18: Step pulse (if enabled) p19: Speed analog (if enabled) p20: Direction
Output p21: L1 p22: L2 p23: H1 p24: H2 p25: H3 p26: H4 p27: L3 p28: L4
Dual H Bridge
------------------------------------------ V+ | | | | \H1 \H2 \H3 \H4 |----MA----| |----MB----| \L1 \L2 \L3 \L4 | | | | ----------------------------------------- V-
main.cpp@0:896d8456cb58, 2013-09-30 (annotated)
- Committer:
- jeroen3
- Date:
- Mon Sep 30 08:01:26 2013 +0000
- Revision:
- 0:896d8456cb58
Initial release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jeroen3 | 0:896d8456cb58 | 1 | /** |
jeroen3 | 0:896d8456cb58 | 2 | * @file main.cpp |
jeroen3 | 0:896d8456cb58 | 3 | * @brief Bipolar Steppr Motor Control with dual H Bridge |
jeroen3 | 0:896d8456cb58 | 4 | * @details Software plays stepper motor lookup tables for dual h bridge control. |
jeroen3 | 0:896d8456cb58 | 5 | * |
jeroen3 | 0:896d8456cb58 | 6 | * |
jeroen3 | 0:896d8456cb58 | 7 | * @Author Jeroen Lodder |
jeroen3 | 0:896d8456cb58 | 8 | * @Date September 2013 |
jeroen3 | 0:896d8456cb58 | 9 | * @version 1 |
jeroen3 | 0:896d8456cb58 | 10 | * |
jeroen3 | 0:896d8456cb58 | 11 | */ |
jeroen3 | 0:896d8456cb58 | 12 | |
jeroen3 | 0:896d8456cb58 | 13 | #include "mbed.h" |
jeroen3 | 0:896d8456cb58 | 14 | |
jeroen3 | 0:896d8456cb58 | 15 | /* IO declarations */ |
jeroen3 | 0:896d8456cb58 | 16 | /* LED coil indicators */ |
jeroen3 | 0:896d8456cb58 | 17 | BusOut leds(LED1, LED2, LED3, LED4); |
jeroen3 | 0:896d8456cb58 | 18 | /* H Bridge output IO */ |
jeroen3 | 0:896d8456cb58 | 19 | BusOut motor(p21, p22, p23, p24, p25, p26, p27, p28); |
jeroen3 | 0:896d8456cb58 | 20 | /* MOSFET io |
jeroen3 | 0:896d8456cb58 | 21 | * FET L1 L2 H1 H2 H3 H4 L3 L4 |
jeroen3 | 0:896d8456cb58 | 22 | * Motor MA MB |
jeroen3 | 0:896d8456cb58 | 23 | * mbed p21 p22 p23 p24 p25 p26 p27 p28 |
jeroen3 | 0:896d8456cb58 | 24 | * ------------------------ V+ |
jeroen3 | 0:896d8456cb58 | 25 | * | | | | |
jeroen3 | 0:896d8456cb58 | 26 | * \H1 \H2 \H3 \H4 |
jeroen3 | 0:896d8456cb58 | 27 | * |--MA--| |--MB--| |
jeroen3 | 0:896d8456cb58 | 28 | * \L1 \L2 \L3 \L4 |
jeroen3 | 0:896d8456cb58 | 29 | * | | | | |
jeroen3 | 0:896d8456cb58 | 30 | * ------------------------ V- |
jeroen3 | 0:896d8456cb58 | 31 | */ |
jeroen3 | 0:896d8456cb58 | 32 | |
jeroen3 | 0:896d8456cb58 | 33 | /* Single phase control */ |
jeroen3 | 0:896d8456cb58 | 34 | const uint8_t motortable_singlephase[4] = { |
jeroen3 | 0:896d8456cb58 | 35 | 0x09 , |
jeroen3 | 0:896d8456cb58 | 36 | 0x90 , |
jeroen3 | 0:896d8456cb58 | 37 | 0x06 , |
jeroen3 | 0:896d8456cb58 | 38 | 0x60 |
jeroen3 | 0:896d8456cb58 | 39 | }; |
jeroen3 | 0:896d8456cb58 | 40 | |
jeroen3 | 0:896d8456cb58 | 41 | /* Dual phase motor control */ |
jeroen3 | 0:896d8456cb58 | 42 | const uint8_t motortable_dualphase[4] = { |
jeroen3 | 0:896d8456cb58 | 43 | 0x99 , |
jeroen3 | 0:896d8456cb58 | 44 | 0x96 , |
jeroen3 | 0:896d8456cb58 | 45 | 0x66 , |
jeroen3 | 0:896d8456cb58 | 46 | 0x69 |
jeroen3 | 0:896d8456cb58 | 47 | }; |
jeroen3 | 0:896d8456cb58 | 48 | |
jeroen3 | 0:896d8456cb58 | 49 | /* Half step motor control */ |
jeroen3 | 0:896d8456cb58 | 50 | const uint8_t motortable_half_step[8] = { |
jeroen3 | 0:896d8456cb58 | 51 | 0x09 , |
jeroen3 | 0:896d8456cb58 | 52 | 0x99 , |
jeroen3 | 0:896d8456cb58 | 53 | 0x90 , |
jeroen3 | 0:896d8456cb58 | 54 | 0x96 , |
jeroen3 | 0:896d8456cb58 | 55 | 0x06 , |
jeroen3 | 0:896d8456cb58 | 56 | 0x66 , |
jeroen3 | 0:896d8456cb58 | 57 | 0x60 , |
jeroen3 | 0:896d8456cb58 | 58 | 0x69 |
jeroen3 | 0:896d8456cb58 | 59 | }; |
jeroen3 | 0:896d8456cb58 | 60 | |
jeroen3 | 0:896d8456cb58 | 61 | /* LED coil indicators tables */ |
jeroen3 | 0:896d8456cb58 | 62 | const uint8_t ledtable_singlephase[4] = { 0x4,0x2,0x8,0x1 }; |
jeroen3 | 0:896d8456cb58 | 63 | const uint8_t ledtable_dualphase[4] = { 0x6,0xA,0x9,0x5 }; |
jeroen3 | 0:896d8456cb58 | 64 | const uint8_t ledtable_half_step[8] = { 0x4,0x6,0x2,0xA,0x8,0x9,0x1,0x5 }; |
jeroen3 | 0:896d8456cb58 | 65 | |
jeroen3 | 0:896d8456cb58 | 66 | /* Fet driver definitions */ |
jeroen3 | 0:896d8456cb58 | 67 | /* Turn off time fet driver in micro seconds (uS) */ |
jeroen3 | 0:896d8456cb58 | 68 | #define TURN_ON_TIME_FET_DRIVER 750 |
jeroen3 | 0:896d8456cb58 | 69 | |
jeroen3 | 0:896d8456cb58 | 70 | /* Control definitions */ |
jeroen3 | 0:896d8456cb58 | 71 | /* Mutliplier of speed wait time setting */ |
jeroen3 | 0:896d8456cb58 | 72 | #define SPEED_SCALING 0.05 |
jeroen3 | 0:896d8456cb58 | 73 | |
jeroen3 | 0:896d8456cb58 | 74 | int main(void) { |
jeroen3 | 0:896d8456cb58 | 75 | /* Control declarations */ |
jeroen3 | 0:896d8456cb58 | 76 | /* Direction LUT are played */ |
jeroen3 | 0:896d8456cb58 | 77 | DigitalIn direction( p20 ); |
jeroen3 | 0:896d8456cb58 | 78 | /* Step pulse input if step mode */ |
jeroen3 | 0:896d8456cb58 | 79 | DigitalIn step( p18 ); |
jeroen3 | 0:896d8456cb58 | 80 | /* Speed potmeter input */ |
jeroen3 | 0:896d8456cb58 | 81 | AnalogIn speed( p19 ); |
jeroen3 | 0:896d8456cb58 | 82 | |
jeroen3 | 0:896d8456cb58 | 83 | /* config variables */ |
jeroen3 | 0:896d8456cb58 | 84 | /* Autostep or stepmode with step input */ |
jeroen3 | 0:896d8456cb58 | 85 | uint8_t autostep = 1; |
jeroen3 | 0:896d8456cb58 | 86 | /* Halfstep or Dual phase mode */ |
jeroen3 | 0:896d8456cb58 | 87 | uint8_t halfstep = 0; |
jeroen3 | 0:896d8456cb58 | 88 | |
jeroen3 | 0:896d8456cb58 | 89 | |
jeroen3 | 0:896d8456cb58 | 90 | /* Stepper motor control loop */ |
jeroen3 | 0:896d8456cb58 | 91 | while(1) { |
jeroen3 | 0:896d8456cb58 | 92 | if( halfstep ){ |
jeroen3 | 0:896d8456cb58 | 93 | if(direction){ |
jeroen3 | 0:896d8456cb58 | 94 | for(int i=0; i<8; i++) { |
jeroen3 | 0:896d8456cb58 | 95 | leds = ledtable_half_step[i]; |
jeroen3 | 0:896d8456cb58 | 96 | motor = 0; |
jeroen3 | 0:896d8456cb58 | 97 | wait_us(TURN_ON_TIME_FET_DRIVER); |
jeroen3 | 0:896d8456cb58 | 98 | motor = motortable_half_step[i]; |
jeroen3 | 0:896d8456cb58 | 99 | /* Delay */ |
jeroen3 | 0:896d8456cb58 | 100 | if(!autostep){ |
jeroen3 | 0:896d8456cb58 | 101 | while(!step); |
jeroen3 | 0:896d8456cb58 | 102 | wait(0.001); |
jeroen3 | 0:896d8456cb58 | 103 | while(step); |
jeroen3 | 0:896d8456cb58 | 104 | }else{ |
jeroen3 | 0:896d8456cb58 | 105 | wait((speed*SPEED_SCALING)+0.001); |
jeroen3 | 0:896d8456cb58 | 106 | } |
jeroen3 | 0:896d8456cb58 | 107 | } |
jeroen3 | 0:896d8456cb58 | 108 | }else{ |
jeroen3 | 0:896d8456cb58 | 109 | for(int i=7; i>-1; i--) { |
jeroen3 | 0:896d8456cb58 | 110 | leds = ledtable_half_step[i]; |
jeroen3 | 0:896d8456cb58 | 111 | motor = 0; |
jeroen3 | 0:896d8456cb58 | 112 | wait_us(TURN_ON_TIME_FET_DRIVER); |
jeroen3 | 0:896d8456cb58 | 113 | motor = motortable_half_step[i]; |
jeroen3 | 0:896d8456cb58 | 114 | /* Delay */ |
jeroen3 | 0:896d8456cb58 | 115 | if(!autostep){ |
jeroen3 | 0:896d8456cb58 | 116 | while(!step); |
jeroen3 | 0:896d8456cb58 | 117 | wait(0.001); |
jeroen3 | 0:896d8456cb58 | 118 | while(step); |
jeroen3 | 0:896d8456cb58 | 119 | }else{ |
jeroen3 | 0:896d8456cb58 | 120 | wait((speed*SPEED_SCALING)+0.001); |
jeroen3 | 0:896d8456cb58 | 121 | } |
jeroen3 | 0:896d8456cb58 | 122 | } |
jeroen3 | 0:896d8456cb58 | 123 | } |
jeroen3 | 0:896d8456cb58 | 124 | }else{ /* Half step */ |
jeroen3 | 0:896d8456cb58 | 125 | if(direction){ |
jeroen3 | 0:896d8456cb58 | 126 | for(int i=0; i<4; i++) { |
jeroen3 | 0:896d8456cb58 | 127 | leds = ledtable_dualphase[i]; |
jeroen3 | 0:896d8456cb58 | 128 | motor = 0; |
jeroen3 | 0:896d8456cb58 | 129 | wait_us(TURN_ON_TIME_FET_DRIVER); |
jeroen3 | 0:896d8456cb58 | 130 | motor = motortable_dualphase[i]; |
jeroen3 | 0:896d8456cb58 | 131 | /* Delay */ |
jeroen3 | 0:896d8456cb58 | 132 | if(!autostep){ |
jeroen3 | 0:896d8456cb58 | 133 | while(!step); |
jeroen3 | 0:896d8456cb58 | 134 | wait(0.001); |
jeroen3 | 0:896d8456cb58 | 135 | while(step); |
jeroen3 | 0:896d8456cb58 | 136 | }else{ |
jeroen3 | 0:896d8456cb58 | 137 | wait((speed*SPEED_SCALING)+0.001); |
jeroen3 | 0:896d8456cb58 | 138 | } |
jeroen3 | 0:896d8456cb58 | 139 | } |
jeroen3 | 0:896d8456cb58 | 140 | }else{ |
jeroen3 | 0:896d8456cb58 | 141 | for(int i=3; i>-1; i--) { |
jeroen3 | 0:896d8456cb58 | 142 | leds = ledtable_dualphase[i]; |
jeroen3 | 0:896d8456cb58 | 143 | motor = 0; |
jeroen3 | 0:896d8456cb58 | 144 | wait_us(TURN_ON_TIME_FET_DRIVER); |
jeroen3 | 0:896d8456cb58 | 145 | motor = motortable_dualphase[i]; |
jeroen3 | 0:896d8456cb58 | 146 | /* Delay */ |
jeroen3 | 0:896d8456cb58 | 147 | if(!autostep){ |
jeroen3 | 0:896d8456cb58 | 148 | while(!step); |
jeroen3 | 0:896d8456cb58 | 149 | wait(0.001); |
jeroen3 | 0:896d8456cb58 | 150 | while(step); |
jeroen3 | 0:896d8456cb58 | 151 | }else{ |
jeroen3 | 0:896d8456cb58 | 152 | wait((speed*SPEED_SCALING)+0.001); |
jeroen3 | 0:896d8456cb58 | 153 | } |
jeroen3 | 0:896d8456cb58 | 154 | } |
jeroen3 | 0:896d8456cb58 | 155 | } |
jeroen3 | 0:896d8456cb58 | 156 | } |
jeroen3 | 0:896d8456cb58 | 157 | } |
jeroen3 | 0:896d8456cb58 | 158 | } |