Electronic cat door completed (but with intermittent problems)

Hi all,

I just wanted to show that I finally finished the electronic cat door that I started last year. I started a thread at the old forum a while back:
http://arduino.cc/forum/index.php/topic,20190.0.html

And now wanted to show the (almost) finished project:

I say it's almost finished because I'm having a strange problem with it intermittently. Sometimes after the door comes up, hits the upper limit switch, it doesn't go back down. :frowning: And even less, it will not open after you hit the button. And once or twice, after it came back down, the servo kept spinning even though the acrylic cover hit the lower limit switch.

I wouldn't think it's the code, because what's weird is that I can pull the circuit board I made and bring it back into my room and test it pretty extensively, and it never seems to fault. See this video: Electronic Cat Door Standalone Board Complete - YouTube

But just in case, here's the code:

// Controlling a full rotational servo

// Attach red wire of servo to TO SEPARATE POWER SUPPLY
// Attach black wire of servo to GND on Arduino
// Attach control wire of servo to pin 9 on Arduino


// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int topLimitSwitch = 4; // the upper limit switch
const int bottomLimitSwitch = 8; // the lower limit switch
const int ledPin =  13;     // the number of the LED pin (Currently not used)

// Variables will change:
int ledState = LOW;         // the current state of the output pin
int lastButtonState = LOW;  // the previous debounced button state
int lastReading= LOW;       // the previous reading from the input pin
int speakerOut = 6;         // piezo

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the input pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers



int servoState = 1500; // the current state of the servo

#include <Servo.h> 

Servo myservo;  // create servo object to control a servo 



void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  
  pinMode(buttonPin, INPUT);
  pinMode(topLimitSwitch, INPUT);
  pinMode(bottomLimitSwitch, INPUT);
  pinMode(ledPin, OUTPUT);
  
  pinMode(speakerOut, OUTPUT);
} 

void loop() 
{  

  //myservo.writeMicroseconds(1500); //stay idle
  
  //myservo.writeMicroseconds(1500); //
  //Serial.print("Running motor at: ");
  
  
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  
  // read the state of the upper and lower limit switches into a local variable:
  int upperSwitchReading = digitalRead(topLimitSwitch);
  int lowerSwitchReading = digitalRead(bottomLimitSwitch);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastReading) {
    // reset the debouncing timer
    lastDebounceTime = millis();
    // save the reading.  Next time through the loop,
    // it'll be lastReading:
    lastReading = reading;
  }
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so accept the button changed state:
  
    // toggle the LED if the state of the button changes from LOW to HIGH:
    if (lastButtonState == LOW && reading == HIGH) {
      /*if (ledState == HIGH) {
        ledState = LOW;
        //servoState = 1520;
        // The below line will stop the servo - we don't need to use this if/then bracket anymore as it is not how we want it to work
        //myservo.writeMicroseconds(1500);
     } else {
        ledState = HIGH;
        //servoState = 3000;
        //myservo.writeMicroseconds(500);
      }
      
      digitalWrite(ledPin, ledState);
      */
      
      
      
      // MAIN CODE GOES HERE
      
      // Turn on servo clockwise to raise cover until it hits the upper limit switch
      while (digitalRead(topLimitSwitch) == LOW) {
        myservo.writeMicroseconds(3000);
      }
      
      // Make servo be idle again
      myservo.writeMicroseconds(1520);
      
      // Wait 8 seconds
      delay(8000);
      
      
       // beep 5 times to give the cat a warning before closing door
        for (long i = 1; i < 6; i++)
        {
          analogWrite(speakerOut,128);
          delay(250);
          digitalWrite(speakerOut, LOW);
          delay(250);
        }
      
      
      
      // Turn on servo couter-clockwise to lower cover until it hits the lower limit switch
      while (digitalRead(bottomLimitSwitch) == LOW) {
      
        // ok, now close the door (rotate servo counter-clockwise)
        myservo.writeMicroseconds(1300);
     
        //digitalWrite(speakerOut,HIGH);

       /*   for (long i = 0; i < 2048 * 3; i++ )
        {
            // 1 / 2048Hz = 488uS, or 244uS high and 244uS low to create 50% duty cycle
            digitalWrite(speakerOut, HIGH);
            delayMicroseconds(244);
            digitalWrite(speakerOut, LOW);
            delayMicroseconds(244);
        }
        */

      }
      
      
      
      // Make servo be idle again
      myservo.writeMicroseconds(1520);
      
      
      // END MAIN CODE
      
    }
    lastButtonState = reading;
  }
  
  
}

When I originally 'completed' this project, I used CatIII twisted pair wires for the wiring, and it seemed the problems happened way too much, so I thought maybe it was the wiring. So I ripped all those wires out, and used 22 gauge solid copper wires (individual wires), then as you can see in the video, covered them with the white wire track. It did seem to get a lot better, but it's still happening. :frowning:

Minus the power-indicating LED (and the resistor for it), and the filtering 100 uF capacitor, the following Fritzing file shows how I built my board:

Do you think that my problems are because I didn't add a .1uF capacitor? Other than that, I have no ideas, and would love to get this project out of my hair so I can start my next Arduino project. :wink:

Thanks

Perhaps moisture is to blame. Because the setup is mounted on an outside door there is a possibility of some condensation on your components as the temperature and humidity changes. If it is a metal door the condensation scenario is even more likely. I had a similar problem with an RFID reader. If that is the problem, you can either move the electronics elsewhere or pot them in epoxy.

This is a wooden door. It is an 'outside' door, but the electronics are on the inside side of the door...although I guess this is probably obvious from the video, but just wanted to be sure. :wink: So could this still pose a problem?

Thanks.

Nice work!
It might not be a bad idea to sprinkle a few .01 caps in there.

Just curious how you trained your cat to push the buttons.
How long did it take the cat to learn?

electronic cat door

I feel there should be a hyphen in there somewhere, otherwise the interpretation is ambiguous.

@ BroHogan - Thanks. And I'll probably start trying to figure out how to add some little caps in there somehow now that it's after the fact. Regarding training the cats, I'm still in the process - I keep having interruptions with keep having to modify this system and the problems. So I keep going back to the manual way of locking the cats in at night.

@ AWOL - I'm not sure I understand your statement. :frowning:

@ AWOL - I'm not sure I understand your statement.

A door for an electronic cat, or an electronic door for a cat? :wink:

Ooohhh. Lol! I never saw that.

I used CatIII twisted pair wires for the wiring,

Well of course you did, what else would have been more appropriate? :smiley:

Lefty

That bad huh? I didn't know being a newbie and all.

Is the room heated?

I (perhaps badly) assumed it was in an unheated garage. If the indoor temperature is well regulated and it's a wood door, chances are the moisture theory is bust.

In what time frame do the intermittent failures happen? Are they pretty normally distributed, or once something goes wrong do other failures happen in close time proximity?

No, the garage isn't heated - it was a correct assumption. :slight_smile:

I've been trying to figure out a pattern or anything that might be triggering it too, but I can't seem to pinpoint anything. Usually the only time I get to test it is in the early morning (when it's cold), or in the evening (again, when it's cold). But I don't think the temperature drops below 30deg Faranheit.

You mentioned 'pot them in epoxy' ... what does that mean/entail?

Pretty much the same effect as a "conformal coating" if that helps any. Actually conformal coating is probably wiser. Here is the potting wiki which explains it for your edification. Potting (electronics) - Wikipedia

All I meant is you can mix up some 5min epoxy, and use a brush to paint a thick layer of it on the circuit, completely coating it. Clear hobby grade epoxy is a pretty good insulator, and is VERY waterproof. It's often used to keep boards from shorting out in harsh environments where conductive substances (water in this case) might come into contact with the board. The only problem is it makes repairing/reworking the board nearly impossible :confused:

It would probably be equally as effective to build an enclosure for the Arduino, too. Make it aluminum and it will help shield it from emf.

You probably could simplify your door setup by making a large cardboard pully to go on the servo (rotated to be parallel with the door) so the door could be opened/closed by the normal 180 deg rotation of the servo.

landru - thanks for the extra info...I'll check into that.

zoomkat - thanks for the idea - I think I follow, and yeah, that would be simpler. I don't know if I want to change it all up now that I've got the hardware in place though.

I thought of something else I can try. I'm going to take out my custom board that I made, and place my actual Arduino Duemilanove board in its place temporarily and see if anything changes. If it works without any problems, I'm not sure exactly what that will tell me, but it will tell me something, right?