Garageland #3

Well it took longer than I expected but it’s all done now.

When I came to put the yellow crap in the case it became obvious that it wouldn’t fit when the micro USB was connected. That was fairly obvious and I should have spotted it before. I did come across a breakout board amongst all the other stuff the other day so I tried that instead – it would require a bit of soldering but it would easily fit into the case, even with the USB connector. Testing the voltages on the pins though showed that they were mostly about 2V, even pins that should be low since that’s what I was setting them to. At that point I abandoned the yellow crap.

A quick rummage in my box of bits yielded a board I built to drive my sadly neglected robot. It’s a bit of a mess as I tried to fix what I thought were noise problems by throwing capacitors at it and hoping something stuck. Anyway, it’s just a bog standard “breadboard Arduino” so it is perfect for this application – especially as it’s hidden out of sight.

Dr Frankenstein's Arduino

Dr Frankenstein’s Arduino

I added the micro USB connector and a resistor to ground to allow me to put an LED in the enclosure lid (just to show that it’s alive and kicking really).

Next up I fettled the wiring including twisting up a couple of meters for the ultrasonic sensor. That’s where things went wrong. I had used some wire I have a lot of, mostly with breadboards or for short runs. It’s fine for that but the ultrasonic sensor wouldn’t work with it. It turned out to be much too thin and have way too high a resistance over that length and the sensor just wasn’t triggering. I dug out a thicker gauge of wire and made an even longer run of that which worked fine.

It’s all up and running now. Unfortunately I didn’t take any photos of the finished layout – it’s pretty much as shown yesterday. I did take a short video though…

I wanted the side door in the shot as it isn’t possible to see that the light goes off otherwise. That’s it, no fancy delays or other faffage – it just jobs the jobs as things happen. Here’s the code (which I may, or may not, get around to uploading to GitHub as it’s relatively trivial):

// ---------------------------------------------------------------------------
// lightEmUp
//
// Simple state machine to switch on garage lights when the door opens and 
// to switch them on again (after a when the doors close again.
//
// This is *really* simple. It does nothing clever, at all.
//
// When we start up, we start by turning the relay off (it should be anyway
// while we've been powered down).
//
// We then check if the door is open or closed and save the state.
//
// Then we just repeatedly call the sensor distance routine:
//
//    If we're OPEN and we see something in range, assume the door has closed 
//    and turn off the relay. Make the new state CLOSED.
//    
//    If we're CLOSED and we don't see anything in range then we assume that
//    the door has opened. Turn on the relay and make the new state OPEN.
//
// Then we do a dumb delay for 0.5s since all we're doing is looking for
// something in range.
//
// ---------------------------------------------------------------------------

// Actions occur only on the transition between states so define the 
// following obvious states:
enum States {OPEN, CLOSED};
States state;

#include <NewPing.h>

// Declare the ultrasonic sensor
const int SONAR_PIN=7;          // Arduino pin tied for HC SR-04 trigger and echo
const int MAX_DISTANCE=30;      // Maximum distance (cm)
NewPing sonar(SONAR_PIN, SONAR_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

// Pin to control relay
const int relayPin = 8;

// Pin to blink an LED to show we are alive
const int ledPin = 9;
int ledCount = 0;

// Return distance in cm
unsigned int getDistance() {
  unsigned int cm = sonar.ping() / US_ROUNDTRIP_CM; // Send ping, get distance (cm).
//  Serial.print(cm);
//  Serial.println(" cm");
  return cm;
}

void setup() {
  
//  Serial.begin(115200);
  
  // Setup relay pin
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  
  // Setup LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  delay(500);

  // Determine initial state
  if ( getDistance() > 0 ) {
    state = CLOSED;
  } else {
    state = OPEN;
  }
}

void loop() {
  unsigned int dist = getDistance();
  
  switch (state) {
    case CLOSED:
      if ( dist == 0 ) {
        // Door has opened, lightEmUp!
        digitalWrite(relayPin, HIGH);
        state = OPEN;
      }
      break;

    case OPEN:
      if ( dist > 0 ) {
       // Door has closed, switch off
        digitalWrite(relayPin, LOW);
        state = CLOSED;
      }
      break;;
  }
  
  // toggle LED (flash every 2.5s)
  if ( ++ledCount == 5 ) {
    digitalWrite(ledPin, HIGH);
    ledCount = 0;
  }
  delay(100);
  digitalWrite(ledPin, LOW);
  
  // We'll update at around 2Hz, allow for delay just above
  delay(400);
}

Well, that’s done. The sensor position might need some tweaking if the passing of the car interferes with the operation of the lights – the other option is to reduce the sensor range.

Now I’m totally happy with the garage doors without messing up the control panel or shelling out a fortune.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*