Monday, December 30, 2013

The Micro And The Garrage

So there I was in Radio Shack minding my own business
Me. Shortly Before Chrismas.
(buying batteries for my car remote) a few days before Christmas, stuck in a line of people confusedly making their way through innumerable forms while signing for phone contracts that my bored co-worker whom I had dragged in after lunch noticed an Arduino display in the back of the store. 

Shortly I was checking out an Arduino Micro, a sonar range finder, a bread board and a bunch of miscellaneous tools and things.

Arduino Micro and Co.



A quick Google search later I had the Arduino SDK installed on my MacBook.  And I was ready to play.

The first project was supposed to be a simple garage parking sensor.  You put it on the wall of your garage and then as you pull in, it indicates how close you are getting to the wall.  It was inspired by a couple of close encounters between the rear gate of my wife's SUV and the closing mechanism of the garage in my old house.  
Essentially if you wanted to park indoors and unload your groceries or whatever you had stashed in the back of the car you had to make sure you pulled in all the way.
lifehacker.au describes a rather elegant option.

This problem has been solved in the past with technologies as simple as well placed tennis balls and strings.  It certainly does not require micro controllers and LEDs and ultra sonic range finders.  But we are in the 21st century here.  So we have to find something to do with our cool gadgets.  And this project was simple enough that I thought I should be able to tackle it on a quite pre christmas morning.  Luckily I was right.

So here is a quick video I made demonstrating the functionality of the completed sensor in my home office.  Cars not included.



Putting things together was pretty simple.  Especailly because the example code for the range sensor got me 90% there.  The sensor is ridiculously clever.  After giving it a 2ms pulse it originates a sonar pulse and measures when the return happens.  Then it gives back a pulse of the exact duration of the sonic round trip time.  No protocols.  No special bits.  No nothing.  (don't get too excited.   Things got more difficult as my ambition grew).    Here is what final project looked like.

I had even decided to use two indicators to show how close the car is to the wall.  One was a normal LED that started blinking ever more rapidly as you got closer and finally went solid when you were at 20cm.  The other was a color LED that chagned color from blue (system on) to green (I see you) to yellow, amber and finally red.

So while I (again - professing my utter inexperience with all things electronic) can't upload a drawing, I will upload the source code.  I hope the picture will do.

(quick note - in my short experience with things Arduino, I can attest to a fairly high number of bad parts.   The range sensor for example, I originally got did not manage to give me more than 2 good readings out of 20.  A replacement worked great.  A co-worker also bought the Mega board shortly after I got mine, and it failed to allow him to upload any code while mine worked really well with his setup.  So while I am generally of the persuasion that external factors ( libraries, kernels, cosmic rays ) are the last things to blame while diagnosing a problem have to concede that in this case in my experience the worst thing to do is to loose confidence because of a bad component.  Get two.  Return the second one if it turns out you did not need it).

Final note.  I will figure out how to get source code to look better.  Soon.

 /* Ping))) Sensor  
   This sketch reads a PING))) ultrasonic rangefinder and returns the  
   distance to the closest object in range. To do this, it sends a pulse  
   to the sensor to initiate a reading, then listens for a pulse   
   to return. The length of the returning pulse is proportional to   
   the distance of the object from the sensor.  
   The circuit:  
      * +V connection of the PING))) attached to +5V  
      * GND connection of the PING))) attached to ground  
      * SIG connection of the PING))) attached to digital pin 7  
   http://www.arduino.cc/en/Tutorial/Ping  
   created 3 Nov 2008  
   by David A. Mellis  
   modified 30 Aug 2011  
   by Tom Igoe  
   This example code is in the public domain.  
  */  
 #define RED 1  
 #define BLUE 2  
 #define GREEN 3  
 // this constant won't change. It's the pin number  
 // of the sensor's output:  
 const int pingPin = 7;  
 // The number of the led pin  
 const int ledPin = 13;  
 const int redPin = 12;  
 const int bluePin = 11;  
 const int greenPin = 10;  
 // This is the blink timer  
 long lastMillis = 0;  
 void setup() {  
  // initialize serial communication:  
  Serial.begin(9600);  
  pinMode( ledPin, OUTPUT );  
  digitalWrite( ledPin, LOW );  
  pinMode( redPin, OUTPUT );  
  digitalWrite( redPin, LOW );  
  pinMode( bluePin, OUTPUT );  
  digitalWrite( bluePin, LOW );  
  pinMode( greenPin, OUTPUT );  
  digitalWrite( greenPin, LOW );  
  lastMillis = millis();  
 }  
 void loop()  
 {  
  // establish variables for duration of the ping,   
  // and the distance result in inches and centimeters:  
  long duration, inches, cm;  
  int val;  
  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.  
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:  
  pinMode(pingPin, OUTPUT);  
  digitalWrite(pingPin, LOW);  
  delayMicroseconds(2);  
  digitalWrite(pingPin, HIGH);  
  delayMicroseconds(5);  
  digitalWrite(pingPin, LOW);  
  // The same pin is used to read the signal from the PING))): a HIGH  
  // pulse whose duration is the time (in microseconds) from the sending  
  // of the ping to the reception of its echo off of an object.  
  pinMode(pingPin, INPUT);  
  duration = pulseIn(pingPin, HIGH);  
  // convert the time into a distance  
  inches = microsecondsToInches(duration);  
  cm = microsecondsToCentimeters(duration);  
  Serial.print("Duration: ");  
  Serial.print(duration);  
  Serial.print(" us in: ");  
  Serial.print(inches);  
  Serial.print("  cm: ");  
  Serial.print(cm);  
  Serial.println();  
  if ( cm > 200 ) {  
   //At 200 cm we don't bother  
   digitalWrite( ledPin, LOW );  
   lastMillis = millis();  
   // Set the light to Blue to signify the system is on  
   setColor( 0, 0, 255 );  
  } else if( cm <= 20 ) {  
   //At 20 cm - we are constant on  
   digitalWrite( ledPin, HIGH );  
   lastMillis = millis();  
   // Set the light to Red to show we are in the danger zone  
   setColor( 255, 0, 0 );  
  } else if( cm <= 200 && cm > 100 ) {  
   // At 200 - 100 cm we blink two times per second  
   if( millis() - lastMillis > 500 ) {  
    val = digitalRead( ledPin );  
    // blink  
    digitalWrite( ledPin, val ? LOW : HIGH );  
    lastMillis = millis();   
   }  
   // Set the light to green. We see you  
   setColor( 0, 255, 0 );  
  } else if( cm <= 100 && cm > 50 ) {  
   // At 100 - 50 cm we blink four times per second  
   if( millis() - lastMillis > 250 ) {  
    val = digitalRead( ledPin );  
    // blink  
    digitalWrite( ledPin, val ? LOW : HIGH );  
    lastMillis = millis();   
   }  
   // Set the light to Yellow. Cover that break pedal.  
   setColor( 255, 255, 0 );  
  } else if( cm <= 50 ) {  
   // At 50 to 20 cm we blink five times per second  
   if( millis() - lastMillis > 100 ) {  
    val = digitalRead( ledPin );  
    // blink  
    digitalWrite( ledPin, val ? LOW : HIGH );  
    lastMillis = millis();  
   }  
   // Set the color to Organgish. Start breaking  
   setColor( 255, 128, 0 );  
  }  
  delay( 50 );   
 }  
 long microsecondsToInches(long microseconds) {  
  // According to Parallax's datasheet for the PING))), there are  
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per  
  // second). This gives the distance travelled by the ping, outbound  
  // and return, so we divide by 2 to get the distance of the obstacle.  
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf  
  return microseconds / 74 / 2;  
 }  
 long microsecondsToCentimeters(long microseconds) {  
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.  
  // The ping travels out and back, so to find the distance of the  
  // object we take half of the distance travelled.  
  return microseconds / 29 / 2;  
 }  
 void setColor(int red, int green, int blue) {  
  analogWrite(redPin, 255-red);  
  analogWrite(greenPin, 255-green);  
  analogWrite(bluePin, 255-blue);   
 }  




Arduinos

It finally bit me.  The bug that has been going around the office and the tech community at large for a couple of years now finally got me.
Arduino Micro
Arduino Mega

I am the proud owner of a couple of Arduino boards and an ever greater number of accessories.  Shortly ( I hope ) I will be receiving an ODroid board as well (they start shipping on Jan 14th 2014 ).

This is not the first time I have played with the Arduino.  The first time was about 6 months ago.  I created a small experiment with a board I borrowed from (and still have not returned to - it is somewhere in my moving boxes ) to a coworker.  The idea was to create an analog display of various KPIs of my computer.  Using a 5v analog voltmeter things worked well.  Except it looked so borring.   There was exactly one type on most shopping sites and it was square and ugly.  Amp meters came in all sizes and shapes - even round and backlit.  But I suck at electronics.

This is a good time to get into this.  I suck at electronics.  I had my required electrical engineering class in college as a part of my CISC curriculum and I never looked back.  Software and Networking were good enough for me, so as long as the little black things soldered to the insides of my equipment did not act up and got faster from year to year I was a happy camper.  This makes this little excursion into what most electronics guys would probably think of as terrace tea garden feel like an expedition into the depths of the electronics Amazonian jungle for me.

Anyway.  The project with the analog meters stalled.  I still think its cool, and I may resurrect it some day.  Probably after I read a good Steam Punk book...  

This time the projects are actually working out much better, and although I have no inkling of what the ultimate practical purpose of the gadgets I am building is going to be, they are certainly have practical purposes...  thought they are unwieldy, fragile and too expensive in their current prototype incarnation.

So I am going to post a couple of little articles detailing my adventures.  If you follow, the going shall be every so slightly less thorny.  But then its while pulling the thorns that the best stories get told...

Innagural

So 2013 is coming to an end.  It was a whirlwind of year for me.  So many new things to get used to.  So many new challenges to conquer.  And now, enjoying its last days, I figured I will start this little blog.
Lazy Morning at The Farm

It won't be the most organized thing in the world.  Its going to probably be mostly about side projects.  At least the first few posts would be.  It will also probably be about travel.  And it will probably also be really quiet for extended periods of time when nothing worth sharing is happening.

I don't know how you found this (I know that web crawlers and spiders are the only things likely to read this) but welcome, and I hope you find something cool in these here millibits.