Robert Persichitte
Published © MIT

Distance Sensor

Mount in front of your garage to help you park at teh exact right distance.

IntermediateFull instructions provided2 hours10,172
Distance Sensor

Things used in this project

Hardware components

Pushbutton Switch, Momentary
Pushbutton Switch, Momentary
The enclosure has an opening for a 16mm button.
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Adafruit NeoPixel Digital RGBW LED Strip - White PCB 30 LED/m
I used a strip containing 8 NeoPixels, but you can adapt the code to use more or fewer.
×1
Arduino Mega 2560
Arduino Mega 2560
The wiring diagram uses an Arduino Mega, but this would just as easily run an on Uno. It would probably also run on other boards, but I haven't tested it.
×1
GE Outlet Light Socket
(Optional)
×1

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Used for printing the enclosure. Optional if you can find a way to secure all the components.

Story

Read more

Custom parts and enclosures

3D Printed Enclosure

This houses the distance sensor, button, and NeoPixels. There isn't a spot for the Arduino, but mine just sat on top.

Schematics

Wiring Diagram for the unit

This is how you wire the distance sensor, button, and NeoPixels to the Arduino.

Code

Distance Senor Code

Arduino
This is the code to upload to the Arduino. It sets allows users to interact with the device.
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <EEPROM.h>

#define PIN 12
#define BUTTON_PIN 11
#define echoPin 10
#define trigPin 9
#define max_dist 300
#define set_loc 1
#define NUM_LEDS 9
#define BRIGHTNESS 50

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);


//Initialize glabal variables
int set_dist;
float duration, distance;

void setup() {
  // Initialize neopixels
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show();

  // Initialize SR04
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Initialize set_dist
  set_dist = EEPROM.read(set_loc);
  // Set for testing
  // set_dist = 10;
  Serial.begin(9600);
  // This fixes a problem with the button reading high on startup
  while(digitalRead(BUTTON_PIN) == LOW){
    
  }
}

void set_lights(uint8_t distance) {
  int total_distance = max_dist - set_dist;
  /*
      We will fill up the colors first with blue,
      then green, then red when too far.
  */
  // Deterimne dist from set_dist
  int dif = distance - set_dist;
  int half_dist = (float) total_distance / 2;

  if (dif > half_dist) {
    // Set lights to be blue
    int to_lite = ((float) dif / half_dist - 1) * NUM_LEDS;
    for (int i = 0; i < NUM_LEDS; i++) {
      if (i > to_lite) {
        strip.setPixelColor(i, strip.Color(0, 0, 255, 0));
      } else {
        strip.setPixelColor(i, strip.Color(0, 0, 0, 0));
      }
    }
    strip.show();
    return;
  }
  if (dif > 0) {
    // Set lights to be blue and green
    int to_lite = ((float) dif / half_dist) * NUM_LEDS;
    for (int i = 0; i < NUM_LEDS; i++) {
      if (i > to_lite) {
        strip.setPixelColor(i, strip.Color(0, 255, 0, 0));
      } else {
        strip.setPixelColor(i, strip.Color(0, 0, 255, 0));
      }
    }
    strip.show();
    return;
  }
  if (dif <= 0) {
    // Set all lights to red
    for (int i = 0; i < NUM_LEDS; i++) {
      strip.setPixelColor(i, strip.Color(255, 0, 0, 0));
    }
    strip.show();
  }
  Serial.println(dif);

  // Setup button
  pinMode(BUTTON_PIN, INPUT_PULLUP);

}

int get_distance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = (duration * .0343) / 2;
  return (int) distance;
}
void flash(uint32_t c){
    for (int i = 0; i < NUM_LEDS; i++) {
      strip.setPixelColor(i, c);
    }
    strip.show();
    delay(1000);
    for (int i = 0; i < NUM_LEDS; i++) {
      strip.setPixelColor(i, strip.Color(0, 0, 0, 0));
    }
    strip.show();
}
void loop() {
  // put your main code here, to run repeatedly:
  set_lights(get_distance());
  delay(100);

  if (digitalRead(BUTTON_PIN) == LOW){
    flash(strip.Color(0,0,0,255));
    delay(1000);
    flash(strip.Color(0,0,0,255));
    delay(1000);
    flash(strip.Color(255,0,0,0));
    set_dist = get_distance();
    EEPROM.update(set_loc, set_dist);

  }
}

Credits

Robert Persichitte

Robert Persichitte

3 projects • 3 followers

Comments