Code to control stepper motor and valves

Hi, I am trying to program the arduino to run a stepper motor while simultaneously turning on/off two solenoid valves. The current loop I have is as follows, which only allows the stepper motor to run after turning on/off the valves. How can I make the stepper motor start running first and have the valves switch on/off while the motor is in motion? Thank you!

void loop() {
  if (millis()<minutes * 4){ //number of cycles
    
   digitalWrite(2,HIGH); //valve 1
   digitalWrite(4,LOW); //valve 2
   myStepper.step(-750); //stepper motor

   digitalWrite(2,LOW); 
   digitalWrite(4,HIGH);
   myStepper.step(750);
    
  } else {
    digitalWrite(4,LOW);
    digitalWrite(2,LOW);

  }

my understanding is step() is blocking, which means it doesn't return until the motor has completed stepping that number of steps.

since turning on/off a solenoid should just require toggling an output bit, couldn't you just step the motor some fraction of the number you need, toggle the solenoid and then step the motor to complete the rotation?

That is a good possible solution. However, the tiny stop in the motor's motion affects the results of my application negatively. I am looking to keep the motor moving while switching on/off the solenoids as the motor moves. Is it possible to do with the arduino? From my understanding is that the microcontroller can only perform one task at a time...

how tiny is the stop?

i've found that i can't step a motor faster than once every msec. a lot could be done in a msec, certainly toggling a bit to control a solenoid

1 Like

Without looking at your full code or your connections, I venture to offer this skeleton of a possible solution. You will have to adjust the stepInterval, even changing it to microseconds, and decide what to do with the motor once the timeout is reached (the time out will not necessarily occur when steps = +750 or -750).

Also, you may have to fiddle with the motor speed (setSpeed()) or the step size to fine tune the motor performance

The code below is only a sample, it can be shortened if need be.

// Use a Finite State Machine to control two valves while rotating a stepper motor

enum  PossibleStates {RotatingLeft, RotatingRight, Stopped} 
	;

PossibleStates state  = RotatingLeft; // indicates where are we. Start rotating left

const unsigned long runTime = 4 * 60 * 1000L; // total time to go: stop after 4 minutes
const int stepsRequired = 750;
const int pinValve1 = 2;
const int pinValve2 = 4;
const unsigned long stepInterval = 1; // how many milliseconds to wait for next step

unsigned long nextStepTime; // when to step the motor.
unsigned long timeOut;

int stepCount;

void setup() {
	stepCount = 0;
	timeOut = millis() + runTime;
	nextStepTime = 0; // First time into the loop it will force a step

       // plus whatever else is required here
}

void loop() {

  // take a time snapshot
  unsigned long currentTime = millis();

  // is time out?
  if (currentTime - timeOut >= 0) {
    state = Stopped;
  }

  switch (state) {

    case Stopped:
      // note that a timeout can occur when the motor is not fully "right" or "left", so 
      // do we
      // 		stop motor?
      // 		wait for the motor to complete the number of steps (750)?
      // ...

      // turn valves off
      digitalWrite(pinValve1, LOW);
      digitalWrite(pinValve2, LOW);
      break;

    case RotatingLeft:
      // set valves. Possibly add logic to do this only once when the motor starts spining left
      digitalWrite(pinValve1, HIGH);
      digitalWrite(pinValve2, LOW);

      // has the step interval elapsed? -> step motor once
      if (currentTime - nextStepTime >= 0) {
        myStepper.step(-1); //step motor "left"

        nextStepTime = currentTime + stepInterval;

        stepCount++;
        if (stepCount >= stepsRequired) {
          // done with the required number of steps. Start rotating to the right upon next step Time
          state = RotatingRight;
          stepCount = 0;
        }
      }
      break;

    case RotatingRight:
      // set valves. Possibly add logic to do this only once when the motor starts spining right
      digitalWrite(pinValve1, LOW); // set valves. Possibly add logic to do this only once
      digitalWrite(pinValve2, HIGH);

      // has the step interval elapsed? -> step motor once
      if (currentTime - nextStepTime >= 0) {
        myStepper.step(1); //step motor "right"

        nextStepTime = currentTime + stepInterval;

        stepCount++;
        if (stepCount >= stepsRequired) {
          // done with the required number of steps. Next time into the loop, rotate left
          state = RotatingLeft;
          stepCount = 0;
        }
      }
      break;
  }
}

Please post your full code. And what Arduino and stepper motor are you using?

I assume you use the builtin stepper library. You need a non blocking library, that moves the stepper without blocking the sketch. An alternative could be to use my MobaTools library. This lib creates the step pulses by timer interrupts in the background and you are free to do what you like in loop while the stepper is turning.
There are several examples and a documentation in english ( the unfortunately only part of the examples are commented in english ).

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