Chicken coop motor delay problem

The code is modified from a sketch written by Dave Nave. You helped him early on with his coding. It works beautifully with my hardware setup for the Chicken Coop Door Control with one exception. When the door closes, a reed switch at the bottom of the door closes and the motor stops. The problem - I need the motor to continue running for a few seconds to allow the predator locks to engage. This is no doubt due to an error in the design and build of the mechanism. That said, I would really like to do a software delay rather than a rebuild of the door. I added a function – stopCloseCoopDoorMotorB() that is called from the closeCoopDoorMotorB() function. I have tried several coding delays including a do/while loop (not sure I did this properly), a for loop and most recently millis. Obviously, I’m not doing something correctly as the code below and my other trials do not delay at all – the motor stops immediately. I have researched this problem and have many code snippets recorded that have not worked. I hate to ask for help, but I give up! I tried to copy the entire program – too long - it is 252 lines?

Here are the variables for the millis delay:

//CloseCoopDoorMotorB delay
unsigned long lastCloseCoopDoorMotorBTime = 0;
unsigned long CloseCoopDoorMotorBDelay = 4000;    // 4 seconds

Here are the functions in question:

//  stop the coop close door motor
void stopCloseCoopDoorMotorB()
{
  digitalRead (bottomSwitchPinVal);
    if (bottomSwitchPinVal == 0)
   {
     if ((unsigned long)(millis() - lastCloseCoopDoorMotorBTime) >= CloseCoopDoorMotorBDelay)
      {
    lastCloseCoopDoorMotorBTime = millis();
      }
       {
       digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
       digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
       digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
       }
   }
}  
void closeCoopDoorMotorB()       // close the coop door motor (motor dir close = clockwise)
{
  digitalWrite (directionCloseCoopDoorMotorB, HIGH);     // turn on motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
  digitalWrite (enableCoopDoorMotorB, HIGH);              // enable motor, full speed
  if (bottomSwitchPinVal == 0)
  {
    stopCloseCoopDoorMotorB();
  }
}

Google + link to photos of my controller board (this is on my desk while I’m working on the code).
https://photos.google.com/u/0/album/AF1QipMhyep_TilQELU7Nx0ejmk6jTGO9gFO7Z4ZMlhv

Arduino Pro Mini 5 volt 16 MHz, SN754410 Motor control IC, 7805 voltage regulator. CdS LDR is connected upper right. White alligator clips simulate the top reed switch, yellow, the bottom. There is a small 5 volt motor for trial use at the bottom of the left picture – in the Coop Door, I use a 24 volt gear motor.

  digitalRead (bottomSwitchPinVal);
  if (bottomSwitchPinVal == 0) ...

digitalRead() expects an argument that refers to a pin on the Arduino, and returns a vaule of HIGH or LOW. The first statement looks to read a value from a pin designated by something called bottomSwitchPinVal, and discards the return value. The second statement appears to test that same value, which, if it's used correctly in digitalRead(), is actually a pin number.

Did you mean to say something like this?

  bottomSwitchPinVal = digitalRead (bottomSwitchPin);
  if (bottomSwitchPinVal == 0) ...

I can't say that's the right fix, because we can't see the rest of your code to see just what kind of an object bottoSwitchPinVal really is. But, the original code doesn't look like it will work.

And this is an example of why code snippets are bad.

Thanks for the replies and suggestion. I’ll not be back to my home computer until tomorrow night or Friday morning. What is the best accepted way to post a program that is too large to add in the normal post? I tried to add it to the original post but got the error message.
David

mayhaw9999: What is the best accepted way to post a program that is too large to add in the normal post?

The best way is to generate a subset of your program that compiles, runs, and demonstrates the problem. You'll get much more participation with a short, understandable program than you will with a long and complicated one.

Here is the program without LED functions or switch debounce routines. As small as I could make it.

// Chicken Coop Program 10/29/2015 Using Arduino Pro Mini 5V Board/SN754410 Motor control
//No LED or debounce code
// pins assignments

const int photocellPin = A0;                 // photocell connected to analog 0
const int enableCoopDoorMotorB = 11;          // enable motor b - pin11
const int directionCloseCoopDoorMotorB = 10;  // direction close motor b - pin 10
const int directionOpenCoopDoorMotorB = 9;   // direction open motor b - pin 9
const int bottomSwitchPin = 5;              // bottom switch is connected to pin 5
const int topSwitchPin = 6;                 // top switch is connected to pin 6
// *************************VARIABLES********************************
// photocell
int photocellReading;                            // analog reading of the photocel
int photocellReadingLevel;                       // photocel reading levels (dark, twilight, light)
// REED SWITCHES - top and bottom of coop door
int topSwitchPinVal;                   // top switch var for reading the pin status
int bottomSwitchPinVal;                // bottom switch var for reading the pin status
// photocell reading delay
unsigned long lastPhotocellReadingTime = 0;
unsigned long photocellReadingDelay = 6000;   // 6 sec
//CloseCoopDoorMotorB delay
unsigned long lastCloseCoopDoorMotorBTime = 0;
unsigned long CloseCoopDoorMotorBDelay = 4000;    // 4 seconds

// ************************************** the setup **************************************
void setup(void)
{ //motor
  pinMode (enableCoopDoorMotorB, OUTPUT);           // enable motor pin = output
  pinMode (directionCloseCoopDoorMotorB, OUTPUT);   // motor close direction pin = output
  pinMode (directionOpenCoopDoorMotorB, OUTPUT);    // motor open direction pin = output
  // bottom switch
  pinMode(bottomSwitchPin, INPUT);                  // set bottom switch pin as input
  digitalWrite(bottomSwitchPin, HIGH);              // activate bottom switch resistor
  // top switch
  pinMode(topSwitchPin, INPUT);                     // set top switch pin as input
  digitalWrite(topSwitchPin, HIGH);                 // activate top switch resistor
}
// ************************************** FUNCTIONS **************************************
// operate the coop door
// photocel to read levels of exterior light
void doReadPhotoCell() { // function to be called repeatedly
  photocellReading = analogRead(photocellPin);
  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay)
  {
    lastPhotocellReadingTime = millis();

    //  set photocel threshholds
    if (photocellReading >= 0 && photocellReading <= 200)
    {
      photocellReadingLevel = '1';
    }
    else if (photocellReading  >= 700)
    {
      photocellReadingLevel = '3';
    }
  }
}
// bottom reed switch
void BottomReedSwitch()  //read bottom reed switch
{
  bottomSwitchPinVal = digitalRead(bottomSwitchPin);       // read input value and store it in val
}
//  top reed switch
void TopReedSwitch()
{
  topSwitchPinVal = digitalRead(topSwitchPin);             // read input value and store it in val
}
void stopCoopDoorMotorB()              // stop the coop OPEN door motor
{
  digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
  digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
}
void stopCloseCoopDoorMotorB()          //  stop the coop close door motor
{
  bottomSwitchPinVal = digitalRead (bottomSwitchPin);
  if (bottomSwitchPinVal == 0)
  {
    if ((unsigned long)(millis() - lastCloseCoopDoorMotorBTime) >= CloseCoopDoorMotorBDelay)
    {
      lastCloseCoopDoorMotorBTime = millis();
    }
    {
      digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
      digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
      digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
    }
  }
}
void closeCoopDoorMotorB()       // close the coop door (motor dir close = clockwise)
{
  digitalWrite (directionCloseCoopDoorMotorB, HIGH);     // turn on motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
  digitalWrite (enableCoopDoorMotorB, HIGH);              // enable motor, full speed
  if (bottomSwitchPinVal == 0)
  {
    stopCloseCoopDoorMotorB();
  }
}
void openCoopDoorMotorB()       // open the coop door (motor dir open = counter-clockwise)
{
  digitalWrite(directionCloseCoopDoorMotorB, LOW);       // turn off motor close direction
  digitalWrite(directionOpenCoopDoorMotorB, HIGH);       // turn on motor open direction
  digitalWrite(enableCoopDoorMotorB, HIGH);              // enable motor, full speed
  if (topSwitchPinVal == 0)                              // if top reed switch circuit is closed
  {
    stopCoopDoorMotorB();
  }
}
// do the coop door
void doCoopDoor()
{
  if (photocellReadingLevel  == '1')             // if it's dark
  {
    {
      TopReedSwitch();                        // read the switches
      BottomReedSwitch();
      closeCoopDoorMotorB();                            // close the door
    }
  }
  if (photocellReadingLevel  == '3')                      // if it's light
  {
    {
      TopReedSwitch();                      // read the switches
      BottomReedSwitch();
      openCoopDoorMotorB();                 // Open the door
    }
  }
}
// ************************************** the loop **************************************
void loop()
{
  doReadPhotoCell();
  doCoopDoor();
}

I think that the problem you describe arises here:

void stopCloseCoopDoorMotorB()          //  stop the coop close door motor
{
  bottomSwitchPinVal = digitalRead (bottomSwitchPin);
  if (bottomSwitchPinVal == 0)
  {
    if ((unsigned long)(millis() - lastCloseCoopDoorMotorBTime) >= CloseCoopDoorMotorBDelay)
    {
      lastCloseCoopDoorMotorBTime = millis();
    }
    {
      digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
      digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
      digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
    }
  }
}

This function, as I understand it, is called when the door-closing routine finds the bottom switch value at zero. When it's called, it, too, should find the bottom switch value at zero. It'll then test the time, and then it will shut off the motor. I think that you want it to shut off the motor when the interval elapses; this code shuts off the motor pretty much all the time.

It also appears that the last closing time doesn't get updated before the stop-closing routine executes. It might help to update that value just before calling the stop-closing routine.

I believe that I see other trouble in the program, too. The routines that operate the door are called based on the current state of the photocell. I think you want to call them when the photocell value changes state. As it stands, it looks to me that function doCoopDoor() will call either the open routine or the close routine every time, energizing the motor each time. You might have better results if you actuate the motor only when the door state and the photocell state disagree - it's open when it should be closed, or vice versa.

All that said, this looks like a good application for a "state machine." You can find out about that kind of program here: http://www.gammon.com.au/statemachine. The states might be: - Daylight, door open. - Night, door open. - Night, door closing. - Night, door close delay. - Night, door closed, delay elapsed. - Daylight, door closed. - Daylight, door opening. You might want to add other states that indicate some sort of failure, like, "Daylight, door closed, tried, didn't open." The device could light a light, honk a horn, or maybe even play a recording of soothing messages telling the chickens not to be alarmed.

I had some trouble following the flow of the program. It's not particularly easy to develop a grasp of what happens each time through loop(). I could be wrong about how the program operates.

It looks like you've gone to some effort to avoid using any blocking routines, like delay(), and in the process, the program flow has become complicated. A state machine implementation could improve the readability of the code, and make it easier to follow.

Thanks for taking the trouble to reduce the code size to a meaningful subset of the original program.

Thanks tmd3. I agree the program is somewhat hard to follow, but maybe easier if the entire program is in front of you. As you can tell, my coding skills leave lots to be desired. It certainly seems that the state machine is the way to go. As I understand it, I would need to rewrite the entire program as a state machine rather than just the functions that control motor closing. Is this correct? I went to Nick Gammon's site that you suggested, but I'm still unsure exactly how to proceed. I'll start working on it and see where it takes me. (I should have done more searching on Nick's site. I've been registered there for quite some time. Just slipped my old mind.)

Thanks again for your help.

David

Well, you could try looking closely at the motor-shutoff program and see if it really does what you want. I think that the shutoff routine turns off the motor whenever it finds the bottom switch reading at zero. I think that you want it to do that after a delay elapses. If you fix that part of the code, the whole thing may work.

I think that trying to continue development with the code that you have, though, will be difficult. I think that redoing it as a state machine will make it easier to get to pay dirt, even if the program is already well-advanced.

I personally don’t like to jump function to function unless I have a good reason to. It makes the code complicate to follow so unless im repeating something or I have a calculation that I only care about the answer I normally stay in the main loop.

try this example its set up for serial printing to show you whats happening in the code

Its not great code but it should be easy to follow

const int photocellPin = A0;                 // photocell connected to analog 0
const int enableCoopDoorMotorB = 11;          // enable motor b - pin11
const int directionCloseCoopDoorMotorB = 10;  // direction close motor b - pin 10
const int directionOpenCoopDoorMotorB = 9;   // direction open motor b - pin 9
const int bottomSwitchPin = 5;              // bottom switch is connected to pin 5
const int topSwitchPin = 6;                 // top switch is connected to pin 6
unsigned long lastPhotocellReadingTime = 0;
unsigned long photocellReadingDelay = 6000;   // 6 sec-do not set lower than stop motor delay
//CloseCoopDoorMotorB delay
unsigned long lastCloseCoopDoorMotorBTime = 0;
unsigned long CloseCoopDoorMotorBDelay = 4000;    // 4 seconds
byte requestdoorclose = 0;
byte requestdooropen = 0;
byte doorIsClosed = 0;
byte photocellReadingLevel = 0;
byte doorstate = 0;//used for test printing
unsigned long prevmillis = 0;//used for test printing
unsigned long currentmillis = 0;
int photocellReading = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);//set up serial print
  pinMode (enableCoopDoorMotorB, OUTPUT);           // enable motor pin = output
  pinMode (directionCloseCoopDoorMotorB, OUTPUT);   // motor close direction pin = output
  pinMode (directionOpenCoopDoorMotorB, OUTPUT);    // motor open direction pin = output
  pinMode(bottomSwitchPin, INPUT_PULLUP); // set bottom switch pin as input low when pressed
  pinMode(topSwitchPin, INPUT_PULLUP);  // set top switch pin as input low when pressed

}

void loop() {
  // put your main code here, to run repeatedly:
  currentmillis = millis();
  photocellReading = analogRead(photocellPin);
  //photocellReading = 750;//test code // above line to use
  byte topSwitchPinVal = digitalRead(topSwitchPin);
  byte bottomSwitchPinVal = digitalRead (bottomSwitchPin);

  if (currentmillis - lastPhotocellReadingTime >= photocellReadingDelay)
  {
    //  set photocel threshholds
    if (photocellReading >= 0 && photocellReading <= 200)
    {
      photocellReadingLevel = 1;
    }
    else if (photocellReading  >= 700)
    {
      photocellReadingLevel = 2;
    }
    else {
      photocellReadingLevel = 0;
    }
    lastPhotocellReadingTime = currentmillis;
  }

  showprints();

  switch (photocellReadingLevel) {
    case 0://not light or dark
      //lets processor skip if 0
      break;
    case 1://it is dark
      requestdoorclose = 1;
      requestdooropen = 0;
      break;
    case 2://it is light
      requestdooropen = 1;
      requestdoorclose = 0;
      break;
  }

  if (requestdooropen == 1 && topSwitchPinVal == HIGH) {
    digitalWrite(directionCloseCoopDoorMotorB, LOW);       // turn off motor close direction
    digitalWrite(directionOpenCoopDoorMotorB, HIGH);       // turn on motor open direction
    digitalWrite(enableCoopDoorMotorB, HIGH);
    doorstate = 1;//used in test prints
  }

  if (requestdoorclose == 1 && doorIsClosed == 0) {
    digitalWrite (directionCloseCoopDoorMotorB, HIGH);     // turn on motor close direction
    digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
    digitalWrite (enableCoopDoorMotorB, HIGH);
    doorstate = 2;//used in test prints
  }

  if (topSwitchPinVal == LOW) {
    motorsOff();
  }


  if ((bottomSwitchPinVal == LOW) && (requestdoorclose == 1)) {
    if (currentmillis - lastCloseCoopDoorMotorBTime >= CloseCoopDoorMotorBDelay) {
      doorIsClosed = 1;
      motorsOff();
    }
  }
  if (bottomSwitchPinVal == HIGH) {
    lastCloseCoopDoorMotorBTime = currentmillis;
    doorIsClosed = 0;
  }
}

void motorsOff() {
  digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
  digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
  doorstate = 0;//used in test prints
}

void showprints() {
  if (currentmillis - prevmillis >= 500) {//slow prints down
    Serial.print("photocellReading = ");
    Serial.println(photocellReading);
    Serial.print("photocellReadingLevel = ");
    Serial.println(photocellReadingLevel);
    Serial.print("door request = ");
    if (requestdooropen == 1) {
      Serial.println ("request open");
    }
    if (requestdoorclose == 1) {
      Serial.println ("request close");
    }
    switch (doorstate) {
      case 0:
        Serial.println("door motors are off");
        break;
      case 1:
        Serial.println("door motors are opening");
        break;
      case 2:
        Serial.println("door motors are closing");
        break;
    }
    Serial.println(" ");
    prevmillis = currentmillis;
  }
}

tmd3 - Yes that's what I want to do. Just haven't found the way to do it yet. And yes, the code is quite advanced as it works perfectly with exception of the motor delay I need.

gpop1 - Thanks for the code. I'll work on your code and see if I can get things to happen. As it stands now, I get a good readout of the photocell, the request to open is printed and motor on or off prints also. The request to close prints but motor on never happens in the printout. Actual motor not turning in open or close mode, however. I just did a cursory read of the code. Later today (after I finish some honey-dos) I have time to work on it further.

I think that you might want to do something like this:

void stopCloseCoopDoorMotorB()          //  stop the coop close door motor
{
  while(digitalRead (bottomSwitchPin)) {}   // Wait for confirmation on the bottom switch
//  if (bottomSwitchPinVal == 0)  -  Don't need this test - waited for this condition to begin with
  {
    uint32_t lastCloseCoopDoorMotorBTime = millis();
    while ((millis() - lastCloseCoopDoorMotorBTime) < CloseCoopDoorMotorBDelay) {}
//    {  - Don't want to update lastCloseCoopDoorMotorBTime - we just waited for the delay to elapse
//      lastCloseCoopDoorMotorBTime = millis();
//    }
//  Now it's time to shut off the motors:
    {
      digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
      digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
      digitalWrite (enableCoopDoorMotorB, LOW);                 // enable motor, 0 speed
    }
  }
// } - Don't need this - closing brace of the unnecessary trace
}

Note that you can completely skip testing the bottom switch altogether in this routine, if you want. The function that calls it already performs that test.

Code is untested.

mayhaw9999:
tmd3 - Yes that’s what I want to do. Just haven’t found the way to do it yet. And yes, the code is quite advanced as it works perfectly with exception of the motor delay I need.

gpop1 - Thanks for the code. I’ll work on your code and see if I can get things to happen. As it stands now, I get a good readout of the photocell, the request to open is printed and motor on or off prints also. The request to close prints but motor on never happens in the printout. Actual motor not turning in open or close mode, however. I just did a cursory read of the code. Later today (after I finish some honey-dos) I have time to work on it further.

nothing like honey dos…lol

your switchs are wired between the arduino pin and the ground ?

gpop1 - My mistake on the open door motor not working. Hardware error. I've been testing my problem using a 9V switching power supply for the electronics with the 7805 voltage regulator on board and another 5 V supply to power the small test motor. Since I needed to use the FDTI cable for serial, I unplugged the 9V supply and forgot to turn on the motor supply again. So the open motor works and shuts off immediately as it should when the switch is closed. Yes, the magnetic reed switches are wired between the Arduino pins 5 and 6 to ground. Close motor is not working yet.

tmd3 - Thanks again. I'll get to both codes later tonight.

I really appreciate both of you taking the time to work with me on this.

tmd3 - As written, the code compiles, the close motor starts with appropriate delay but the motor does not stop.

When I test it, it shuts off. I suspect that it's shutting off for you too.

The next thing that happens, though, is that it reads the photocell again, calls doCoopDoor() again, energizes the motor, tests the door switch and finds it closed, and then waits four seconds again. The process doesn't stop until the photocell state changes.

I think that's what's wrong with the program overall. It's written as a level-triggered program, and it really wants to be edge-triggered. It should operate the door based on the fact that the photocell has changed, rather than its state.

gpop1 - Worked with your code tonight. The open door works fine. I had to move lastPhotocellReadingTime = currentmillis; above // set photocel threshholds for the photocell reading delay to work properly.

As written, the close motor does not start until I open the top switch. The motorsOff function is called when the topSwitchPinVal == LOW so I have to open the switch to start the close motor. I tried to add a function call in the braces of the open motor if statement, but I couldn't get it to compile. If I comment out that if statement, the close motor works well and there is a delay!!!!!

if (requestdooropen == 1 && topSwitchPinVal == HIGH)  {
    digitalWrite(directionCloseCoopDoorMotorB, LOW);       // turn off motor close direction
    digitalWrite(directionOpenCoopDoorMotorB, HIGH);       // turn on motor open direction
    digitalWrite(enableCoopDoorMotorB, HIGH);
    doorstate = 1;    //used in test prints
   }

  if (requestdoorclose == 1 && doorIsClosed == 0) {
    digitalWrite (directionCloseCoopDoorMotorB, HIGH);     // turn on motor close direction
    digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
    digitalWrite (enableCoopDoorMotorB, HIGH);
    doorstate = 2;//used in test prints
 }

 if (topSwitchPinVal == LOW) {
    motorsOff();
  }


  if ((bottomSwitchPinVal == LOW) && (requestdoorclose == 1)) {
    if (currentmillis - lastCloseCoopDoorMotorBTime >= CloseCoopDoorMotorBDelay) {
      doorIsClosed = 1;
      motorsOff();
    }
  }
  if (bottomSwitchPinVal == HIGH) {
    lastCloseCoopDoorMotorBTime = currentmillis;
    doorIsClosed = 0;
  }
}

I'll get back to this tomorrow night. Have to work at the paying job tomorrow.

Thanks so much. Making progress.

David

mayhaw9999: gpop1 - Worked with your code tonight. The open door works fine. I had to move lastPhotocellReadingTime = currentmillis; above // set photocel threshholds for the photocell reading delay to work properly.

As written, the close motor does not start until I open the top switch. The motorsOff function is called when the topSwitchPinVal == LOW so I have to open the switch to start the close motor. I tried to add a function call in the braces of the open motor if statement, but I couldn't get it to compile. If I comment out that if statement, the close motor works well and there is a delay!!!!!

if (requestdooropen == 1 && topSwitchPinVal == HIGH)  {
    digitalWrite(directionCloseCoopDoorMotorB, LOW);       // turn off motor close direction
    digitalWrite(directionOpenCoopDoorMotorB, HIGH);       // turn on motor open direction
    digitalWrite(enableCoopDoorMotorB, HIGH);
    doorstate = 1;    //used in test prints
   }

  if (requestdoorclose == 1 && doorIsClosed == 0) {     digitalWrite (directionCloseCoopDoorMotorB, HIGH);    // turn on motor close direction     digitalWrite (directionOpenCoopDoorMotorB, LOW);      // turn off motor open direction     digitalWrite (enableCoopDoorMotorB, HIGH);     doorstate = 2;//used in test prints }

if (topSwitchPinVal == LOW) {     motorsOff();   }

  if ((bottomSwitchPinVal == LOW) && (requestdoorclose == 1)) {     if (currentmillis - lastCloseCoopDoorMotorBTime >= CloseCoopDoorMotorBDelay) {       doorIsClosed = 1;       motorsOff();     }   }   if (bottomSwitchPinVal == HIGH) {     lastCloseCoopDoorMotorBTime = currentmillis;     doorIsClosed = 0;   } }




I'll get back to this tomorrow night. Have to work at the paying job tomorrow.

Thanks so much. Making progress.

David

that makes sense. Just add a flag to block the code

if (topSwitchPinVal == LOW) { motorsOff(); }

so it only happens when door is being requested to open

if (topSwitchPinVal == LOW && requestdooropen == 1) { motorsOff(); }

you will have to check that logic as its early and im on my way to work.

It looks like you’re working on a state-machine implementation already. I’d recommend letting the original code sit on the shelf while you work on that, as the state-machine is likely to perform better, and be much more maintainable.

tmd3- Yes, I worked a couple hours last night and I think you are correct. I'm going to keep working along these lines and see what happens. I'm learning as I go which is a good thing for an old brain.