Delay not working as expected

This project is pretty well explained in the code description. My main problem is I need a delay for digitalWrite(vacPin,LOW);. With this part included the stepper doesn’t react a quickly as before 2/3 sec lag, & the ACS712 current sensor does not read at all in the console screen. I have tried different operatives, statements, and relocating the code in different spots with no luck!
I think this has a simple fix, but it has alluded me!. Hope this is clear enough, any help would be appreciated.

/*This version works as is **EXCEPT** the Delay vac 4 sec has to be turned off. See ########### area for Problem.
/*Auto Blast gate project:  for dust collection in wood shop.
Arduino Nano
ACS712 current sensor
DRV8825 stepper driver
Nema 17 stepper
Each tool will be monitor by a current sensor and when that analog port exceeds a given threshold
1. Rotate the stepper to a predetermined position to align ports for that tool.
2. After the gate is align a digital pin will drive relay to turn on Vacuum system.
   Vacuum will stay on as long as sensor exceed the threshold while tool is running. 
   **When tool stops vacuum will continue for 4 seconds to clear remaining dust.**
3. If the same tool is used next, the Stepper will remain in it's current position.
   But the vacuum system should still operate the same.
4.  currently using buttons to simulate tools and also one ACS712 for testing  */


```
// defines pins numbers
const int stepPin = 3;
const int dirPin  = 2;
const int enPin  = 8;
const int vacPin = 4; //simulate Vacuum relay

int ca = 0;  //currentAngle
int na = 0;  //angle
int stepPerAngle = 5 / 9; // full step = 1.8 or could have used "*1.8"
int   numstep;
int analogValue = 0;

void setup() {
Serial.begin(9600);

// Sets the 3 pins as Outputs
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
pinMode(vacPin, OUTPUT); //Just added this for vac

//set values for 2 outputs
digitalWrite(enPin, LOW);
digitalWrite(dirPin, HIGH);
digitalWrite(vacPin, LOW); //just add this for vac


}

void loop() {
int n;
analogValue = 0;


// Assign button degrees
if      ( analogRead(A0) > 600) {
 analogValue = (analogRead(A0));
 Serial.print("AO = ");
 Serial.println(analogValue);
 na = 0; 
 
}
else if ( analogRead(A1) > 600) {
 analogValue = (analogRead(A1));
 Serial.print("A1 = ");
 Serial.println(analogValue);
 na = 45;    
}

else if ( analogRead(A2) > 600) {
 analogValue = (analogRead(A2));
 Serial.print("A2 = ");
 Serial.println(analogValue);
 na = 225;
}

else if ( analogRead(A3) > 600) {   //=tool on
analogValue = (analogRead(A3));
 Serial.print("A3 = ");
 Serial.println(analogValue);
 na = 270;

}


/*###########################################################
****this is where I need help.  The first if statement works as it should.**
**when those 2 condition are met the vacPin goes high.** */**  

if(analogValue > 600 && ca==na) {
 digitalWrite(vacPin, HIGH);
}

/* **this part is not working correctly.  If the delay is remove it works as the "else if" statment reads.
I need the delay so when a tool is stopped, the vacuum continues for a few secounds to clear remaining saw dust** */

else if (analogValue < 600) {
delay (4000); **/*  with this on:
          the stepper does not start as quickly as before,
          the analog will not read the ACS712 sensor at all,  only the buttons*/** 
 digitalWrite(vacPin, LOW);
}

//################################################################################

if ( ca != na ) {

//2nd SCENARIO
if (na - ca > 0 && na - ca <= 180)
 { digitalWrite(dirPin, HIGH);
   n = ((na - ca) * 5 / 9);
   numstep = n;
   ca = na;
  
 }

 //3rd SCENARIO
 else if (ca - na > 0 && ca - na > 180)
 { digitalWrite(dirPin, HIGH);
   n = ((na + 360 - ca) * 5 / 9);
   numstep = n;
   ca = na;
 }

 // 4th SCENARIO
 else if (na - ca < 0 && na - ca <= 180)
 { digitalWrite(dirPin, LOW);
   n = ((ca - na) * 5 / 9);
   numstep = n;
   ca = na;
 }

 //5th SCENARIO
 else if (na - ca > 0 && na - ca > 180)
 { digitalWrite(dirPin, LOW);
   n = ((ca + 360 - na) * 5 / 9);
   numstep = n;
   ca = na;   
}
 



 for (int x = 0; x < numstep; x++) {

   digitalWrite(stepPin, HIGH);
   delayMicroseconds(1000);  //speed
   digitalWrite(stepPin, LOW);
   delayMicroseconds(1000);



 }
 
 
 
 delay(200);
}

}

programmingarduino-nano

(Code tags fixed by Moderator)

have you tried a longer delay?
i’ve had problems driving stepper motor with < 2 msec delay

@GAMKCMO - I’d almost let it go, but I’m anal retentive / obsessive, so here it goes…
ALLUDED, should be ELUDED

Thanks Mom, (my 5th grade teacher). Surprised that’s the only error you found. Other than my spelling issues, any help with the code?

The stepper part works fine, The delay that is causing the problem is for keeping the vacuum on for 4 sec after the tool is turn off. I thought it would only be active when the statement was true.

else if (analogValue < 600 && vacPin==HIGH) {
delay (4000); **/*  with this on:
          the stepper does not start as quickly as before,
          the analog will not read the ACS712 sensor at all,  only the buttons*/** 
 digitalWrite(vacPin, LOW);
}

Let me understand this correctly: you have a carpenter’s workshop and it is about sawdust extraction?
When a machine or a tool is switched on, the vacuum tube should be aligned accordingly, and then start the vacuum fan?

The problem seems to me that your sketch is blocking with the delay. During this time it cannot react to anything. You should look how to write nonblocking sketches.
The library MobaTools could be a solution. It can position the stepper absolutely in degrees - without blocking the sketch - ( you only need to tell the lib how much steps are needed for one revolution ). And it has non blocking timer fuctions that can be used for the vacuum fan.

N.B. How do you assure, that the stepper is in Position ‘0’ when the sketch starts?

Edit: because stepPerAngel is declared as an integer this:
int stepPerAngle = 5 / 9; // full step = 1.8 or could have used "*1.8"
results into ‘0’.

Hello
I would like to help you.
But:
Please do not use cryptic abbreviations.
Provide for the I/O pins meaningful and unique names.
If you have a scenario, give it a meaningful and unique name. Delete all blank lines add descriptive comments for the flow and not what happens in the line.

Thanks for the info and I will check it out. Your understanding of what I doing is pretty accurate. I would only use the delay when the tool is turned off to clear remaining debris, Been trying to figure out nonblocking from other suggestion. When written I thought the delay would only occur when the statement above was met. I learning now that this was wrong!

To answer your question, after I get this part to work I will add a sensor to detect home and a homing routine when started up. Perhaps a button to activate the routine if needed. Doing one set at a time so I don’t get to confused!

Not sure what your telling me in the edit at the bottom?

Thanks Greg

Use millis for your timing so the rest of the code will be more responsive. For your vacuum, keep a boolean that tells you that you should turn it off. Set it when conditions tell you you should turn off and note the time. Keep checking to see if enough time has passed, when it has, clear the boolean.

Note that you will need to use the boolean to avoid constantly resetting the start time of the interval the vacuum is to stay on.

The thing about stepPerAngle is to warn you that it is using integer math and therefore evaluates to zero. Since your code never uses it, it doesn’t matter (yet!).

This would be my suggestion with MobaTools:

/*This version works as is **EXCEPT** the Delay vac 4 sec has to be turned off. See ########### area for Problem.
  Auto Blast gate project:  for dust collection in wood shop.
  Arduino Nano
  ACS712 current sensor
  DRV8825 stepper driver
  Nema 17 stepper
  Each tool will be monitor by a current sensor and when that analog port exceeds a given threshold
  1. Rotate the stepper to a predetermined position to align ports for that tool.
  2. After the gate is align a digital pin will drive relay to turn on Vacuum system.
   Vacuum will stay on as long as sensor exceed the threshold while tool is running.
   **When tool stops vacuum will continue for 4 seconds to clear remaining dust.**
  3. If the same tool is used next, the Stepper will remain in it's current position.
   But the vacuum system should still operate the same.
  4.  currently using buttons to simulate tools and also one ACS712 for testing 
*/
// suggestion with MobaTools for driving the stepper and timer fuction
#include <MobaTools.h>

// defines pins numbers
const int stepPin = 3;
const int dirPin  = 2;
const int enPin  = 8;
const int vacPin = 4; //simulate Vacuum relay

const int stepPer360Degree = 200; // Number of steps for one revolution ( adjust to your needs )
MoToStepper stepper ( stepPer360Degree, STEPDIR );
MoToTimer vacTimer; // for delayed switch off
const long runOnTime = 4000;

int na = 0;  //angle

int analogValue = 0;

void setup() {
  Serial.begin(9600);

  // Setup the stepper
  stepper.attach( stepPin, dirPin );
  stepper.setSpeedSteps( 1000, 20 ); // sets Speed and ramplength
  stepper.attachEnable( enPin, 100, LOW ); // Disable after 100ms. enabled is LOW

  pinMode(vacPin, OUTPUT); //Just added this for vac

  //set values for 2 outputs
  digitalWrite(vacPin, LOW); //just add this for vac


}

void loop() {
  analogValue = 0;

  // Assign button degrees
  if      ( analogRead(A0) > 600) {
    analogValue = (analogRead(A0));
    Serial.print("AO = ");
    Serial.println(analogValue);
    na = 0;

  }
  else if ( analogRead(A1) > 600) {
    analogValue = (analogRead(A1));
    Serial.print("A1 = ");
    Serial.println(analogValue);
    na = 45;
  }

  else if ( analogRead(A2) > 600) {
    analogValue = (analogRead(A2));
    Serial.print("A2 = ");
    Serial.println(analogValue);
    na = 225;
  }

  else if ( analogRead(A3) > 600) {   //=tool on
    analogValue = (analogRead(A3));
    Serial.print("A3 = ");
    Serial.println(analogValue);
    na = 270;

  }

  // position stepper if needed
  if ( stepper.read() != na ) stepper.write( na );

  // start vac if tool is on and stepper is in position
  if (analogValue > 600 && !stepper.moving()) {
    digitalWrite(vacPin, HIGH);
  }
  
  if ( vacTimer.expired() ) {
    // switch off vac if timer expires
    Serial.println( "Vac = off");
    digitalWrite(vacPin, LOW);
  }

  if (analogValue < 600 && digitalRead( vacPin ) && !vacTimer.running()) {
    // start timer to switch off vac after time
    Serial.println( " start vac run-on-time" );
    vacTimer.setTime( runOnTime );
  }

}

If you want to give it a try, the library can be installed by means of the library manager ( enter mobatools in the search field )

I don’t know where to start but, this worked PERFECTLY! I need to work on stepper speed and ramp Length to smooth out, or jumpers on the DRV8825 expansion bd. Other than that, I want to understand the library! I went to the readme and it explained the thing it can do, but I don’t know how to utilize on my own. I noticed your name and written by are the same! Am I talking to a person or a company? Thanks again

This is indeed not a coincidence :wink: , yes this lib was written by me, there is no company. Fell free to ask if you have any questions.

If you change the microstepping at your DRV8825 board, the steps per revolution will change. In this case you have to adjust the stepPer360Degree
accordingly. E.g. if xou choose 1/8 microstepping stepPer360Degree must be set to

const int stepPer360Degree = 1600; // Number of steps for one revolution ( adjust to your needs )

Thanks, Is there a document that I can read to understand everything in the Library. I can see what is going on with some of it but, just having the library I would have never made it to where you took me!

I do have questions but think I should at least try first.

Greg

I found the document so I’ll work with that.

That's fine. I missed to give you a link to it in my previous post. Feel free to ask if you don't understand something.

Used your library for my delay and it worked great. I don't know if you can help with a different problem. Using a Hall effect sensor in a homing program for a stepper. Because the sensor does not stop in perfect alignment, but does always stop in same position (this is normal), I want to fine tune it in the code. I was thinking in the function, or after I could enter a number of extra steps to fine tune the alignment. Say I wanted to add 12 steps after it stop. Below the code would be the loop after it has homed.
Code below. Thanks for any help or Ideas
Greg

/*
  Stepper Motor Homing Switch Demo
  stepper-homing-demo.ino
  Uses Hall Effect sensor as homing switch
  Uses A4988 Stepper Motor Driver module

  DroneBot Workshop 2019
  https://dronebotworkshop.com
*/

// Define connections
//#define HALL_SENSOR     6
//#define DIR      2
//#define STEP      3
//#define En       8
const int stepPin = 3;
const int dirPin  = 2;
const int enPin  = 8;
const int halPin  = 6;
// Direction Variable
//boolean setdir = LOW;

void homefunction() {
  // Set motor speed pulse duration
  int pd = 2000;

  // Move motor until home position reached
  while (digitalRead(halPin) == 1) {
//digitalWrite(EN, LOW);
    digitalWrite(dirPin, LOW);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pd);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(pd);
  }

}

void setup() {

  // Setup the stepper controller pins as Outputs
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  // Setup the Hall Effect switch as an Input
  pinMode(halPin, INPUT);

  // Home the motor
  homefunction();

}

void loop() {

  // Loop, put code here

}

there are multiple functions to move the motor absolute or relative to a position and you can reset what position zero is

When I was working as a software-developer for a company with stepper-motor-machines the homeing-sequency was this way:

move into directiopn towards home-sensor until sensor reacts.
Move slowly away from sensor until sensor switches off again
On configuraing the machine we measured the distance between this switch-off-point and the physical stop according to this the position after homing
the coordinate was set to this value
We used inductive approximation sensors and reached a precision of minimum 0,1 mm.
best regards Stefan

Thanks for the reply. What you outlined makes perfect sense. With my set up it is going to be hard to adjust the Hall Effect sensor to get it rough adjusted. So what I’m after is, where in my code should I enter that number of steps. Should it be in the function or after the function is executed. Once I can get it to react correctly I can adjust the number of steps till I get it aligned.

Thanks

Greg

In the homing function, after the while loop add a for loop that steps the motor a fixed number of times. Adjust the step count and direction to dial in your calibration.

If something like the MoBaTools is used which keep track of the absolute position it is not so important where you do the correction

example: you would like to have axle-zero on the left-end but the homing-sensor is near the right-end

|X=0--------------------------------------------Sensor-------|

Let's say the hole traveldistance is 400 mm
Homing-sensor is at position 380 mm

Just drive to the sensor for homing and set position to 380 mm. Done

If you execute any command to drive to any other position in absolute coordinate the MoBaTools will know where the position is now and what direction it has to drive how many steps just from calculating my actual position is and I shall drive to new position X

But of course it makes sense to set the offset right at the end of the homing.

If your mechanic is robust enough and you add a second sensor on the other end you could even a completely automation of this process.

The program starts at any point to drive in one direction until the sensor reacts. Let' say to the right
Then the program drives into the other direction = to the left until the other sensor reacts

The stepdistance is stored. Then drive more to the left until the moving part hits the physical stop. drive back to homing sensor counting steps. This will be less steps and give you the stepdistance from left physical stop until left sensor

go on driving to the right until right sensor reacts. store stepdistance go on driving too many steps to the right to make sure the physical stop is hit. drive back to the right sensor. this gives the stepdistance from physical stop to the right sensor.

This will even work with one sensor by driving forth and back multiple times.

As I already wrote this is possible if your mechanic is robust enough. a stepper-motor and a drive build from a ballscrewspindle is robust enough. Steppermotors just stall if you drive them to fast or against physcial obstacle

best regards Stefan