ajfisher's doing space

From the Blog

Jul
05

Warmer-Cooler LEDs with range finder

Posted by ajfisher on July 5th, 2011 at 9:22 pm

This little project started out really as a means of testing my Parallax Ping))) ultrasonic rangefinder that I got from Little Bird last week. As normal however a six year old wanted to understand what I was doing and how it all worked. So, what started as a test turned into something a little more fun in order to create an explanation for what was involved.

Materials:

  • A Parallax Ping))) range finder
  • Arduino (any type should work – I used a Freetronics Eleven)
  • An RGB LED (with relevant current limiting resistors – or you could use these cheap, fun DF Robot 7-LED SMD light discs). The code assumes a Common ANODE type LED.
  • A breadboard and some hookup or jumper wires

Directions:

Plug the ping))) in to +5v and GND and connect the signal pin to digital pin 7 on the arduino (this uses the same set up as the ping))) arduino example).

Connect your RGB LED to +5v and then connect your Red leg to Pin 9, Green leg to Pin 10 and Blue leg to pin 11. This is where your breadboard comes in handy because you can put your LEDs and sensor on the board then jumper everything to the arduino (see photo below for my set up).

* note that I haven’t

Wiring photos

 

Code:

Load the following code onto your Arduino (can also be downloaded from the gist here):

/*
  WARMER COOLER GAME
 
  Use a ping sensor to determine distance and then depending on the distance,
  show warmer or cooler colours.
 
  Built using a ping))) Sensor and connected to a RGB display.
 
  Uses the ping))) example in the base Arduino install,
  written by David Mellis & Tom Igoe
  http://www.arduino.cc/en/Tutorial/Ping
 
 */
 
#define PING_PIN 7
#define RED 9
#define GREEN 10
#define BLUE 11
 
#define BLUE_LONG 400
#define BLUE_SHORT 175
#define GREEN_LONG 225
#define GREEN_SHORT 75
#define RED_LONG 125
#define RED_SHORT 0
 
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
 
  // set the LED off
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
 
  // uses a common anode RGB LED (so +5v turns them off)
  digitalWrite(RED, HIGH);
  digitalWrite(GREEN, HIGH);
  digitalWrite(BLUE, HIGH);
}
 
void loop()
{
 
  long distance;
  distance = ping();
 
  // now depending on the distances we map the colours on the LED.
  // BLUE will be bright at about 350 cm fading out to 175cm
  // GREEN will be bright about 225cm fading out to about 75cm
  // RED will be faded at about 125cm getting bright to 0cm
 
  if (distance > RED_LONG) {
    digitalWrite(RED, HIGH);
  } else {
    analogWrite(RED, map(distance, RED_LONG, RED_SHORT, 255, 0));
  }
  if ((distance > GREEN_LONG) || (distance < GREEN_SHORT)) {
        digitalWrite(GREEN, HIGH);
  } else {
        analogWrite(GREEN, map(distance, GREEN_LONG, GREEN_SHORT, 255, 0));
    }
  if ((distance > BLUE_LONG) || (distance < BLUE_SHORT)) {
      digitalWrite(BLUE, HIGH);
  } else {
      analogWrite(BLUE, map(distance, BLUE_LONG, BLUE_SHORT, 255, 0));
  }
 
  Serial.print(distance);
  Serial.print("cm");
  Serial.println();
 
  delay(100);
}
 
long ping() {
  // returns the distance to the nearest object.
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  long duration, cm;
 
  // 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(PING_PIN, OUTPUT);
  digitalWrite(PING_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(PING_PIN, HIGH);
  delayMicroseconds(5);
  digitalWrite(PING_PIN, 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(PING_PIN, INPUT);
  duration = pulseIn(PING_PIN, HIGH);
 
  // convert the time into a distance
  return (microsecondsToCentimeters(duration));
 
}
 
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;
}

The code is pretty straight forward – get the distance on the range finder using the ping() function then use that distance to determine which coloured LEDs should be switched on. Note that there is some overlaps between the ranges so you get a transition from blue to green and then from green to red.

Given the rangefinder’s view is narrow and 6-year olds tend to be small and unable to stand still for long periods of time, the game then turned into how long you could keep the LEDs solid green.