Running only once an action from a IF Statement. (Halloween Project)

Hi,

I’m working on a Halloween project with an e18 d80nk sensor, A4988 driver and a stepper motor. Basically, I’m attaching a hand to the stepper motor and putting it under a chair. When the sensor detects somebody in front of the chair the stepper motor will turn a revolution clockwise bringing the hand out and then one revolution backward bringing the hand back. My problem is that if the sensor is activated the motor keeps going forward and backward in a loop until the sensor is deactivated. I want the action to be done only once when the sensor is activated. This is my code.

#define STEP 4     
#define DIR 5    
int E18Sensor = 8;
int Distance;


void setup() 
{
  pinMode(E18Sensor,INPUT);
  pinMode(STEP, OUTPUT); 
  pinMode(DIR, OUTPUT);   
  Serial.begin(9600);
}

void loop() 
{
Distance = digitalRead (E18Sensor);
if (Distance == LOW)
{
  
   digitalWrite(DIR, HIGH);    
  for(int i = 0; i < 400; i++){     
    digitalWrite(STEP, HIGH);       
    delayMicroseconds(250);          
    digitalWrite(STEP, LOW);        
    delayMicroseconds(1000);         
  }
  delay(1000);          

  digitalWrite(DIR, LOW);     
  for(int i = 0; i < 400; i++){
    digitalWrite(STEP, HIGH); 
    delayMicroseconds(250);
    digitalWrite(STEP, LOW);
    delayMicroseconds(1000);
  }
  delay(1000);         
  
}
}

I thought putting a FOR statement will do the trick but It didn’t work. I know the basics for programming the arduino but I think the answers is beyond my knowledge.

Thanks in advance.

Read about IDE -> file/examples/digital/statechangedetection.

You want to initiate some action when the signal *becomes * LOW.

Hi cesariocs,

Great work on posting your code with code tags!

Try this:

#define STEP 4
#define DIR 5
int E18Sensor = 8;
int Distance;


void setup()
{
  pinMode(E18Sensor, INPUT);
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  Distance = digitalRead (E18Sensor);
  if (Distance == LOW)
  {
    digitalWrite(DIR, HIGH);
    for (int i = 0; i < 400; i++) {
      digitalWrite(STEP, HIGH);
      delayMicroseconds(250);
      digitalWrite(STEP, LOW);
      delayMicroseconds(1000);
    }
    delay(1000);

    digitalWrite(DIR, LOW);
    for (int i = 0; i < 400; i++) {
      digitalWrite(STEP, HIGH);
      delayMicroseconds(250);
      digitalWrite(STEP, LOW);
      delayMicroseconds(1000);
    }
    while (Distance == LOW) {
      delay(1000);
    }
  }
}

This code uses a while loop to accomplish what dougp was talking about.

Hope this helps!

Kind regards,

Zeb

Thanks for responding!

ZebH, I tried your code and it makes one cycle when the sensor is activated , even if it stays activated. But the problem is that it doesn’t run again when I try to activate the sensor.

Also like dougp recommended, I got into the Change of State example and i took it as a guide so I made some changes in my code.

#define STEP 4      // pin STEP of A4988 on pin 4
#define DIR 5     // pin DIR of A4988 on pin 5
int E18Sensor = 8; // Sensor on pin 8
int SensorState = 0; // current state of the sensor
int LastSensorState= 0; // previous state of the sensor


void setup() 
{
  pinMode(E18Sensor,INPUT);
  pinMode(STEP, OUTPUT);  // pin 4 as an output
  pinMode(DIR, OUTPUT);   // pin 5 as an output
  Serial.begin(9600);
}

void loop() 
{
SensorState = digitalRead (E18Sensor);// read the sensor input pin:
Serial.println (SensorState);

if (SensorState!=LastSensorState){ // compare the SensorState to its previous state

if ( SensorState == LOW) // if the state has changed, do the cycle
{
  
   digitalWrite(DIR, HIGH);    // Stepper Motor Forward
  for(int i = 0; i < 400; i++){     
    digitalWrite(STEP, HIGH);
    delayMicroseconds(250);  
    digitalWrite(STEP, LOW);        
    delayMicroseconds(1000);         
  }
  delay(1000);          // delay 

  digitalWrite(DIR, LOW);     // Stepper Motor Backward
  for(int i = 0; i < 400; i++){
    digitalWrite(STEP, HIGH); 
    delayMicroseconds(250);
    digitalWrite(STEP, LOW);
    delayMicroseconds(1000);
  }
  delay(1000);           
} 
}
 LastSensorState=SensorState; // save the current state as the last state, for next time through the loop
}

i finally got it to work!

Thank you so much for your help!

cesariocs:
i finally got it to work!

Excellent.

Great! Sorry I forgot to add a line a line to read the sensor again.

This code should work fine but since your code works just stick with that as it will be just as good :slight_smile:

#define STEP 4
#define DIR 5
int E18Sensor = 8;
int Distance;


void setup()
{
  pinMode(E18Sensor, INPUT);
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  Distance = digitalRead (E18Sensor);
  if (Distance == LOW)
  {
    digitalWrite(DIR, HIGH);
    for (int i = 0; i < 400; i++) {
      digitalWrite(STEP, HIGH);
      delayMicroseconds(250);
      digitalWrite(STEP, LOW);
      delayMicroseconds(1000);
    }
    delay(1000);

    digitalWrite(DIR, LOW);
    for (int i = 0; i < 400; i++) {
      digitalWrite(STEP, HIGH);
      delayMicroseconds(250);
      digitalWrite(STEP, LOW);
      delayMicroseconds(1000);
    }
    while (Distance == LOW) {
      delay(1000);
      Distance = digitalRead (E18Sensor);
    }
  }
}

Kind regards,

Zeb