Samstag, 27. Dezember 2014

CatDetect - a touchless and remote door bell

The Story behind this project

My parents have three cats and they are allowed to roam outside in the backyard and the gardens in the neighbourhood during the day. But in the evening when it dawns we like to have them inside where it's warm and safe. Especially in winter it's important that they're in before it gets too cold. However, one cannot watch the door the whole day and look whether they want in or not; and a cat flap would allow them to bring all kinds of mice and other pests inside. That's the story how it came to this little project.

Different concepts

How could you detect a cat sitting infront of the door (reliably!)?
  • RFID
    (+) distinct identification of our cats, hardly any false alarms
    (-) range too short, the readout of the cats' RFID chip only works when really close to the detector (< 5 cm) or they needed another RFID chip at a collar which they would lose (we tried that before); cost intensive
  • Pressure plate
    (+) probably invisible under the doormat
    (-) needs to be very sensitive because the cats aren't that heavy -> more likely to have false alarms
  • Light barrier
    (+) relatively small and cheap
    (-) heavily dependent on lighting conditions, large effort needed to "clean" the signal from disturbance; emitter and receiver needed
  • Reflective light barrier
    (+) probably the smallest solution
    (-) heavily dependent on lighting conditions; cats' fur isn't very reflective
  • Reflective sonar barrier
    (+) small, cheap (an ultrasonic rangefinder costs about $2) and very reliable (lighting conditions don't matter)
    (-)  temperature dependent
I finally went with the ultrasonic method, and I even had some sensors lying around, as well as a simple wireless doorbell. The bell button and sender unit ran off a 12 V battery and was testet to run even at 8 volts with only slightly less range. A pair transistors is used to short the push button electrically by the ATtiny84. I added a few LEDs to simplify the positioning and troubleshooting. Every 1.5 seconds the sensor is activated and read out once. The green LED indicates a correct measurement, after 4 good readouts the bell is rung (red LED). If motion is detected but out of range, the yellow LED blinks briefly. Everything was put on a little breadboard.
The whole device is powered by a Nokia charger which outputs 8 Volts - quite strange, since it is specified to 5 volts. Probably the voltage drops to 5 when enough current is drawn during the charching. That is actually quite handy for my application because it can still power the sending unit as well as it can be regulated down easily with a 78L05 to the right voltage for the microcontroller and the ultrasonic sensor.
However the testing went not that well. It sometimes worked, but far away from reliable.

A fail?

To this point, yes. There where a lot of false alarms and undetected cats. For example, after a cold night the whole device stopped working at all. Unplugging it briefly, and it worked again. I couldn't imagine what the problem was and eventually I stopped working on it. That was a year ago.

Why breadboarding is not a great idea

This winter I gave it another try. The circuit and the software hasn't been changed, but I soldered everything on perfboard and put it in a nice 12x6x4 cm ABS box to keep it safe from spray water. Of course it isn't waterproof, but under the balcony there shouldn't be any downfall. I cut out holes for the LEDs, the sensor (those 16 mm holes were a real pain to drill) and the power jack (the charching socket salvaged from the broken cell phone the charger is from).

The finished product

I also threw together a simple artwork to make the box look pretty and give the user some information what the LEDs mean.

It is now exactly two months in use, and everything is working out really good. The electronics don't seem to fail, even at temperatures less than -10 °C. There hasn't been a single false alarm or a cat sitting infront of that hasn't been detected correctly. Awesome!

Here a little video where I catched one of the cats "using" it ;)

In case you want to take a look at it, here is the code (neither pretty nor efficient, I threw it together in just an hour or so)

const byte gongpin = 0;
const byte trig    = 1;
const byte echo    = 2;
//debug leds:
const byte red     = 6;
const byte yellow  = 7;
const byte green   = 8;

const long waittime = 1500;   //cycle
const int triggercm = 70;
const int minimalcm = 5;
const int numberofreads = 4;
const int repeattime = 20000;  //milliseconds
const int hightime = 500;      //milliseconds

void setup() { 
  pinMode(gongpin, OUTPUT);    
  pinMode(trig, OUTPUT);  
  pinMode(echo, INPUT);   


bool gonged = false;
bool gong = false;
int cm = 0;
byte count = 0;

void loop() {

void handleGong(){
  static long lm = millis();
  static bool activated = false;
  if (count >= numberofreads && !activated){
    count = 0;
    activated = true;
    gonged = true;
    lm = millis();
  if (activated && (millis()-lm >= hightime)){
    activated = false;
  if (gonged && (millis()-lm >= repeattime)){
    gonged = false;

void initialRead(){
  static long lm = millis();
  if (millis()-lm > waittime){  
    lm = millis();
    cm = readCm();
    if (cm < triggercm){
      if (!gonged) count++;
    count = 0;

long readCm(){
  digitalWrite(trig, HIGH);
  digitalWrite(trig, LOW); 
  long microseconds = pulseIn(echo, HIGH, 100000);
  long c = microseconds / 29 / 2;
  if (c < minimalcm){
    c = triggercm*2;
  return c;
- Marv