Programming guidance

I need guidance to write a program to run stepper motor with three buttons.

a. With button 1, stepper shall start to run single step and count number of steps it run.
b. With button 2 freezes the number of steps it ran.
c. and when button 3 is pressed, motor should run freezed number of steps in same direction and shall stop after run.
d. After that when ever button 3 is pressed it should run same number steps until reset button is pressed.

I tried to write program but not satisfied with that

#include <AccelStepper.h>

#define HALFSTEP 8

#define motorPin1  8     // IN1 on ULN2003 ==> Blue   on 28BYJ-48
#define motorPin2  9     // IN2 on ULN2004 ==> Pink   on 28BYJ-48
#define motorPin3  10    // IN3 on ULN2003 ==> Yellow on 28BYJ-48
#define motorPin4  11    // IN4 on ULN2003 ==> Orange on 28BYJ-48

AccelStepper stepper(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

int Distance = 0;
long initial_homing = 1;

void setup() {
  Serial.begin(9600);
  pinMode(5, INPUT_PULLUP); // Button to initiate steps to move
  pinMode(6, INPUT_PULLUP); // Button to freeze steps to be moved by stepper
  pinMode(7, INPUT_PULLUP); // Button to Start the motor to run
}

void loop() {
  distanceTomove();
  Run_motor();
}

void distanceTomove() {
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(100);
  stepper.setAcceleration(1000);  // Set Acceleration

  if (digitalRead(5) == LOW) {
    stepper.moveTo(initial_homing);
    initial_homing++;
    delay(5);
    stepper.runSpeedToPosition();
  }
  if (digitalRead(6) == LOW) {
    Distance = initial_homing;
  }
}


void Run_motor() {
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(500);
  stepper.setAcceleration(1000);  // Set Acceleration

  if (digitalRead(7) == LOW) {
    stepper.moveTo(-Distance);
    stepper.runSpeedToPosition();
  }
}

In what way(s), exactly, are you unsatisfied with it?

Your program bears almost no resemblance to the prose description of the desired functionality.

I suggest you use some means to get the logic correct before you code a single line.

In the old days, ppl used flowcharts. This might help you.

a7

2 Likes

It is not working as intended.
a. It runs with button 1 and counts numbers of steps it ran.
b. with button 2 it doesn't freezes steps
c. with button 3, it return in reverse direction instead of forward.
d. it doesn't start again when button 3 is pressed again after completion of first cycle

Hello pankajsharma200

My advice:

Take a piece a paper and a pencil and design a program structure based on the IPO model before start coding.
The basics for coding the project are to be found in the IDE as examples.

Have a nice day and enjoy coding in C++.

p.s.

You might start with a function called button manager and a function to control the stepper in CW,CCW and Stopp.

2 Likes

I read this as you want button1 to go one step and increase a counter.
button3 should just "replay" the steps depending on the counter.

3 different states, IDLE, SINGLESTEP, REPLAY
the button1 and button3 have clear actions:

I don't understand what button2 should do.
@pankajsharma200 is the graphic correct? If not - what's missing?

code for graphic
/*
   edit graphic: https://dreampuf.github.io/GraphvizOnline/
   for: https://forum.arduino.cc/t/programming-guidance/1155310/6
   2023-08-05 by noiasca
*/

digraph G { 
  graph [
    label="Finite State Machine"
    labelloc="t"
    fontname="sans-serif"
  ]
  node [
    style=filled
    fillcolor=gray95
    fontname="sans-serif"
  ]
  
  IDLE -> SINGLESTEP [label="onButton1" fontsize=10]; 
  SINGLESTEP -> IDLE [label="done" fontsize=10]; 
  IDLE -> REPLAY [label ="onButton3" fontsize=10];
  REPLAY -> IDLE [label="done" fontsize=10]; 

  SINGLESTEP [label=<<b>SINGLESTEP</b><br/>go 1 step<br/>n++<br/>>];
  REPLAY [label=<<b>REPLAY</b><br/>go n steps<br/>>];
}

Idea is once button 2 is pressed, program should skip "DistanceTomove" step and it should not go in this loop to reestablish new distance.

I think that button 1 starts the stepping, button 2 stops the stepping.
Button 1 doesn't need pressing for each step, it just starts the learning process and button 2 stops and saves it..
OR
Button 1 makes a step on each application.
Button 2 saves the count puts the controller back ready to either relearn or do the auto steps when Button 3 is pressed.

Tom.. :grinning: :+1: :coffee: :australia:

You are correct.

Which one first or second?

Tom.. :grinning: :+1: :coffee: :australia:

First one

so button 1 starts and button2 stops?

Yes. Now I am puzzled how to skip "DistanceToMove" so that it does not go in this loop and whenever button 3 is pressed motor should run saved steps only every time.

Design and code a function called button manager as already mentioned.

1 Like

I am new to coding. Searching button manager on net.

button 2 just captures the current position, initial_homing, in the Distance variable

it moves to -Distance. did you want it to move another Distance?

1 Like

I hope .move() is blocking.
That would be my idea ... but I don't have your hardware:

untested:

#include <AccelStepper.h>

#define HALFSTEP 8

#define motorPin1  8     // IN1 on ULN2003 ==> Blue   on 28BYJ-48
#define motorPin2  9     // IN2 on ULN2004 ==> Pink   on 28BYJ-48
#define motorPin3  10    // IN3 on ULN2003 ==> Yellow on 28BYJ-48
#define motorPin4  11    // IN4 on ULN2003 ==> Orange on 28BYJ-48

AccelStepper stepper(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

int distance = 0;

const uint8_t startPin = 5;
const uint8_t stopPin = 6;
const uint8_t replayPin = 7;

enum State {IDLE, LEARN, REPLAY} state;

void initStepper() {
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(100);
  stepper.setAcceleration(1000);  // Set Acceleration
}

void runFSM() {
  switch (state) {
    case IDLE :
      if (digitalRead(startPin) == LOW) {
        state = LEARN;
        Serial.println(F("LEARN"));
      }
      if (digitalRead(replayPin) == LOW) {
        state = REPLAY;
        Serial.println(F("REPLAY"));
      }
      break;
    case LEARN:
      if (digitalRead(stopPin) == LOW) {
        state = IDLE;
        Serial.println(F("IDLE"));
      }
      stepper.move(1);
      distance++;
      delay(100); // just a dirty delay to slow down the movement
      break;
    case REPLAY:
      Serial.print(F("steps to go ")); Serial.println(distance);
      stepper.move(distance);
      state = IDLE;
      break;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(startPin, INPUT_PULLUP);  // Button to initiate steps to move
  pinMode(stopPin, INPUT_PULLUP);   // Button to freeze steps to be moved by stepper
  pinMode(replayPin, INPUT_PULLUP); // Button to Start the motor to run

  initStepper();
}

void loop() {
  runFSM();
  stepper.run(); // triggers the stepper if necessary
}

a. you are correct.
b. With button 3 pressed, it moves back to zero position. While intended is, it should move in one direction only. It should not return to Zero position.

so don't

do
stepper.moveTo( Distance);

1 Like

I checked this. Individual case are working in serial monitor but while Idle / Learn / Replay, Motor is not powering / steping .