/* example for controlling a bipolar steppermotor
with 4 buttons and a potentiometer (for adjusting the speed)
in this example three different parts of the MobaTools are used
MotoStepper, MoToButtons, MoToTimeBase
each of the 4 button makes the steppermotor drive to a pre-defined position
in case the button is pressed
a double-press (double-click) of a button 1/2 activates ENDLESS rotation
double-click of button 1 => endless rotation forward
double-click of button 2 => endless rotation backward
double-click of button 3 => stop
looong press of button 4 => initiate reference
in this example referenceing is coded as a blocking function
this means if referencing is active the code can do nothing else but the referencing
until referencing has finished successfully
The internal LED is switched on if reference-switch is active
*/
#define MAX8BUTTONS // spart Speicher, da nur 4 myButtons benötigt werden
#include <MobaTools.h>
const int STEPS_REVOLUTION = 800;
//create stepper-object ( 800 steps / revolution = 1/4 Microstep )
MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );
const byte dirPin = 5;
const byte stepPin = 6;
const byte enaPin = 7;
// create buttons ( the code expects that the buttons are wired IO-Pin---button----GND )
enum { button1, button2, button3, button4 } ; // assign the button-names the index-numbers 0,1,2,3
const byte buttonPins[] = {A1, A2, A3, A4 }; // must be defined as byte that the calculation works
const byte buttonNr = sizeof(buttonPins);
const long buttonPos[] = { 1600, 3200, 6400, 7600 };
MoToButtons myButtons( buttonPins, buttonNr, 20, 500 );
// reference / limit-switch
const byte refPin = A5; // IO-pin for limit-switch
const byte atRefpoint = LOW; // if limit-switch is triggered the logic level is LOW
MoToTimebase speedIntervall; // time-interval for reading speed potentiometer
const byte potiPin = A0; //potentiometer for speed
int vspeed = 0; //Stepperspeed in rev/min*10
int oldSpeed = 0; // nescessary for detecting speed-changes
void toRefPoint() {
// drive stepper to reference-point then set position to 0
Serial.println("drive fast towards reference-point");
// driving fast to reference ...
if ( digitalRead( refPin ) != atRefpoint ) {
// ... onyl in case steppermotor is not already at reference-point
myStepper.setSpeedSteps( 20000, 100 );
myStepper.rotate(-1);
while ( digitalRead( refPin ) != atRefpoint );
}
Serial.println("limit-switch triggered STOP");
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
// limit-switch reached stop
myStepper.rotate(0);
while ( myStepper.moving() ); // wait until deccelerating has finished;
// drive slowly without acceleration until limit-switch changes state
myStepper.setSpeedSteps( 1000 );
myStepper.setRampLen(0); // de-activate acceleration through value zero
// remark myStepper.rotate( 1 ) must be called only a SINGLE time
// the MobaTools will create a infinite train of step-pulses
// in the background until you execute function myStepper.rotate(0) or myStepper.stop()
Serial.println("driving away from limit-switch until limit-switch is NOT triggered anymore");
myStepper.rotate( 1 );
// wait for limit-switch to change state
while ( digitalRead( refPin ) == atRefpoint );
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
Serial.println("limit-switch unpressed => reference reached");
myStepper.rotate(0);
while (myStepper.moving() );
myStepper.setZero();
myStepper.setSpeed( 200 );
// re-actiavte acceleration
myStepper.setRampLen( 100 ); // number of steps for used for acceleration 100 Steps
oldSpeed = 0; // set to zero to make sure value of potentiometer is used
Serial.println("end of referencing");
}
void setup() {
Serial.begin(115200);
while (!Serial);
myStepper.attach( stepPin, dirPin );
myStepper.attachEnable( enaPin, 10, LOW ); // activate Enable Pin ( LOW=active )
myStepper.setSpeed( 200 );
vspeed = 200;
myStepper.setRampLen( 100 ); // number of steps for used for acceleration 100 Steps
speedIntervall.setBasetime( 100 ); // set timer-intervall to 100 millisecons
pinMode(LED_BUILTIN, OUTPUT);
pinMode(refPin, INPUT_PULLUP );
toRefPoint();
}
void loop() {
myButtons.processButtons(); // reading in myButtons and check for pressed / released, double-press, long-press
digitalWrite( LED_BUILTIN, digitalRead( refPin ) );
// read in speed from potentiometer once every 100 milliseconds
if ( speedIntervall.tick() ) {
// if 100 milliseconds have passed by ( see function-call speedIntervall.setBasetime(); in setup()
vspeed = map((analogRead(potiPin)), 0, 1023, 20, 1800); // map values to 2 ... 180 rev/Min
//min speed =2 and max speed =180 rpm
if ( abs( oldSpeed - vspeed ) > 5 ) {
myStepper.setSpeed( vspeed );
oldSpeed = vspeed;
}
}
// initiate referencing
if ( myButtons.longPress( button4 ) ) toRefPoint();
//
for ( byte tastIx = 0; tastIx < buttonNr; tastIx++ ) {
// check myButtons for Click/double-click
byte clickTyp = myButtons.clicked(tastIx);
if ( clickTyp == SINGLECLICK ) {
//button single-press
Serial.print("rotate to Pos ");
Serial.println( buttonPos[tastIx] );
myStepper.writeSteps(buttonPos[tastIx]);
}
else if ( clickTyp == DOUBLECLICK ) {
// button double-click detected
switch ( tastIx ) {
case button1:
Serial.println("double-press of button 1 rotate endless forward");
myStepper.rotate(1);
break;
case button2:
Serial.println("double-press of button 2 rotate endless backwar");
myStepper.rotate(-1);
break;
case button3:
Serial.println("double-press of button 3 STOP!");
myStepper.rotate(0);
break;
default:
break;
}
}
}
}