IMAG0209-1024x575

A couple months ago my brother introduced me to the Arduino microcontroller. I had always been interested in small electronics, but let’s be honest I didn’t know the first thing when it came to resistors or transistors. I saw some potential in the device, so in my usual manner I jump right in head first. After picking up a board at the local Radio Shack, I plowed through some basic circuits and applications to get a feel for the design environment. They really made this thing easy for the entry level person. I quickly realized that my weakest area wasn’t so much the electronics, but instead was in the C programming that it uses. I did what anyone in my position would do; I picked up a C programming book and spent a month or so working through it.

The entire time I was reading the C programming book, I was also working on the design for my first real Arduino project. This project would be a replacement for the ball and string system that was currently hanging in my garage. I decided to build a garage parking sensor to assist my wife and I with parking. I figured I could use the ultrasonic sensor I saw at Radio Shack to measure how far away a vehicle was and then display a red/yellow/green light system to know when to stop.

High Level Requirements:

  1. The device shall be able to measure the distance of an incoming object (car)
  2. The device shall be able to illuminate a series of lights that corresponds to three possible zones: Green (greater than 40 inches), Yellow (between 4 inches greater then threshold and 39 inches), and Red (threshold plus or minus 3 inches).
  3. The device shall be able to indicate when the object is too far inside of the threshold value.
  4. The device shall be able to be calibrated to any distance within a 15 foot range and store this value in a semi-permanent memory, retaining the data in the event of a power loss.
  5. The device shall provide the ability to be reset in the case something goes wrong.

I figured the first thing was to get a hold of some of the components and breadboard it out. I needed a proof of concept before I invested a lot of time and money in building the device. I went back to Radio Shack and learned my first real lesson about DIY prices. They can be a little expensive when purchased locally at the store. They wanted something like 30 bucks for the PING Ultrasonic sensor, Ouch. I could buy a commercial parking garage sensor for that price. I figured there had to be a better way, so I found myself scanning the web for a possible solution. I was able to find a HC-SR04 Ultrasonic sensor for around two bucks. The best part was that cnobile developed a class library specifically for the HC-SR04 sensor (link is located to the right).

IMAG0206-1024x575

I also decided that I didn’t want to use my only Arduino board as permanent component of the end product. I figure the best route to go would be to build a bare bones Arduino board myself. With the help of Ryan Winters tutorial, I was able to build an Arduino and the sonic sensor circuit on a breadboard. Surprisingly enough everything worked pretty much on the first try. This gave me the confidence to move to the next phase of the project.

I sketched out a circuit designed based on what I used in the proof of concept device. Then created a parts list and started working on an improved program to control the final prototype.
Over the course of few weeks I built up the prototype. I decided to take a modular approach to help break up the activity. The first thing I built was a control module. This was a true learning experience for me. I did many things wrong right out the gate. In the end the module worked, but it wasn’t as easy as I thought. My first attempts at soldering included a cheap (low watt) iron and lead free solder. This was a mistake; I should have watched those video tutorials first. I quickly learned that you need to a decent iron and rosin core based solder. The stuff I ended up using was a 60/40 Rosin Core .032 diameter solder. I think I will try to find something a little smaller for my next project, as this seemed a little think for my purposes.

IMAG0212

Once I had a working barebones Arduino board, I put together the light module. This was my first attempt at building a circuit from scratch, though it is probably one of the easier ones to start with. I decided to put six 5mm LEDs of each color in series with each other. I was able to control all 18 LEDs through the use of 3 transistors. I averaged the required power in amps for a series of LEDs and picked a transistor that could support that range. After the module was completed I was a little disappointed with the Green portion. These seemed to be less bright at different angles. Something for me to look into in the future is whether or not I should be using a different resistor size for the different colors. I remember reading somewhere once that different colors illuminate at different brightness based on input power. Overall, the module worked as needed for the prototype.

IMAG0191-e1353380287292-1024x786

The final module was a bit simpler to build. I needed a way of resetting the device and calibrating it per the requirements. I quickly put together some buttons on a blank PCB board and didn’t think much about it. Due to a lack of attention to this portion, which I thought was straight forward; I ended up with a less than ideal solution for the calibration button. The figure on the left shows the design I ended up using and the one on the right shows a little simpler approach. In the design that was implemented I have to supply a HIGH voltage to pin 11 at all times. When the button is pushed the circuit is complete and the reading from Analog pin 5 changes from 0 to around 1019. That change is what I use to trigger my calibration code.

To pull it all together I used some empty plastic containers as the housing units with a couple standoffs from the hardware store. The final prototype looks a bit rough around the edges, but it functions as expected. My one complaint at the moment is that there is nothing in the code to measure how long it has been since the last change, so the LEDs stay on all the time. I think it would a good idea to add some way for the device to know when to shut down the light module until it is needed. Maybe I will be able to incorporate that in the final design. The schematic, photos, and code for the prototype are provided below.

Lessons Learned:

  1. Rosin Core solder is much easier to work with than lead free solder.
  2. Buttons have a right way to be integrated into a circuit and a wrong way, make sure you are aware of what pins you are soldering to.
  3. Working with blank PCB boards is a little harder than I anticipated. I think it would be easier to design a circuit board in Eagle and have then manufactured through Itead Studio or Seeed Studio. Both of these places will print out small project boards for pretty cheap.
  4. A 9 volt battery will only power a system like this for around 200 hours. It appears that AA batteries are way more efficient at providing power as you don’t loss 4 volts in the power regulator. I will end up running my garage sensor off of an AC to DC wall wart.
  5. Need a method for shutting down the LEDs if there has been no change for a specified amount of time.
  6. I need to investigate the problem encounter with the Green LEDs.

Original Source Code:

Get Updated Source Code


 #include <Ultrasonic.h>
 #include <EEPROM.h>
 
 #define TRIGGER_PIN 5
 #define ECHO_PIN 6
 const int red = 4; // Red bank of LEDs
 const int yellow = 3; // Yellow bank of LEDs
 const int green = 2; // Green bank of LEDs
 const int calibration = 11;  // Calibration button
 int threshold = 0;
  
 Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
 
 /**************************************************************************************
  * Setup Area
  **************************************************************************************/
 void setup()
{
 // I don't set the ref pin and the analogread pin because 
 // Arduino automatically sets them
 pinMode(red, OUTPUT);
 pinMode(yellow, OUTPUT);
 pinMode(green, OUTPUT);
 pinMode(calibration, OUTPUT);
 digitalWrite(calibration, HIGH);
 
 // Sets the threshold value equal to the value in EEPROM
    threshold = EEPROM.read(0); 
 
 for(int i = 0; i < 6; i++) // When the system first resets it should flash the leds
   {
     digitalWrite(red, HIGH);
     digitalWrite(yellow, HIGH);
     digitalWrite(green, HIGH);

     delay(100);

     digitalWrite(red, LOW);
     digitalWrite(yellow, LOW);
     digitalWrite(green, LOW);

     delay(100);
    }
}

 /**************************************************************************************
  * Run Loop Starts
  **************************************************************************************/
 void loop()
{
  // Inlude the code for taking a sensor sample and converting it to a measurement
  float cmMsec, inMsec;
  long microsec = ultrasonic.timing();
  
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  inMsec = ultrasonic.convert(microsec, Ultrasonic::IN);
  
  int currentDistance = (int)inMsec;
  
 /**************************************************************************************
  * Calibration Button
  **************************************************************************************/
  // Execute the calibration function
  if (analogRead(5) > 800)
   {
    // Earse the current value in the EEPROM
    EEPROM.write(0, 0);
     
    // Write the current distance measurement to the first byte in EEPROM
    EEPROM.write(0, currentDistance);  
    
  // Send the program back to the setup function to start the system over,
  // the flashing at the end of setup will let you know that the calibration when okay
   setup();
   }
   
  /**************************************************************************************
  * Determine what zone the car is in
  **************************************************************************************/  
  else 
   {              
        if (currentDistance > (40 + threshold))
          {
          digitalWrite(green, HIGH);
          digitalWrite(yellow, LOW);
          digitalWrite(red, LOW);
        }
        if (currentDistance <= (39 + threshold) && currentDistance > (threshold + 4))
          {
          digitalWrite(green, LOW);
          digitalWrite(yellow, HIGH);
          digitalWrite(red, LOW);       
          }
        if (currentDistance <= (threshold + 3) && currentDistance > (threshold - 3))
        {
          digitalWrite(green, LOW);
          digitalWrite(yellow, LOW);
          digitalWrite(red, HIGH);
        }
   }
   delay(50);
   
}