How to keep carrying out the function even if the state is not true anymore

Project Background(Details);

I am making an automatic egg incubator tray. which would simply tilt the eggs back and forth. i have posted a few times regarding the same project. Thankfully all the hardware part is done. However i have not been able to solve the software side. I will explain the problem in the Problem header,

This is what the build looks like

These are the limit switches

I have installed two limit switches which will limit the tilt on both sides to 45 degrees.

The motion is kind of unbalanced so i have to use limit switches in order for it to move exactly 45 degrees.

CODE:

[

int s1=6;     //switches and l298n's pins
int s2=5;
int m1=4;
int m2=3;
boolean m1Flag;   //flags 
boolean m2Flag;
boolean s1Flag;
boolean s2Flag;

void setup() 
  {
  pinMode(s1,INPUT);
  pinMode(s2,INPUT);
  pinMode(m1,OUTPUT);
  pinMode(m2,OUTPUT);
  if((digitalRead(s1) == LOW) & (digitalRead(s2) == LOW)) {    //for initial calibration, if the motor stop in mid air
  digitalWrite(m2,HIGH);                           //(not touching any switch) during a blackout, i want it to calibrate itself.
  digitalWrite(m1,LOW);
  Serial.println("initial Calibration");
  }
  Serial.begin(9600);
  Serial.println("START");
  }

void loop() {
  setSwitchFlag();       
  if((digitalRead(s1)==LOW)&(digitalRead(s2)==HIGH) | (digitalRead(s1)==HIGH)&(digitalRead(s2)==LOW)){    //if the tray is either tilted to the left or right
   setSwitchFlag();                                   //record the current data 
   setFlags();
   digitalWrite(m1,LOW);
   digitalWrite(m2,LOW);                           //stop the motor
   delay(10000);                                   //wait for a specific delay(will update to 2 hours once the problem solves
   
   if((digitalRead(s2) == LOW) || (digitalRead(s1) == LOW)) {         //this is just making the motor spin in the opposite direction from what they were before
    digitalWrite(m1,!m1Flag);                                        //and telling it go until one of the opposite switch becomes high
    digitalWrite(m2,!m2Flag);
  setSwitchFlag();                                  //set flags again to be used for later use
  setFlags();
  }
  }

}

void setFlags() {         //just setting up flags so that arduino will remember which state to follow
  if((digitalRead(m1) == HIGH) & (digitalRead(m2) == LOW)) {
    m1Flag = HIGH;
    m2Flag = LOW;
  }
  if((digitalRead(m1) == LOW) & (digitalRead(m2) == HIGH)) {
    m1Flag = LOW;
    m2Flag = HIGH;
  }
}

void setSwitchFlag() {
  if((digitalRead(s1) == LOW) & (digitalRead(s2) == HIGH)) {
    s1Flag = LOW;
    s2Flag = HIGH;
  }
  if((digitalRead(s1) == HIGH) & (digitalRead(s2) == LOW)) {
    s1Flag = HIGH;
    s2Flag = LOW;
    
  }
}

PROBLEM

When one of the limit switch is pressed, it starts to move in the opposite direction after a delay, just the way i want,
but it would only work i let go of the switch. (in other words it wont start moving as long as that switch is pressed) and as soon as i let go it will go in the opposite direction. And sometimes it wont move unless i press both of the switches at the same time, it's weird.

What i want:

  • I want the motor to spin in the opposite direction even if the switch is pressed.
  • Want the arduino to decide on the basis of time and not the switch. for example as soon as the delay ends, recall what position motor was in, start going in the opposite direction until one of the opposite switch is pressed.
  • assume the motor stops as soon as the tray touches switch1. and it starts going the opposite direction the transition of the switch from pressed to unpressed while the tray is moving should not affect its decision.

You need to detect when the switch becomes pressed rather than when it is pressed

Look at the StateChangeDetection example in the IDE

off topic
Hmmm.... Any connection with "Chicken Invaders"?

demkat1:
off topic
Hmmm.... Any connection with "Chicken Invaders"?

Nop. :slight_smile:

UKHeliBob:
You need to detect when the switch becomes pressed rather than when it is pressed

Look at the StateChangeDetection example in the IDE

I actually thought statechangedetection example could work for me, i looked at it a few times before uploading to the forum and i looked at it again, didn't quite understand how to use it (i guess im just tired)

But i came up with something like this which something like what that example was doing

boolean  s2Flag;
boolean  s1Flag;  
boolean s1State; 
boolean s2State;
  
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  s1State = digitalRead(s1);
  s2State = digitalRead(s2);

  if(s1State == HIGH) & (s2State == LOW) {      //the tray touches one of the switch and this function will be carried out by monitoring the live switch state
    s1Flag == HIGH;
    motorstop();         //the motor stops 
    if(s2State == LOW) {    //go in the opposite direction until the opposite switch becomes low
      reverseDirection();
    } else 
    {
      stopMotor();
      s2Flag == HIGH;
      s1Flag == LOW;
    }
  }

}

Do you think something like this might work? ill test it soon but still, have a look at it if there is any problem with it.

After some thinking, i think i'm committing the same mistake which you pointed out, by using the live switch states start the if statement

Question: if this first condition becomes true

  if(s1State == HIGH) & (s2State == LOW)

And it goes into the next if statement

if(s2State == LOW) {    //go in the opposite direction until the opposite switch becomes low

Then, when the motor starts moving and the s1state becomes low (because the tray moved and now that switch is unpressed)
Will this transition stop the function because the first IF statement:

 if(s1State == HIGH) & (s2State == LOW)

is now false?

I am a newbie when it comes to software, i appreciate your patience.

pinMode(s1,INPUT);
pinMode(s2,INPUT);

Are you using external resistor pullups on the inputs? If not, they're floating, ie. in an undefined state. Using INPUT_PULLUP in pinMode would stabilize the inputs.

Here's a simpler state change example. Essential to understanding this is to realize that the processor scans the code sequentially.

stateChangeUp = (s1 and changeSetup);
changeSetup = !s1;

stateChangeUp will be true for one scan when s1 goes true.

dougp:

pinMode(s1,INPUT);

pinMode(s2,INPUT);




Are you using external resistor pullups on the inputs? If not, they're floating. Using `INPUT_PULLUP` in `pinMode` would stabilize the inputs. That would be a better place to start from.

yup i am using external resistors. or i might use input pullups next time. this code was to focus on the problem while ignoring other things such as input pull up and stuff.

I have edited post #6.

dougp:
I have edited post #6.

The thing is, i looked into statechange and i don't think that would work in my project. solely because i want the motor to move when switch is high. i don't know how i get the same output after i use something like this,

currentstate = !previousState

because this would carry out the function even when it is low i guess?

i don't know correct me if i am wrong i am just not able to connect the dots in my brain.

I will read the comments and stateChangeDetection again. there must be something i am missing.

if (currentstate = !previousState && currentstate == HIGH)
{
  //code here to run when the switch becomes HIGH
}

UKHeliBob:

if (currentstate = !previousState && currentstate == HIGH)

{
  //code here to run when the switch becomes HIGH
}

Great! I'll try it out