I need advice on how to change this code to make my NEMA17 engine rotate smoothly and when I click on the button so that it starts spinning to the other side, now I only have the rotation, but the engine goes in steps and it would not be much because I need it for blinds
`// Define pins #include <Stepper.h>
const int stepsPerRevolution = 200;
const int reverseSwitch = 2; // Push button for reverse
int buttonState = 0;
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int lastState = 0; //cw=0, ccw = 1
int lastButtonState = LOW;
const int LED = 12;
enum state
{
WAITING,
MOVING_CW,
MOVING_CCW
};
byte currentState = WAITING;
int test = 0;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50;
void loop() {
digitalWrite(LED,HIGH);
if ((millis() - lastDebounceTime) > debounceDelay) {
switch (currentState)
{
case WAITING:
buttonState = digitalRead(reverseSwitch);
if (buttonState != lastButtonState) {
lastDebounceTime = millis();
}
if (buttonState == HIGH) {
test = 0;
}
if (lastState == 1 && buttonState == LOW && test == 0) //and move to state MOVING_CW or MOVING_CCW when pressed depending on previous direction
{
currentState = MOVING_CW;
lastState = 0;
} else if (lastState == 0 && buttonState == LOW && test == 0) {
currentState = MOVING_CCW;
lastState = 1;
}
else
{
currentState = WAITING;
if (buttonState == HIGH) {
test = 0;
}
}
break;
case MOVING_CW:
myStepper.step(stepsPerRevolution); //code to move CW until end, then set direction flag and set state to WAITING
currentState = WAITING;
lastState = 0;
test = 1;
lastDebounceTime = millis();
break;
case MOVING_CCW:
myStepper.step(-stepsPerRevolution);//code to move CCW until the end
currentState = WAITING;//then set direction flag and set state to WAITING
lastState = 1;
test = 1;
lastDebounceTime = millis();
break;
}
}
lastButtonState = buttonState;
}` //
How have you got your button wired?
If it connects the digital input pin HIGH when pressed, do you have a 10K resistor between the digital pin and gnd?
If it connects the digital input pin LOW when pressed, do you have a 10K resistor between the digital pin and 5V?
What model Arduino are you using?
Thanks.. Tom..
Can we please have a circuit diagram?
An image of a hand drawn schematic will be fine, include ALL power supplies, component names and pin labels.
without a resistor acting either as a pullup-resistor or as a pulldown-resistor the IO-pin is "floating" when the button is not pressed. The IO-pin will act as an antenna and pick up elecromagnetic noise that will make the logic state randomly sometimes HIGH sometimes LOW
The pullup/pulldown-resistor takes away the electromagnitic noise and gives a stable logic state when the button is not pressed.
The alternative is to use the internal pullup-resistor of the microcontroller. Then you have to connect your button between IO-pin and ground.
And in this case the logic is inverted.
The unpressed button gives a HIGH and the pressed button a LOW
instead of using the stepper-library stepper.h
I recommend to use the MobaTools-library
The MobaTools-library has th ebig advantage that your code can do other things in parallel to driving the stepper-motor very easy.
You can install the mobatools with the library manager of the arduino-IDE
The functions have different names but once you are familiar with them writing code is easy
I do not understand what this means.
It is a stepper-motor which really does steps.
You have to describe the behaviour of the stepper-motor in more details is the movement regular continuing but somehow rough
does the steppermotor rotate for some degrees smoothly and then stops / rotates /stops /rotates?
from your pictures I assume you are using a simple L298 H-bridge-driver.
Such a simple H-bridge can do only half-steps.
If you use a more advanced stepper-driver like a TMC2209 you can have a ver very smooth and almost silent rotation of the steppermotor.
to be clear, this is how I connected it and did it according to the video instructions, and it works as it should, I just need the motor to not always stop for a second and then continue in the same direction, but it always does 270°, stops for a second and then takes another step and so on, only I would need it not to stop, and to go in one piece, I know that it can be done when there are options in the arduino stepper settings, so I set it there and it rotated smoothly, but I couldn't use that because I needed and on the other side and control it with that button. So if you could help me just change my basic code so that it just spins smoothly and otherwise everything stays as it is, thanks
while maybe the stepper is wired correctly and works as it should, the code is not working as it should
all the code for handling the button make the code overly complicated. currentState is only changed in the WAITING state which is why it's stuck in the other state
i've posted a way to simplify the code. looks like you don't need a timer, so remove that and add you code stepper function calls to the cases in the code i posted OR delete the button processing code from your code and add the button code from mine which advances the state
look this over.
i modified your approach to constantly rotate the motor in one direction or the other while in the CW/CCW states so that the button can change state immediately without waiting for the stepper to complete the # of requested steps
#include <Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
const byte PinBut = A1;
byte butLst;
enum { Idle, CW, CCW };
int state = Idle;
// -----------------------------------------------------------------------------
void loop ()
{
// process state
switch (state) {
case Idle:
break;
case CCW:
myStepper.step (-1);
break;
case CW:
myStepper.step (1);
break;
}
// check for button press
byte but = digitalRead (PinBut);
if (butLst != but) {
butLst = but;
delay (20); // debounce
if (LOW == but) {
if (CCW < ++state) // advance state
state = Idle;
Serial.println (state);
}
}
}
// -----------------------------------------------------------------------------
void setup () {
Serial.begin (9600);
myStepper.setSpeed (200);
pinMode (PinBut, INPUT);
butLst = digitalRead (PinBut);
}
The code works the way I imagined, just a little perfection could possibly be done? The engine rotates a little bit by itself in steps and when I hold the button it spins as it should, could I do it that I would just click and the engine would spin itself like this?