Multiple condition motor with limit switch feedback.

Hello all,
I have quite a bit of PLC programming experience but almost no real programming and am stuck trying to get a small application working. I own an escape room and the device I am trying to make is the following:
-There are three head statues with some embedded reed switches.
-Each head has a corresponding mask with a magnet in it so when the correct mask is placed on the head it activates.
-Once all three masks are in place a screw actuator is activated which moves door over a hidden compartment. The actuator is driven by a continuous rotation servo motor.
-There are limits at both the open and close position
-If any of the masks are removed I would like the door to close again.

I have this system working now on a stepper motor with no limits but the stepper is weak and easy for people to force open. This new actuator uses a 1/4" bolt and holds the door solid and can not be forced open.

I would be fine if someone just gives me the correct code, though I will be doing a lot more projects in the future so any help understanding what I am not seeing I would appreciate it greatly.

Here is what I have but I feel like its way off, have tried several things and at this point I just need help.

#include <Servo.h>


Servo screw;


int GreenPin = 3;
int PinkPin = 4;
int PurplePin = 5;
int OpenPin = 7;
int ClosePin = 8;

void setup() {
  
  screw.attach(6);
  
  pinMode (GreenPin, INPUT_PULLUP);
  pinMode (PinkPin, INPUT_PULLUP);
  pinMode (PurplePin, INPUT_PULLUP);
  pinMode (OpenPin, INPUT_PULLUP); 
  pinMode (ClosePin, INPUT_PULLUP);  

 
 }


void loop() {

   int GreenMask = (digitalRead (GreenPin));
   int PinkMask = (digitalRead (PinkPin));
   int PurpleMask = (digitalRead (PurplePin));  
   int CloseLimit = (digitalRead (ClosePin));
   int OpenLimit = (digitalRead (OpenPin));
   
if (GreenMask == LOW && PinkMask == LOW && PurpleMask == LOW && OpenLimit == HIGH){
    
  screw.write(0);
}
else if (GreenMask == HIGH || PinkMask == HIGH || PurpleMask == HIGH && CloseLimit == HIGH){
   screw.write(180);
  }
  else{
    screw.write(90);
  }
   int GreenMask = (digitalRead (GreenPin));
   int PinkMask = (digitalRead (PinkPin));
   int PurpleMask = (digitalRead (PurplePin)); 
   int CloseLimit = (digitalRead (ClosePin));
   int OpenLimit = (digitalRead (OpenPin));

(Why) (are) (the) (function) (calls) (wrapped) (in) (useless) (parentheses) (?)

How does this code determine that the correct mask is in place?

Reading the limit switches at this point is useless. You need to determine if the door needs to be opened, regardless of what state the door is in. If it does, then you need to determine if the door is open, or not. If not, call a function to begin the door opening process. That process needs to have a while loop that continually monitors the limit switch and stops the motor when the limit switch becomes pressed. It should also monitor the mask switches, and stop opening the door if one of them becomes released.

If the door should not be open, but is, close it, using a function with a while loop that monitors the other limit switch and stops the motor when the door becomes closed.

The parenthesis are there because that is how the examples I have seen were done, it seems to go along with a great number of other useless stuff that this sort of programing does over something like ladder logic. But that is just my frustration mounting I suppose.

The masks being in the correct place is self evident by the fact that they trigger the reed switch each one has a magnet in a place that will only trigger if on the correct statue.

I understand that I need to monitor the current state, and have been looking into something like a switchcase to look for whether I am open, opening, closed, or closing but I'm not able to put it together.

I used a "while" statement with the stepper motor in a the program that has been running the last few months on it. The while worked there because it was moving 1 step at a time and as soon as it became untrue because the limit was hit it stopped.

Should it be an IF all masks are made start open, with an IF open limit made halt motor inside of it?

I can't say that I understand clearly what you are trying to achieve. For example is the lock closed at 0° or 180°?

Why do you need limit switches with a servo?

Your code seems to move the servo to 0° when ALL of the masks are LOW and the openLimit is HIGH. That seems straightforward.

The other test is not obvious. It seems to moveto 180° when AT LEAST ONE of the masks is HIGH and the closeLimit is HIGH. It would be a good idea to use extra brackets to make it clear what you want - such as

else if ( (GreenMask == HIGH || PinkMask == HIGH || PurpleMask == HIGH)  && CloseLimit == HIGH){

However I think if that was my program I would test for the limit switches separately - like this

if (CloseLimit == HIGH) {
   if (GreenMask == HIGH || PinkMask == HIGH || PurpleMask == HIGH) {

I am also very wary of ELSE clauses that follow complex IF clauses - it is not always obvious what conditions trigger the ELSE.

...R

It is a continuous rotation servo which is effectively a little gearmotor. At 90 it is stationary, at 0 its full speed clockwise at 180 its full speed counter.

I was using the else here because only in the very specific condition of having all masks triggered do I want it to open, in any other condition I want it to be fully closed.

caseybruder: It is a continuous rotation servo which is effectively a little gearmotor. At 90 it is stationary, at 0 its full speed clockwise at 180 its full speed counter.

OK. Then can you describe in English (not code) the sequences of events that you want to happen.

It should be straightforward to program it when we know precisely what is required.

...R

The bullet points in my question were supposed to line that out but for simplification here it is:

Activate and maintain 3 switchs → motor turns clockwise untill a limit is hit, then stops.
If any switch is lost → motor turns coutner clockwise untill a differnt limit is hit, then stops.

Thats it.

I interpret that to mean that the motor is normally at (say) the left limit switch.

And it only moves off the left limit switch if all 3 conditions are met
And while all 3 conditions are met it moves towards, and stops at the right limit switch

When any of the conditions fails it moves back towards the left limit switch - which may mean changing direction in the middle of a move towards the right limit switch.

Similarly, if it is moving towards the left limit switch and all 3 conditions are met, it stops moving left and moves right.

Let me know if any of that is wrong,

I think the way I would code that is something like this pseudo code

if all 3 conditions are met the direction is set to rightwards
else direction is set to leftwards

if the direction is rightwards
     if the right limit is NOT triggered the motor moves right
else
     if the left limit is NOT triggered the motor moves left

…R

Thanks a lot for the help. Here is what I came up with and it seems to be working so far.

#include <Servo.h>


Servo screw;


int GreenPin = 3;
int PinkPin = 4;
int PurplePin = 5;
int OpenPin = 7;
int ClosePin = 8;
int MotorDirection;
int MotorSpeed;

void setup() {
  
  screw.attach(6);
  Serial.begin(9600);
  Serial.println("--START__");
  
  pinMode (GreenPin, INPUT_PULLUP);
  pinMode (PinkPin, INPUT_PULLUP);
  pinMode (PurplePin, INPUT_PULLUP);
  pinMode (OpenPin, INPUT_PULLUP); 
  pinMode (ClosePin, INPUT_PULLUP);  

 
 }


void loop() {

   int GreenMask = (digitalRead (GreenPin));
   int PinkMask = (digitalRead (PinkPin));
   int PurpleMask = (digitalRead (PurplePin));  
   int CloseLimit = (digitalRead (ClosePin));
   int OpenLimit = (digitalRead (OpenPin));

MotorSpeed = 90;
  
if (GreenMask == LOW && PinkMask == LOW && PurpleMask == LOW){
 MotorDirection = 1;
 Serial.println("-Masks Okay-");
  }
else{
 MotorDirection = 2;
 Serial.println("-No Masks-");
  }

if (MotorDirection == 1 && OpenLimit == HIGH){
    MotorSpeed = 180;
    Serial.println("-Forward-");
    }
else if (MotorDirection == 2 && CloseLimit == HIGH){
    MotorSpeed = 0;
    Serial.println("-Reverse-");
    }
else {
    MotorSpeed = 90;
    Serial.println("-STOPPED-");
}
screw.write(MotorSpeed);
Serial.println(MotorSpeed);
}

Yes. That's what I had in mind.

...R