User Tools

Site Tools


oak:tutorials:stepper_motor

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
oak:tutorials:stepper_motor [2017/01/14 16:19]
Rover#18
oak:tutorials:stepper_motor [2017/01/14 16:52]
Rover#18 minor edits in the remote commanding description
Line 5: Line 5:
 {{ :​oak:​tutorials:​oak_stepper_motor_setup.jpg?​direct&​500 | Oak commanding stepper motor via A4988 driver. ​ A 6-wire 2-phase unipolar stepper motor is shown here, with its coil center tap leads (white/​yellow) unconnected. ​ The A4988 driver (red) is upside-down in this photo, showing the backside of the board, which is opposite of the view shown in the Fritzing diagram. ​ The motor is powered from a common 12V DC wall wart transformer,​ with a 68uF cap connected at the jack. }} {{ :​oak:​tutorials:​oak_stepper_motor_setup.jpg?​direct&​500 | Oak commanding stepper motor via A4988 driver. ​ A 6-wire 2-phase unipolar stepper motor is shown here, with its coil center tap leads (white/​yellow) unconnected. ​ The A4988 driver (red) is upside-down in this photo, showing the backside of the board, which is opposite of the view shown in the Fritzing diagram. ​ The motor is powered from a common 12V DC wall wart transformer,​ with a 68uF cap connected at the jack. }}
  
-This lesson teaches you how to:+**This lesson teaches you how to:**
   * Control a stepper motor using an [[https://​www.pololu.com/​file/​download/​A4988.pdf?​file_id=0J450|A4988]] stepper motor driver,   * Control a stepper motor using an [[https://​www.pololu.com/​file/​download/​A4988.pdf?​file_id=0J450|A4988]] stepper motor driver,
   * Expose functions and variables to the Particle Cloud, for remote commanding via either [[http://​digistu.mp/​oakterm|OakTerm]],​ the Particle mobile app, or a [[https://​digistump.com/​wiki/​oak/​tutorials/​stepper_motor?​do=edit#​stepper_controller_web_interface|custom web interface]].   * Expose functions and variables to the Particle Cloud, for remote commanding via either [[http://​digistu.mp/​oakterm|OakTerm]],​ the Particle mobile app, or a [[https://​digistump.com/​wiki/​oak/​tutorials/​stepper_motor?​do=edit#​stepper_controller_web_interface|custom web interface]].
Line 148: Line 148:
 const int pinStep = 1; const int pinStep = 1;
 const int pinDirection = 0; const int pinDirection = 0;
-const int durationStepPulseMs ​1; //ms+const int durationStepPulseMicroseconds ​100; //us
 const int maxStepsPerSec = 4; const int maxStepsPerSec = 4;
  
Line 179: Line 179:
   Particle.variable("​direction",​stepDirection);​   Particle.variable("​direction",​stepDirection);​
   Particle.variable("​do_motion",​doMotion);​   Particle.variable("​do_motion",​doMotion);​
-  Particle.variable("​step_period",​stepPeriodMs); +  Particle.variable("​stepperiod",​stepPeriodMs);​
-  Particle.variable("​step_wait",​waitBetweenStepsMs);+
 } }
  
Line 191: Line 190:
   if( doMotion && stepSpeed>​0 && (stepDirection==-1 || stepDirection==1) ){   if( doMotion && stepSpeed>​0 && (stepDirection==-1 || stepDirection==1) ){
     doOneStep(); ​ // send one pulse to the A4988 STEP pin     doOneStep(); ​ // send one pulse to the A4988 STEP pin
-    ​delay(waitBetweenStepsMs);  ​// pause here until it's time to send the next tick+    ​ 
 +    ​// Pause here until it's time to send the next pulse 
 +    // To be more precise, we would account for cpu time and step pulse duration, 
 +    // both of which should be small relative to the step period until you get up 
 +    // to speeds over 500 steps per second. ​ Future builds should correct this. 
 +    delay(stepPeriodMs);  ​
  
   // Otherwise, pause briefly before checking again   // Otherwise, pause briefly before checking again
Line 217: Line 221:
  
  
-// setSpeed expects one argument: ​ steps per second+// setSpeed expects one argument: ​ steps per second, between -1000 and 1000
 // The steps per second argument is received as a string but may indicate // The steps per second argument is received as a string but may indicate
 // integer or fractional, positive or negative (i.g. "​-100",​ "​10",​ "​0.25"​) // integer or fractional, positive or negative (i.g. "​-100",​ "​10",​ "​0.25"​)
Line 229: Line 233:
     sprintf(outStr,​ "​Unable to convert \"​%s\"​ to float",​ strStepsPerSecond.c_str());​     sprintf(outStr,​ "​Unable to convert \"​%s\"​ to float",​ strStepsPerSecond.c_str());​
     Particle.publish("​setSpeed() error",​ outStr);     Particle.publish("​setSpeed() error",​ outStr);
 +    stepSpeed = 0;
 +    return -1;
 +  }
 +  // Reject speeds over 1000 steps/sec:
 +  if (stepSpeed<​-1000 || stepSpeed>​1000){
 +    Particle.publish("​setSpeed() error",​ "speed must be between -1000.0 and 1000.0 steps/​sec"​);​
     stepSpeed = 0;     stepSpeed = 0;
     return -1;     return -1;
Line 245: Line 255:
   digitalWrite(pinDirection,​ (stepDirection>​0) ? HIGH : LOW );   digitalWrite(pinDirection,​ (stepDirection>​0) ? HIGH : LOW );
   ​   ​
-  // Calculate step period (ms between steps) ​and prescribe wait time between steps:+  // Calculate step period (ms between steps):
   stepPeriodMs = (stepSpeed==0) ? 1000 : 1000/​stepSpeed; ​ //ms   stepPeriodMs = (stepSpeed==0) ? 1000 : 1000/​stepSpeed; ​ //ms
-  waitBetweenStepsMs = stepPeriodMs - durationStepPulseMs;​ // wait = period - pulseduration 
   ​   ​
   return stepPeriodMs;​   return stepPeriodMs;​
Line 282: Line 291:
 void doOneStep(){ void doOneStep(){
   digitalWrite(pinStep,​ HIGH); ​ // start step pulse   digitalWrite(pinStep,​ HIGH); ​ // start step pulse
-  ​delay(durationStepPulseMs);   ​// hold step pulse+  ​delayMicroseconds(durationStepPulseMicroseconds); // hold step pulse
   digitalWrite(pinStep,​ LOW);   // stop step pulse   digitalWrite(pinStep,​ LOW);   // stop step pulse
 } }
Line 292: Line 301:
   * **motion(start)** starts motion, if you previously configured speed and direction.   * **motion(start)** starts motion, if you previously configured speed and direction.
   * **motion(stop)** stops motion.   * **motion(stop)** stops motion.
-  * **setspeed(**[stepsPerSecond]**)** sets the motor speed in steps per second. +  * **setspeed**(stepsPerSecond) sets the motor speed in steps per second. 
-    This accepts ​floating point values.  ​For example, value 0.5 steps step per 2 seconds. +      Accepts ​floating point values ​between -1000 and 1000.  ​ 
-    * You can command a different speed while the motor is running. +      * Example: speed of 0.5 steps/sec will step once per 2 seconds. 
-  * setdir(-1 or 1) sets motor direction. ​  +      * Negative values set direction negative. 
-    * Whether 1 corresponds to CW or CCW depends on which coil you hooked up to A and B. +      ​* You can command a different speed while the motor is running. 
-    * You can command a different direction while the motor is running.+  ​* **setdir**(-1 or 1) sets motor direction. ​  
 +      * Whether 1 corresponds to CW or CCW depends on which coil you hooked up to A and B. 
 +      * You can command a different direction while the motor is running.
  
  
Line 316: Line 327:
     <form action="​https://​api.particle.io/​v1/​devices/​MY_DEVICE_ID/​setspeed"​ method="​POST"​ target="​replyFrame">​     <form action="​https://​api.particle.io/​v1/​devices/​MY_DEVICE_ID/​setspeed"​ method="​POST"​ target="​replyFrame">​
       <input type="​hidden"​ name="​access_token"​ value="​MY_ACCESS_TOKEN"​ />        <input type="​hidden"​ name="​access_token"​ value="​MY_ACCESS_TOKEN"​ /> 
-   Set speed (-2000.0:2000.0):  ​+   Set speed (-1000.0 : 1000.0):  ​
       <input type="​text"​ name="​speed"​ value="">​       <input type="​text"​ name="​speed"​ value="">​
       <input type="​submit"​ value="​Submit">​       <input type="​submit"​ value="​Submit">​
Line 372: Line 383:
 As noted in the stepper motor overview above, stepper motors can only reach a finite set of positions. ​ A stepper motor with 200 steps/rev, for example, can only position within 0.9° from an arbitrary target position, when operated in full-step mode.  If you require better accuracy, consider researching and experimenting with [[https://​en.wikipedia.org/​wiki/​Stepper_motor#​Microstepping|micro-stepping]]. ​ The A4988 facilitates micro-stepping to 1/16th-step resolution, and enabling this function is quite simple. ​ If you want to use 1/4, 1/8, or 1/16th step sizes exclusively,​ then you can configure the A4988 for this with 1, 2, or 3 additional jumpers or resistors, respecively. ​ If you want to toggle between step sizes, then connect 3 Oak GPIO pins to the A4988 MS1, MS2, and MS3 pins and update the sketch to manage these pins. As noted in the stepper motor overview above, stepper motors can only reach a finite set of positions. ​ A stepper motor with 200 steps/rev, for example, can only position within 0.9° from an arbitrary target position, when operated in full-step mode.  If you require better accuracy, consider researching and experimenting with [[https://​en.wikipedia.org/​wiki/​Stepper_motor#​Microstepping|micro-stepping]]. ​ The A4988 facilitates micro-stepping to 1/16th-step resolution, and enabling this function is quite simple. ​ If you want to use 1/4, 1/8, or 1/16th step sizes exclusively,​ then you can configure the A4988 for this with 1, 2, or 3 additional jumpers or resistors, respecively. ​ If you want to toggle between step sizes, then connect 3 Oak GPIO pins to the A4988 MS1, MS2, and MS3 pins and update the sketch to manage these pins.
  
- +Hope you found this useful!
oak/tutorials/stepper_motor.txt · Last modified: 2017/01/14 16:52 by Rover#18