Contains code to drive a small stepper motor with a Freescale h-bridge driver evaluation board, and a Freedom FRDM-KL25Z

Dependencies:   USBDevice mbed

Fork of LVHB Stepper Motor Drive by Freescale

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 //Libraries needed 
00003 #include "mbed.h"
00004 #include "USBHID.h"
00005 
00006 // We declare a USBHID device.
00007 // HID In/Out Reports are 64 Bytes long
00008 // Vendor ID (VID):     0x15A2
00009 // Product ID (PID):    0x0138
00010 // Serial Number:       0x0001
00011 USBHID hid(64, 64, 0x15A2, 0x0138, 0x0001, true);
00012 
00013 //storage for send and receive data
00014 HID_REPORT send_report;
00015 HID_REPORT recv_report;
00016 
00017 //Stepper Motor States
00018 #define STATE1  1
00019 #define STATE2  2
00020 #define STATE3  3
00021 #define STATE4  4
00022 #define STATE5  5
00023 #define STATE6  6
00024 #define STATE7  7
00025 #define STATE8  8
00026 
00027 // USB COMMANDS
00028 // These are sent from the PC
00029 #define WRITE_LED           0x20
00030 #define WRITE_OUTPUT_EN     0x30
00031 #define WRITE_STEPS_PER_SEC 0x40
00032 #define WRITE_RUN_STOP      0x70
00033 #define WRITE_DIRECTION     0x71
00034 #define WRITE_ACCEL         0x80
00035 #define WRITE_RESET         0xA0
00036 #define WRITE_STEPMODE      0xB0
00037 
00038 
00039 // MOTOR STATES
00040 #define STOP            0x00
00041 #define RUN             0x02
00042 #define RAMP            0x03
00043 #define RESET           0x05
00044 
00045 // LED CONSTANTS
00046 #define LEDS_OFF        0x00
00047 #define RED             0x01
00048 #define GREEN           0x02
00049 #define BLUE            0x03
00050 #define READY_LED       0x04
00051 
00052 // LOGICAL CONSTANTS
00053 #define OFF             0x00
00054 #define ON              0x01
00055 
00056 //step modes
00057 #define QTR             0x01
00058 #define HALF            0x02
00059 
00060 //FRDM-KL25Z LEDs
00061 DigitalOut red_led(LED1);
00062 DigitalOut green_led(LED2);
00063 DigitalOut blue_led(LED3);
00064 
00065 //Input pins on Eval Board
00066 DigitalOut IN1A(PTD4);          // Pin IN1A input to EVAL board (FRDM PIN Name)
00067 DigitalOut IN1B(PTA12);         // Pin IN1B input to EVAL board (FRDM PIN Name)
00068 DigitalOut IN2A(PTA4);          // Pin IN2A input to EVAL board (FRDM PIN Name)
00069 DigitalOut IN2B(PTA5);          // Pin IN2B input to EVAL board (FRDM PIN Name)
00070 
00071 //Green LED on Eval Board
00072 DigitalOut READY(PTC5);         // Pin READY input to EVAL board (FRDM PIN Name)
00073 
00074 //These pins are defined differntly on different parts
00075 //OE for FRDM-17529 and FRDM-17533 Eval Boards
00076 //and PSAVE for FRDM-17C724 and FRDM-17531 Eval Boards
00077 //FRDM-34933 Eval Board does not have either of these pins
00078 DigitalOut OE(PTC7);            // Pin OE input to MPC17533, MPC17529 (FRDM PIN Name)
00079 
00080 //variables
00081 static int stepState = 1;                   //holds current step state of the step being applied to the stepper
00082 static int stepMode = 0;                    //This is either 1/2 or 1/4 step
00083 static int dir = 0;                         //rotational direction of stepper
00084 static int rampCount = 0;                   //counter value used during acceleration ramp-up
00085 static int initflag = 0;                    //used upon first entry into main at startup
00086 static int runstop = 0;                     //holds value of running or stopped of commanded value from PC
00087 static int motorState = 0;                  //holds state of stepper motor state machine (RUN, STOP, RESET, or RAMP)
00088 static int accel = 0;                       //holds the value of accceleration enabled from PC
00089 static float numRampSteps = 0;              //calculated value that is based on the stepper speed after acceleration
00090 static float stepRate = 10;
00091 static int stepMultiplier = 1;
00092 static float next_interval_us = 1200;
00093 static float stepInterval_us = 1200;
00094 static bool acceleration_start = 0;
00095 static bool runStopChange = 0;
00096 static bool accel_wait_flag = 0;
00097 
00098 //static int mode = 0;
00099 
00100 void test_state_mach(void);
00101 void adv_state_mach_half(void);
00102 void adv_state_mach_full(void);
00103 void set_speed(float stepRate);
00104 void acceleration_a(void);
00105 void acceleration_b(void);
00106 void set_speed_with_ramp(void);
00107 void null_function(void);
00108 void clear_accel_wait_flag(void);
00109 
00110 
00111 
00112 //
00113 //Create a Timeout function.  Used for ramping up the speed at startup
00114 Timeout accel_ramp;
00115 
00116 //Create a Ticker function.  Called during normal runtime to advance the stepper motor
00117 Ticker advance_state;
00118   
00119  
00120 int main() 
00121 {
00122     //set up storage for incoming/outgoing 
00123     send_report.length = 64;
00124     recv_report.length = 64;
00125     
00126     red_led     = 1;        // Red LED = OFF
00127     green_led   = 1;        // Green LED = OFF
00128     blue_led    = 0;        // Blue LED = ON
00129     
00130     READY = 0;
00131     
00132     motorState = RESET;
00133  
00134     while(1) 
00135     {
00136         //try to read a msg
00137         if(hid.readNB(&recv_report)) 
00138         {
00139             if(initflag == true)
00140             {
00141                 initflag = false;
00142                 blue_led = 1;               //turn off blue LED
00143                 READY = 0;
00144             }
00145             switch(recv_report.data[0])     //byte 0 of recv_report.data is command
00146             {
00147 //-----------------------------------------------------------------------------------------------------------------
00148 //          COMMAND PARSER
00149 //-----------------------------------------------------------------------------------------------------------------
00150 ////////
00151                 case WRITE_LED:
00152                     switch(recv_report.data[1])
00153                     {
00154                         case LEDS_OFF:
00155                             red_led = 1;
00156                             green_led = 1;
00157                             blue_led = 1;
00158                             break;
00159                         case RED:
00160                             if(recv_report.data[2] == 1){red_led = 0;} else {red_led = 1;}
00161                             break;
00162                         case GREEN:
00163                             if(recv_report.data[2] == 1){green_led = 0;} else {green_led = 1;}
00164                             break; 
00165                         case BLUE:
00166                             if(recv_report.data[2] == 1){blue_led = 0;} else {blue_led = 1;}
00167                             break;     
00168                          default:
00169                             break;
00170                     }// End recv report data[1]
00171                     break;
00172 ////////end   case WRITE_LED                  
00173 
00174 ////////              
00175                  case  WRITE_STEPS_PER_SEC:
00176 
00177                     stepRate = recv_report.data[1];
00178                     set_speed(stepRate);
00179                     break;
00180 ////////                
00181                 case  WRITE_RUN_STOP:
00182                     if(recv_report.data[1] == 1)
00183                     {
00184                         if(runstop != 1)
00185                         {
00186                             red_led = 1;
00187                             blue_led = 1;
00188                             green_led = 0;
00189                             runstop = 1;
00190                             runStopChange = 1;
00191                             
00192                             if(accel == 1)
00193                             {
00194                                 motorState = RAMP;
00195                                 next_interval_us = stepMultiplier;
00196                                 acceleration_start = 1;                               
00197                             }
00198                             else
00199                             {
00200                                 motorState = RUN;
00201                                 set_speed(stepRate);
00202                             }
00203                         }
00204  
00205                     }
00206                     else
00207                     {
00208                         if(runstop != 0)
00209                         {
00210                             runstop = 0;
00211                             runStopChange = 1;                            
00212                             motorState = STOP;
00213                             red_led = 0;
00214                             green_led = 1;
00215                             blue_led = 1;                          
00216                         }
00217                     }//end if(recv_report.data[1] == 1)
00218                      break;
00219 ////////                
00220                 case  WRITE_DIRECTION:
00221    
00222                     if(recv_report.data[1] == 1)
00223                     {
00224                         dir = 1;
00225  
00226                     }
00227                     else
00228                     {
00229                         dir = 0;    
00230  
00231                     }                    
00232                     break;
00233 ////////
00234                 case  WRITE_ACCEL:
00235                     if(recv_report.data[1] == 1)
00236                     {
00237                             accel = 1;
00238                     }
00239                     else
00240                     {
00241                             accel = 0;
00242                     }
00243                     break;
00244 ////////    
00245                 case WRITE_STEPMODE:
00246                     if(recv_report.data[1] == QTR)
00247                     {
00248                         stepMode = QTR;
00249                         stepMultiplier = 8;
00250  
00251                     }
00252                     else
00253                     {
00254                         stepMode = HALF;
00255                         stepMultiplier = 4;
00256     
00257                     }
00258                     break;
00259 ////////                               
00260                 default:
00261                     break;
00262             }// End Switch recv report data[0]
00263             
00264 
00265 //-----------------------------------------------------------------------------------------------------------------
00266 //      end command parser    
00267 //-----------------------------------------------------------------------------------------------------------------
00268             
00269             send_report.data[0] = recv_report.data[0];      // Echo Command
00270             send_report.data[1] = recv_report.data[1];      // Echo Subcommand 1
00271             send_report.data[2] = recv_report.data[2];      // Echo Subcommand 2
00272             send_report.data[3] = 0x00;
00273             send_report.data[4] = 0x00;
00274             send_report.data[5] = 0x00;
00275             send_report.data[6] = 0x00;
00276             send_report.data[7] = 0x00;
00277               
00278             //Send the report
00279             hid.send(&send_report);
00280         }// End If(hid.readNB(&recv_report))
00281 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00282 //End of USB message handling        
00283 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00284 
00285 
00286 /************************************************************************************************************************
00287 // This is handling of Speed, Acceleration, Direction, and Start/Stop
00288 ***********************************************************************************************************************/
00289 
00290 
00291 
00292 
00293 
00294 
00295         switch (motorState)
00296         {
00297             case STOP:
00298                 if(runStopChange == 1)
00299                 {
00300                     runStopChange = 0;
00301                     OE = 1;                  
00302                     advance_state.detach();
00303                 }
00304                 else
00305                 {
00306                     OE = 1;                    
00307                 }
00308                 break;
00309              
00310             case RUN:
00311                 if(runStopChange != 0)
00312                 {
00313                     OE = 0;
00314                     runStopChange = 0;
00315                  }    
00316                 break;
00317                 
00318             case RESET:
00319                 OE = 1;
00320                 runStopChange = false;
00321                 motorState = STOP;                
00322                 break;
00323                 
00324             case RAMP:
00325                 if(acceleration_start == 1)
00326                 {
00327                     OE = 0;
00328                     acceleration_a();
00329                     acceleration_start = 0;
00330                 }
00331                 if(accel_wait_flag == 0)
00332                 {
00333                     acceleration_a();
00334                     accel_wait_flag = 1;
00335                     accel_ramp.attach_us(&clear_accel_wait_flag, next_interval_us);
00336                 }  
00337 
00338                 break; 
00339                 
00340         }// end switch motorState
00341  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////       
00342 
00343         
00344     }//end while
00345 }//end main
00346 
00347 
00348  
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 //state machine to advance to next step
00357 //called each time
00358 void adv_state_mach_half()
00359 {
00360 
00361     READY = 1; 
00362  if(OE == 0)
00363     {
00364 
00365     if(dir == 1)
00366     {
00367         switch(stepState)
00368         {
00369             case STATE1:
00370             IN1A = 1;       //coil A +, coil B +
00371             IN1B = 0;
00372             IN2A = 1;
00373             IN2B = 0;
00374             stepState = 2;
00375             break;
00376             
00377             case STATE2:
00378             IN1A = 0;       //coil A 0, coil B +
00379             IN1B = 0;
00380             IN2A = 1;
00381             IN2B = 0;
00382             stepState = 3;
00383             break;
00384             
00385             case STATE3:
00386             IN1A = 0;       //coil A -, coil B +
00387             IN1B = 1;
00388             IN2A = 1;
00389             IN2B = 0;
00390             stepState = 4;
00391             break;
00392             
00393             case STATE4:
00394             IN1A = 0;       //coil A -, coil B 0
00395             IN1B = 1;
00396             IN2A = 0;
00397             IN2B = 0;
00398             stepState = 5;
00399             break;
00400             
00401             case STATE5:
00402             IN1A = 0;       //coil A -, coil B -
00403             IN1B = 1;
00404             IN2A = 0;
00405             IN2B = 1;
00406             stepState = 6;
00407             break;
00408             
00409             case STATE6:
00410             IN1A = 0;       //coil A 0, coil B -
00411             IN1B = 0;
00412             IN2A = 0;
00413             IN2B = 1;
00414             stepState = 7;
00415             break;
00416             
00417             case STATE7:
00418             IN1A = 1;       //coil A +, coil B -
00419             IN1B = 0;
00420             IN2A = 0;
00421             IN2B = 1;
00422             stepState = 8;
00423             break;
00424             
00425             case STATE8:
00426             IN1A = 1;       //coil A +, coil B 0
00427             IN1B = 0;
00428             IN2A = 0;
00429             IN2B = 0;
00430             stepState = 1;
00431             break;
00432             
00433             default:
00434             IN1A = 0;
00435             IN1B = 0;
00436             IN2A = 0;
00437             IN2B = 0;
00438             stepState = 1;
00439             break;
00440             
00441             
00442         }
00443     }
00444     else
00445     {
00446         switch(stepState)
00447         {
00448             case STATE1:
00449             IN1A = 1;       //coil A +, coil B 0
00450             IN1B = 0;
00451             IN2A = 0;
00452             IN2B = 0;
00453             stepState = 2;
00454             break;
00455             
00456             case STATE2:
00457             IN1A = 1;       //coil A +, coil B -
00458             IN1B = 0;
00459             IN2A = 0;
00460             IN2B = 1;
00461             stepState = 3;
00462             break;
00463             
00464             case STATE3:
00465             IN1A = 0;       //coil A 0 , coil B -
00466             IN1B = 0;
00467             IN2A = 0;
00468             IN2B = 1;
00469             stepState = 4;
00470             break;
00471             
00472             case STATE4:
00473             IN1A = 0;       //coil A -, coil B -
00474             IN1B = 1;
00475             IN2A = 0;
00476             IN2B = 1;
00477             stepState = 5;
00478             break;
00479             
00480             case STATE5:
00481             IN1A = 0;       //coil A -, coil B 0
00482             IN1B = 1;
00483             IN2A = 0;
00484             IN2B = 0;
00485             stepState = 6;
00486             break;
00487             
00488             case STATE6:
00489             IN1A = 0;       //coil A -, coil B +
00490             IN1B = 1;
00491             IN2A = 1;
00492             IN2B = 0;
00493             stepState = 7;
00494             break;
00495             
00496             case STATE7:
00497             IN1A = 0;       //coil A 0, coil B +
00498             IN1B = 0;
00499             IN2A = 1;
00500             IN2B = 0;
00501             stepState = 8;
00502             break;
00503             
00504             case STATE8:
00505             IN1A = 1;       //coil A +, coil B +
00506             IN1B = 0;
00507             IN2A = 1;
00508             IN2B = 0;
00509             stepState = 1;
00510             break;
00511             
00512             default:
00513             IN1A = 0;
00514             IN1B = 0;
00515             IN2A = 0;
00516             IN2B = 0;
00517             stepState = 1;
00518             break;
00519             
00520             
00521         }
00522     }        
00523  }   
00524 
00525 }
00526 
00527 
00528 void adv_state_mach_full()
00529 {
00530  if(OE == 0)
00531     {
00532         if(dir == 1)
00533         {
00534             switch(stepState)
00535             {
00536                 case STATE1:
00537                 IN1A = 1;       //coil A +, coil B +
00538                 IN1B = 0;
00539                 IN2A = 1;
00540                 IN2B = 0;
00541                 stepState = 2;
00542                 break;
00543                 
00544                 case STATE2:
00545                 IN1A = 1;       //coil A +, coil B -
00546                 IN1B = 0;
00547                 IN2A = 0;
00548                 IN2B = 1;
00549                 stepState = 3;
00550                 break;
00551                 
00552                 case STATE3:
00553                 IN1A = 0;       //coil A -, coil B -
00554                 IN1B = 1;
00555                 IN2A = 0;
00556                 IN2B = 1;
00557                 stepState = 4;
00558                 break;
00559                 
00560                 
00561                 case STATE4:
00562                 IN1A = 0;       //coil A -, coil B +
00563                 IN1B = 1;
00564                 IN2A = 1;
00565                 IN2B = 0;
00566                 stepState = 1;
00567                 break;
00568                 
00569                 
00570                 
00571                 default:
00572                 IN1A = 0;
00573                 IN1B = 0;
00574                 IN2A = 0;
00575                 IN2B = 0;
00576                 stepState = 1;
00577                 break;
00578                 
00579                 
00580             }
00581         }
00582         else
00583         {
00584             switch(stepState)
00585             {
00586                 case STATE1:
00587                 IN1A = 0;       //coil A -, coil B +
00588                 IN1B = 1;
00589                 IN2A = 1;
00590                 IN2B = 0;
00591                 stepState = 2;
00592                 break;
00593     
00594                 case STATE2:
00595                 IN1A = 0;       //coil A -, coil B -
00596                 IN1B = 1;
00597                 IN2A = 0;
00598                 IN2B = 1;
00599                 stepState = 3;
00600                 break;
00601                 
00602                 case STATE3:
00603                 IN1A = 1;       //coil A +, coil B -
00604                 IN1B = 0;
00605                 IN2A = 0;
00606                 IN2B = 1;
00607                 stepState = 4;
00608                 break;
00609                 
00610                 case STATE4:
00611                 IN1A = 1;       //coil A +, coil B +
00612                 IN1B = 0;
00613                 IN2A = 1;
00614                 IN2B = 0;
00615                 stepState = 1;
00616                 break;
00617                 
00618                 default:
00619                 IN1A = 0;
00620                 IN1B = 0;
00621                 IN2A = 0;
00622                 IN2B = 0;
00623                 stepState = 1;
00624                 break;
00625                 
00626                 
00627             } //end switch
00628         }  //end else   
00629     } 
00630 }
00631 /////////////////////////////////////////////////////////////////////////////////
00632 
00633 
00634 void clear_accel_wait_flag(void)
00635 {
00636     accel_wait_flag = 0;
00637 }
00638 
00639 
00640 
00641 
00642 void acceleration_a(void)
00643 {
00644     
00645     rampCount ++;
00646     if(rampCount <= numRampSteps)
00647     {
00648         test_state_mach();
00649         next_interval_us = 1000000 * (1/float(rampCount * stepMultiplier));
00650   //      accel_ramp.attach_us(&acceleration_b, next_interval_us);//speed);
00651     }
00652     else
00653     {
00654       rampCount = 0;
00655       motorState = RUN;
00656       advance_state.attach_us(&test_state_mach, stepInterval_us);     
00657     }
00658 
00659 }
00660 /////////////////////////////////////////////////////////////////////////////////
00661 void acceleration_b(void)
00662 {
00663     READY = 1;
00664     rampCount ++;    
00665     if(rampCount <= 5000) //numRampSteps)
00666     {
00667         test_state_mach();
00668         next_interval_us = 1000000 * (1/(rampCount)); // * stepMultiplier));
00669         accel_ramp.attach_us(&acceleration_a, next_interval_us);
00670     }
00671     else
00672     {
00673         READY = 0;
00674         rampCount = 0;
00675         motorState = RUN;
00676         advance_state.attach_us(&test_state_mach, stepInterval_us);          
00677     }
00678     
00679 }
00680 /////////////////////////////////////////////////////////////////////////////////
00681 
00682 void test_state_mach(void)
00683 {
00684     if(stepMode == QTR) 
00685     {
00686         adv_state_mach_half();
00687     }
00688     else
00689     {
00690         adv_state_mach_full();
00691     }
00692 }
00693 ///////////////////////////////////////////////////////////////////////////////////
00694 
00695 
00696 void set_speed(float speed)
00697 {
00698     if(motorState == RUN)
00699     {
00700       if(stepMode == QTR)
00701       {
00702          numRampSteps = speed;
00703          stepInterval_us = 1000000*(1.0/(speed * 8));
00704          advance_state.attach_us(&test_state_mach, stepInterval_us); 
00705       }
00706       else
00707       {
00708          numRampSteps = speed;
00709          stepInterval_us = 1000000*(1.0/(speed * 4));
00710          advance_state.attach_us(&test_state_mach, stepInterval_us); 
00711       }    
00712     }
00713     else    //not in run mode, save the change
00714     {
00715           if(stepMode == QTR)
00716           {
00717              numRampSteps = speed;
00718              stepInterval_us = 1000000*(1.0/(speed * 8));
00719           }
00720           else
00721           {
00722              stepInterval_us = 1000000*(1.0/(speed * 4));
00723              numRampSteps = speed;
00724           }   
00725         }             
00726 }