Multiple Things With Delay()

Hi,
I have to drive a stepper motor creating a square wave. Sometimes I want to use a sensor but the function of the sensor contains a delay of some milliseconds. The function is contained in an external library so I cant modify it. Obviously when I call the function the loop and also the stepper motor stop. There is a way to avoid this? I think no but maybe there are method that I dont know.
I post a very simple example sketch to make you understand the problem.

void mySensor(){
  //other instructions
  delay(10);
}

void setup() {
  pinMode(7,OUTPUT); //pin connected to a stepper motor driver
}

void loop() {
  //square wave to drive the motor
  digitalWrite(7,HIGH);
  delayMicroseconds(500);
  digitalWrite(7,LOW);
  delayMicroseconds(500);
  mySensor(); //now the loop stops for 10ms
}

Thanks.

Jaason:
The function is contained in an external library so I cant modify it.

You certainly can, that's the beauty of the Open Source paradigm. Make your own copy of the library files with a different name. Then modify it to be non-blocking.

What type of sensor and which library ?

gfvalvo:
You certainly can, that's the beauty of the Open Source paradigm. Make your own copy of the library files with a different name. Then modify it to be non-blocking.

Yes I could but I'm not so good at programming and it would be my first time...

UKHeliBob:
What type of sensor and which library ?

Sensor TCS34725 with the Adafruit library;
The sensor has an integration time (I use the function GetRawData).

Maybe I can generate a square wave with PWM but then it would be difficult to count the pulses (->step of the motor), I dont know

Thanks

Your mySensor() function contains a delay of 10 milliseconds. Therefore, your code execution will be delayed by that time.

What is the relationship between the sensor output and the stepper movement? How do you want the stepper to move depending on what is read by the sensor?

@Jaason, have a look at this: [SOLVED] Reading from TCS34725 slows down subsequent functions - Sensors - Arduino Forum

@Jaason

I had the exact same problem and fellow posters pointed me in the right direction. The approach below, a bit shortened from the Adafruit library example, helps to surf around the sensor delaying loop() execution. Here, a servo function and a random number function tick away with millis() while the sensor reads with 700ms. Give it a try.

#include <Wire.h>
#include <Servo.h>
#include <Adafruit_TCS34725.h>

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
const int interruptPin = 2;
volatile boolean state = false;

const byte timeServoInterval = 6;
int timeSimUserInterval; // Set "do something" interval programmatically
unsigned long timeNowServo = 0;
unsigned long timeNowUser = 0;

int angleCurrent;
int angleTarget;

Servo ovres;

void isr()
{
  state = true;
}

/* tcs.getRawData() does a delay(Integration_Time) after the sensor readout.
  We don't need to wait for the next integration cycle because we receive an interrupt when the integration cycle is complete*/
void getRawData_noDelay(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
{
  *c = tcs.read16(TCS34725_CDATAL);
  *r = tcs.read16(TCS34725_RDATAL);
  *g = tcs.read16(TCS34725_GDATAL);
  *b = tcs.read16(TCS34725_BDATAL);
}

void setup()
{
  pinMode(interruptPin, INPUT_PULLUP); //TCS interrupt output is Active-LOW and Open-Drain
  attachInterrupt(digitalPinToInterrupt(interruptPin), isr, FALLING);

  Serial.begin(19200);
  
  tcs.begin();
  tcs.write8(TCS34725_PERS, TCS34725_PERS_NONE); // Set persistence filter to generate an interrupt for every RGB Cycle, regardless of the integration limits
  tcs.setInterrupt(true);

  randomSeed(analogRead(0));
  ovres.attach(3);
  ovres.write(0);
  angleCurrent = ovres.read(); // Seed with initial value to start
  angleTarget = random(0, 180); // Seed with initial value to start
}

void loop()
{
  readSensor();
  simulateUserInput(); // Values (°) randomly generated within a range
  rotateServo();
}

void readSensor()
{
  if (state)
  {
    uint16_t r, g, b, c;
    getRawData_noDelay(&r, &g, &b, &c);

    Serial.print("R: "); Serial.print(r, DEC); Serial.print(" ");
    Serial.print("G: "); Serial.print(g, DEC); Serial.print(" ");
    Serial.print("B: "); Serial.print(b, DEC); Serial.print(" ");
    Serial.print("C: "); Serial.print(c, DEC); Serial.print(" ");
    Serial.println(" ");

    tcs.clearInterrupt();
    state = false;
  }
}

void rotateServo()
{
  if (millis() - timeNowServo >= timeServoInterval) // Check if it is time to rotate
  {
    timeNowServo = millis(); // Record the current time
    if (angleCurrent != angleTarget) // Don't write to servo if target angle is reached
    {
      if (angleCurrent <= angleTarget)
      {
        angleCurrent ++;
        ovres.write(angleCurrent);
      }
      else
      {
        if (angleCurrent >= angleTarget)
        {
          angleCurrent --;
          ovres.write(angleCurrent);
        }
      }
    }
  }
}

void simulateUserInput() // Set target angle programmatically (later through user input)
{
  if (millis() - timeNowUser > timeSimUserInterval)
  {
    timeNowUser = millis();
    timeSimUserInterval = random(1000, 8000);
    angleTarget = random(0, 180);
  }
}