How to prevent stepper motor from being interupted

Hello all,

New Arduino user here. My project goal is to control the speed of a stepper motor based on input from a light reflectance sensor array. I have an Arduino Leonardo, an A4988 stepper driver, and a Pololu QTR six-sensor array.

So far I have successfully driven the motor at 1000 steps/sec using the micro(s) timing signal with this code:

unsigned long halfstep = 500;
if (currentMicros-previousMicros >= halfstep)
{
  previousMicros = currentMicros;
  if (pinstate == LOW) {
    pinstate = HIGH;
  }
  else {
    pinstate = LOW;
  }
 digitalWrite(stepPin,pinstate);
}

I also have a working sensor routine that sums the digital readings of the six reflectance sensors:

unsigned long read_interval = 1000000;  
unsigned long currentMicros = micros();
int sensor_sum (0);
if (currentMicros-previousRead >= read_interval)
{
  previousRead=currentMicros;
  qtr.read(sensorValues);
   for (int i=0; i < 6; i++)
   {
  sensor_sum = sensor_sum + sensorValues[i];
   }  
   }

In the above the read interval is set to 1000000 microseconds or one second. Both of these routines work fine separately, but when I combine them in the same loop, the motor pulses gets interrupted every second while the sensor values are read causing a noticeable "jerk" in the motor. I guess the processor stops sending signals to the step pin while it reads the sensors. Is there any way to fix this?

Please post your combined code.

#include <QTRSensors.h>
QTRSensors qtr;
const uint8_t SensorCount = 6;
uint16_t sensorValues[SensorCount];


// defines pins numbers
const int stepPin = 12; 
const int dirPin = 13; 
unsigned long halfstep;
unsigned long previousMicros = 0;
unsigned long previousRead = 0;
int pinstate = LOW;

 
void setup()
 {
  // configure the sensors
qtr.setTypeRC();
  qtr.setTimeout(1000);
  qtr.setSensorPins((const uint8_t[]){3, 4, 5, 6, 7, 8}, SensorCount);
  //qtr.setEmitterPin(2);
  // Sets the two pins as outputs for motor drive
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction

}
void loop() 

{
unsigned long read_interval = 1000000;  
unsigned long currentMicros = micros();
// sensor read section
int sensor_sum (0);
if (currentMicros-previousRead >= read_interval)
{
  previousRead=currentMicros;
  qtr.read(sensorValues);
   for (int i=0; i < SensorCount; i++)
   {
     sensor_sum = sensor_sum + sensorValues[i];
   }  
   //halfstep=sensor_sum;
   }
// motor drive section
unsigned long halfstep = 500;

if (currentMicros-previousMicros >= halfstep)
{
  previousMicros = currentMicros;
  if (pinstate == LOW) {
    pinstate = HIGH;
  }
  else {
    pinstate = LOW;
  }
 digitalWrite(stepPin,pinstate);
}
}

The way to fix this is to use a timer-interrupt that creates the step-pulses.
an interrupt does what its name says: interrupting the "normal" program-execution
doing its thing and then normal code-execution continues.
An interrupt should finish its own work as quick as possible.
Switching an IO-pin from LOW to HIGH or HIGH to LOW is executed very fast

There are some steppermotor-libraries. Some of them have blocking step-signal-creation which means no other code can be executed as long as the step-creation is active.

Some have non-blocking step-signal-creation.
The MobaTools have non-blocking step-signal-creation

You can install the mobatools with the library-manager of the arduino-ide.
The examples have german comments. Whatever questions you have the author of the mobatools @MicroBahner can answer your questions in english too as many other users.

Take a look into the intervalStepper.ino demo-example
best regards Stefan

In case it isn't obvious, the stepper is waiting for sample timeout
You can probably use Waitmillisends($ as you
sample trigger using an If statement. I forgot the for the comparison but it's easy to find

You mean the

statement? I wonder if using the analog output version of the sensor would fix this. It doesn't need a timeout.

Yes

I could also just eliminate the timeout statement and then the sensor will default to a max value of 2500. I'll try it tomorrow.

Look at the part : previousmillis = current millis

It's basically what you are doing to control the motor step speed, but needs to be added to
control the sample delay as well.

I think I see, I need to move the timeout statement inside the sample loop, correct?