Stepper motor control with 1 button

Hi, i am new to Arduino.

Im looking for a scetch for a stepper motor. I want it to run a stepper for a certain amount of steps when a input button is LOW. Then when a input button is HIGH reverse the stepper dirction for a certain amount of steps. Using Visuino i have managed to get one direction and stop but can not get it to reverse just using one button.

Stepper is a 4 wire.

Any help would be greatful.
Thank you

That's unknown here. What is it?
Start by using some simple example code and modify it to suit Your needs. Have a look into the example folder in the IDE.

This i what Visuino has created for me, which i watched a video on utube. If i press the button i with step in one direction. But what im after, when i release the button the stepper will reverse for a certiain amount of steps.

#define VISUINO_ARDUINO_AVR4809
#define VISUINO_ARDUINO_NANO_EVERY

#include <OpenWire.h>
#include <Mitov.h>
#include <Mitov_LogicGates.h>
#include <Mitov_Counter.h>
#include <Mitov_BinaryGenerators.h>
#include <Mitov_Stepper.h>

// Shared Component Member Variables

namespace ComponentVariables
{
class
{
public:
bool Value1 : 1;
uint32_t Value2 : 31;
bool Value3 : 1;
uint32_t Value4 : 4;
bool Value5 : 1;
bool Value6 : 1;

} BitFields;

class Variable1
{
public:
inline static bool GetValue() { return BitFields.Value1; }
inline static void SetValue( bool AValue ) { BitFields.Value1 = AValue; }

};

class Variable2
{
public:
inline static uint32_t GetValue() { return BitFields.Value2; }
inline static void SetValue( uint32_t AValue ) { BitFields.Value2 = AValue; }

};

class Variable3
{
public:
inline static bool GetValue() { return BitFields.Value3; }
inline static void SetValue( bool AValue ) { BitFields.Value3 = AValue; }

};

class Variable4
{
public:
inline static uint32_t GetValue() { return BitFields.Value4; }
inline static void SetValue( uint32_t AValue ) { BitFields.Value4 = AValue; }

};

class Variable5
{
public:
inline static bool GetValue() { return BitFields.Value5; }
inline static void SetValue( bool AValue ) { BitFields.Value5 = AValue; }

};

class Variable6
{
public:
inline static bool GetValue() { return BitFields.Value6; }
inline static void SetValue( bool AValue ) { BitFields.Value6 = AValue; }

};

} // ComponentVariables

// Arduino Constant Declarations

namespace VisuinoConstants
{
class FloatValue0
{
public:
inline static constexpr float GetValue() { return 100; }
};

class FloatValue1
{
public:
inline static constexpr float GetValue() { return 0; }
};

} // VisuinoConstants

// Pin Call Declarations

namespace PinCalls
{
class PinCallerReceive0
{
public:
void Notify( void *_Data );

};
class PinCallerReceive1
{
public:
void Notify( void *_Data );

};
class PinCallerReceive2
{
public:
void Notify( void *_Data );

};
class PinCallerReceive3
{
public:
void Notify( void *_Data );

};
} // PinCalls

// Arduino Board Declarations

namespace BoardDeclarations
{
namespace Types
{
typedef Mitov::ArduinoDigitalOutputChannel<
Mitov::ConstantProperty<22, bool, false >, // IsAnalog
Mitov::ConstantProperty<24, bool, false >, // IsCombinedInOut
Mitov::ConstantProperty<21, bool, false >, // IsOpenDrain
Mitov::ConstantProperty<26, bool, false >, // IsOutput
Mitov::ConstantProperty<20, bool, false >, // IsPullDown
Mitov::ConstantProperty<5, bool, true >, // IsPullUp
Mitov::ConstantProperty<23, bool, false >, // IsRawInput
Mitov::DigitalPin_EmbeddedPinImplementation<6, ::PinCalls::PinCallerReceive0 >, // OutputPin
6 // PIN

ArduinoDigitalChannel_6;
} // Types

namespace Instances
{
Types::ArduinoDigitalChannel_6 ArduinoDigitalChannel_6;
} // Instances

} // BoardDeclarations

// Declarations

namespace Declarations
{
namespace Types
{
typedef Mitov::BooleanInverter<
Mitov::ConstantProperty<4, bool, true >, // Enabled
Mitov::DigitalPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive1 > // OutputPin

Inverter1;
} // Types

namespace Instances
{
Types::Inverter1 Inverter1;
} // Instances

namespace Types
{
typedef Mitov::UpDownCounter<
Mitov::ConstantProperty<4, bool, true >, // Enabled
Mitov::TypedVariableMinMax<20, int32_t, ::ComponentVariables::Variable2, 0, 2147483647 >, // FCount
Mitov::ConstantProperty<6, int32_t, 1000 >, // InitialValue
Mitov::NestedProperty<14, Mitov::GenericValueLimit<
Mitov::ConstantProperty<13, bool, true >, // RollOver
Mitov::ConstantProperty<12, int32_t, 2147483647 > // Value
> >, // Value_Max
Mitov::NestedProperty<10, Mitov::GenericValueLimit<
Mitov::ConstantProperty<9, bool, false >, // RollOver
Mitov::ConstantProperty<8, int32_t, 0 > // Value
> >, // Value_Min
Mitov::TypedVariable<18, bool, ::ComponentVariables::Variable1 >, // NeedsUpdate
Mitov::TypedPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive2, int32_t > // OutputPin

UpDownCounter1;
} // Types

namespace Instances
{
Types::UpDownCounter1 UpDownCounter1;
} // Instances

namespace Types
{
typedef Mitov::PulseGenerator<
Mitov::ConstantPropertyFloat<8, float, ::VisuinoConstants::FloatValue1 >, // Asymmetry
Mitov::ConstantProperty<4, bool, true >, // Enabled
Mitov::ConstantPropertyFloat<17, float, ::VisuinoConstants::FloatValue1>, // FPhase
Mitov::TypedVariable<15, bool, ::ComponentVariables::Variable3 >, // FValue
Mitov::ConstantPropertyFloat<7, float, ::VisuinoConstants::FloatValue0 >, // Frequency
Mitov::ConstantProperty<5, bool, false >, // InitialValue
Mitov::DigitalPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive3 >, // OutputPin
Mitov::ConstantPropertyFloat<9, float, ::VisuinoConstants::FloatValue1 >, // Phase
Mitov::NestedProperty<14, Mitov::TArduinoGeneratorWhenDisabled<
Mitov::ConstantProperty<13, bool, false >, // CompleteCycle
Mitov::ConstantProperty<12, bool, true >, // FCycleCompleted
Mitov::ConstantProperty<11, bool, false > // Reset
> > // WhenDisabled

PulseGenerator1;
} // Types

namespace Instances
{
Types::PulseGenerator1 PulseGenerator1;
} // Instances

namespace Types
{
typedef Mitov::StepperMotor4Wire<
Mitov::ConstantProperty<4, bool, true >, // Enabled
Mitov::ConstantProperty<15, uint32_t, 0 >, // FLastTime
Mitov::TypedVariable<13, uint32_t, ::ComponentVariables::Variable4 >, // FStep
Mitov::ConstantProperty<12, bool, true >, // HalfStep
Mitov::DigitalPin_DirectBoardPinImplementation<8 >, // OutputPins_0
Mitov::DigitalPin_DirectBoardPinImplementation<9 >, // OutputPins_1
Mitov::DigitalPin_DirectBoardPinImplementation<10 >, // OutputPins_2
Mitov::DigitalPin_DirectBoardPinImplementation<11 >, // OutputPins_3
Mitov::ConstantProperty<5, bool, true >, // Reversed
Mitov::ConstantPropertyFloat<6, float, ::VisuinoConstants::FloatValue1 > // StepsPerSecond

Stepper1;
} // Types

namespace Instances
{
Types::Stepper1 Stepper1;
} // Instances

} // Declarations

// Type Converters

namespace TypeConverters
{
Mitov::Convert_BinaryToClock<Mitov::TypedVariable<0, bool, ::ComponentVariables::Variable5 >> Converter0;
Mitov::Convert_BinaryToClock<Mitov::TypedVariable<0, bool, ::ComponentVariables::Variable6 >> Converter1;
} // TypeConverters

// Pin Call Declarations

namespace PinCalls
{
void PinCallerConverterReceive1( void *_Data );
void PinCallerConverterReceive2( void *_Data );
} // PinCalls

// Pin Call Implementations

namespace PinCalls
{
void PinCallerReceive0::Notify( void *_Data )
{
Declarations::Instances::Inverter1.InputPin_o_Receive( _Data );
}

void PinCallerReceive1::Notify( void *_Data )
{
TypeConverters::Converter0.Convert( _Data, PinCallerConverterReceive1 );
}

void PinCallerConverterReceive1( void *_Data )
{
Declarations::Instances::UpDownCounter1.ResetInputPin_o_Receive( _Data );
}
void PinCallerReceive2::Notify( void *_Data )
{
Declarations::Instances::Stepper1.StepInputPin_o_Receive( _Data );
}

void PinCallerReceive3::Notify( void *_Data )
{
TypeConverters::Converter1.Convert( _Data, PinCallerConverterReceive2 );
}

void PinCallerConverterReceive2( void *_Data )
{
Declarations::Instances::UpDownCounter1.DownInputPin_o_Receive( _Data );
}
} // PinCalls

namespace ComponentsHardware
{
void SystemUpdateHardware()
{
}
} // ComponentsHardware

//The setup function is called once at startup of the sketch
void setup()
{
BoardDeclarations::Instances::ArduinoDigitalChannel_6.SystemInit();
Declarations::Instances::UpDownCounter1.SystemInit();
BoardDeclarations::Instances::ArduinoDigitalChannel_6.SystemStart();
Declarations::Instances::UpDownCounter1.SystemStart();
Declarations::Instances::PulseGenerator1.SystemStart();
}

// The loop function is called in an endless loop
void loop()
{
BoardDeclarations::Instances::ArduinoDigitalChannel_6.SystemLoopBegin();
Declarations::Instances::PulseGenerator1.SystemLoopBegin();
}

Thanks. The task is quite small, reading a button and moving a stepper.
The code You posted is like shooting mosquitos with HIMARS....
Not doing much of real C## programming I'll not look into that massive stuff.
You managed to put in one button pressing and the stepping, What stops You from putting in a second button action and reverse stepping? Either You learn more about Visuino or learn how to write that output Yourself.

1 Like

The application its going on can only have one button. Maybe it might be easier if i use a NO and NC switch then use two input pins and try and get it to step.

One button gives two states. One is On and one is Off. Code On for forward and Off for backward?
Using a switch makes what difference? The input reads either a HIGH or a LOW.

What stepper driver and stepper motor do you use? Data sheets, please.

Can you post a schematic. Hand drawn, photographed and posted is fine. Include all pin names/numbers, components, their part numbers and/or values and power supplies.

How about one press of the button and the motor moves forward a fixed nuimber of steps and stops then another press of the button and the motor reverses a fixed number of steps and stops. That could be easily done using the state change detection method and the MobaTools stepper library (using the Arduino IDE, I don't do Visuino).

Hello, sorry for the late reply all my family got a bug.

I need it to be one button operation, for example 500 steps one direction with button pushed, once button is released 500 steps in reverse. I'm not 100% sure on how many steps i currently need, i will need to experiment with it.

The steppers are 28byj-28 4 wire 5v
driver uln2003an
Arduino nano every
driver uln2003an
5v regulator

Steppers connected to pinws 8,9,10 and 11
push button is on GND to pin 6

Thank you

Here is a tested example that, I think, will do what you want to do. It uses the MobaTools stepper library and the state change detection method previously linked. Also Blink without delay() for timing.

Install the MobaTools library using the IDE library manager.

The example uses a NO push button switch attached to pin 6, wired to ground and the input pinMode is set to INPUT_PULLUP. The motor rotates 500 steps CW when the switch is pressed and stops until the switch is released. Upon release the motor rotates 500 steps CCW and stops until the switch is pressed again. Rinse, repeat.

#include <MobaTools.h>

const byte switchPin = 6;

// motor pins
const byte in1 = 8;
const byte in2 = 9;
const byte in3 = 10;
const byte in4 = 11;

MoToStepper stepper(2048, FULLSTEP);

void setup()
{
  Serial.begin(115200);

  pinMode(switchPin, INPUT_PULLUP);  

 stepper.attach( in1, in2, in3, in4 );
 stepper.setSpeed(100);
 stepper.setRampLen(5);
}

void loop()
{
  static bool lastSwitchState = 0;
  static unsigned long timer = 0;
  unsigned long interval = 50;
  if(millis() - timer > interval)
  {
     timer = millis();
     bool switchState = digitalRead(switchPin);
     if(switchState != lastSwitchState)
     {
        if(switchState == LOW)
        {
           stepper.move(500);
        }
        else
        {
           stepper.move(-500);
        }
        lastSwitchState = switchState;
     }
  }
}

If you absolutely must use Visuino, I suggest that you post your question in the Visuino forum.

Thank you so much for your help.

This is a project i'm working on for my disabled daughter to make a aid for her.

I tried Visuino just because was watching youtube :flushed: I have only just tried to learn Arduino.

I have copied in to Arduino IDE and getting this error message:-

WARNING: library MobaTools claims to run on avr, STM32F1, STM32F4, esp8266, esp32 architecture(s) and may be incompatible with your current board which runs on megaavr architecture(s).
In file included from C:\Users\Adrian\AppData\Local\Temp.arduinoIDE-unsaved202286-15576-17w2fyx.pskf\sketch_sep6a\sketch_sep6a.ino:1:0:
C:\Users\Adrian\Documents\Arduino\libraries\MobaTools\src/MobaTools.h:138:6: error: #error Processor not supported
#error Processor not supported
^~~~~
In file included from C:\Users\Adrian\Documents\Arduino\libraries\MobaTools\src/MobaTools.h:162:0,
from C:\Users\Adrian\AppData\Local\Temp.arduinoIDE-unsaved202286-15576-17w2fyx.pskf\sketch_sep6a\sketch_sep6a.ino:1:
C:\Users\Adrian\Documents\Arduino\libraries\MobaTools\src/utilities/MoToBase.h:25:6: error: #error "Processor not supported"
#error "Processor not supported"
^~~~~

exit status 1

Compilation error: exit status 1

Again thank you for your help

I have also just thought, i think i will have to fit a limit switch. If my daughter accidently double presses the button it will forse the stepper further than it can physically go.

Yes, unfortunately, the Nano Every is not yet supported by MobaTools. Work on it has already started, but at the moment I have a lot on my plate and cannot continue working on it.

ok no problem, thank you any way

I have made a bit of progress, i now have the stepper rotating different directions with just one button.

My issue now is i want to add limit switch, so when switchcw LOW dirstatus = 1 and switchstop = LOW dirstatus 3, i want the stepper to stop. I have put the two switches in one line but its not stopping the stepper? What do i need to add in?

Many thanks

int Pin1 = 8;//IN1 is connected to 10 
int Pin2 = 9;//IN2 is connected to 11  
int Pin3 = 10;//IN3 is connected to 12  
int Pin4 = 11;//IN4 is connected to 13 
int switchCW  =7;//define input pin for CW push button
int switchStop=6;//define input pin for Stop push button


 
int pole1[] ={0,0,0,0, 0,1,1,1, 0};//pole1, 8 step values
int pole2[] ={0,0,0,1, 1,1,0,0, 0};//pole2, 8 step values
int pole3[] ={0,1,1,1, 0,0,0,0, 0};//pole3, 8 step values
int pole4[] ={1,1,0,0, 0,0,0,1, 0};//pole4, 8 step values


int poleStep = 0; 
int  dirStatus = 3;// stores direction status 3= stop (do not change)

void setup() 
{ 
 pinMode(Pin1, OUTPUT);//define pin for ULN2003 in1 
 pinMode(Pin2, OUTPUT);//define pin for ULN2003 in2   
 pinMode(Pin3, OUTPUT);//define pin for ULN2003 in3   
 pinMode(Pin4, OUTPUT);//define pin for ULN2003 in4   
 
 pinMode(switchCW,INPUT_PULLUP);// CW push button pin as input
 pinMode(switchStop,INPUT_PULLUP);//Stop push button pin as input 


} 
 void loop() 
{ 
  
  if(digitalRead(switchCW) == LOW) 
  {
    dirStatus =1;
  }else if(digitalRead(switchCW) == HIGH)

  
  {
   dirStatus  = 2;  
  }else if(digitalRead(switchStop) == LOW && digitalRead(switchCW) == LOW)
  {
    dirStatus =3; 
  }
 if(dirStatus ==1){ 
   poleStep++; 
    driveStepper(poleStep);    
 }else if(dirStatus ==2){ 
   poleStep--; 
    driveStepper(poleStep);    
 }else{
  driveStepper(8);   
 }
 if(poleStep>7){ 
   poleStep=0; 
 } 
 if(poleStep<0){ 
   poleStep=7; 
 } 
 delay(1); 

}// loop


void driveStepper(int c)
{
     digitalWrite(Pin1, pole1[c]);  
     digitalWrite(Pin2, pole2[c]); 
     digitalWrite(Pin3, pole3[c]); 
     digitalWrite(Pin4, pole4[c]);   
}//driveStepper end here




This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.