├── .gitignore
├── Arduino_Garage_Breadboard.pdf
├── README.md
├── TODO.txt
└── src
├── Arduino Garage.ino
└── ledring.ino
/.gitignore:
--------------------------------------------------------------------------------
1 | .pioenvs
2 | .piolibdeps
3 | .clang_complete
4 | .gcc-flags.json
5 | .pioenvs
6 | .piolibdeps
7 | .ini
8 | .yml
9 |
--------------------------------------------------------------------------------
/Arduino_Garage_Breadboard.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvrickv/Arduino-Garage/7ad4ce1c6bad06ad1f63b194e5100ddd98a2ddfc/Arduino_Garage_Breadboard.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Arduino-Garage
2 | Parking distance sensor using ESP8266, HC-SR04, and Addressable LED strips/rings
3 |
4 | I started this project to solve a personal issue -- parking the car just right so that I have space to walk around it in the garage while leaving a reasonable gap to the garage door.
5 |
6 | It started as a Python/Pi Zero project and now I have decided to port it to Arduino/ESP8266. Eventually I plan to move it to an ATTiny85 for an even smaller footprint/power profile.
7 |
8 | Two important notes:
9 | 1) I've got very limited coding skills
10 | 2) I have no idea what I'm doing
11 |
12 | So if you have a better way of doing some of this stuff, I'm totally open to suggestions.
13 |
14 | The biggest challenge so far is "noise" in the sensor data. They are rock solid with large/flat objects. But can struggle with curvy car shapes and especially with empty spaces or cluttered garages. I've tried many techniques to smooth the data but now am running into performance issues with the MCUs. It will likely be magnified with the ATTiny85.
15 |
16 | The code uses a few awesome libraries that made this project super easy. Among them:
17 |
18 | NewPing // sensor library. Much more flexible than the UltraSonic library in Arduino
19 |
20 | FastLED // library for controlling individually addressable LEDs
21 |
22 |
Usage
23 |
24 | Usage is simple. A parking distance is set by default (100cm). As the car approaches the sensor, the LED strip/ring fills with Green LEDs, until the parking position is reached, where the LEDs turn Red.
25 |
26 | After a few seconds parked (Red), the LEDs fade out.
27 |
28 | To change the distance, begin by parking your car at the intended parking distance. Put your hand over the sensor at about 5 cm. The LEDs will change to a rainbow pattern. Keep your hand over the sensor until a countdown starts. Move your hand out of the way, and the MCU will take several readings, and set the parking distance. The distance is written to EEPROM so it is not lost if power is cycled.
29 |
30 | That's it!
31 |
32 | I'll be adding schematics and more soon.
33 |
34 | Thanks for stopping by.
35 |
36 | rvrickv
37 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvrickv/Arduino-Garage/7ad4ce1c6bad06ad1f63b194e5100ddd98a2ddfc/TODO.txt
--------------------------------------------------------------------------------
/src/Arduino Garage.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "FastLED.h"
6 | #include "NewPing.h"
7 |
8 | //#include "QuickStats.h" // Used to calculate the mode if using Mode sampling. Slow, even on 8266 at 160 MHz.
9 |
10 | #define DATA_PIN D3 // Data pin for FastLED LED control
11 | #define TRIGGER D5 // Pin used to trigger HC-SR04
12 | #define ECHO D0 // Pin that receives unltrasound ping
13 | #define LED_TYPE NEOPIXEL // Type of LED pixels for FastLED
14 | #define NUM_LEDS 16 // Number of LEDs being used
15 | #define BRIGHTNESS 180 // How brignt will LESs appear.
16 | #define PARKING_DISTANCE 100 // Default parking distance
17 | #define MAX_DISTANCE 350 // Sensor is less precise at longer distances
18 | #define RESET_DISTANCE 5 // Distance that will trigger parking distance setting
19 | #define SAMPLE_READINGS 5 // Number of readings to increase precision
20 | #define TIME_TO_OFF 10000 // How long before LEDs go off
21 |
22 | CRGB leds[NUM_LEDS];
23 | elapsedMillis timeElapsed;
24 | //QuickStats stats;
25 |
26 | bool parked = false;
27 | NewPing sensor(TRIGGER, ECHO, MAX_DISTANCE);
28 |
29 | uint16_t parking_distance = PARKING_DISTANCE;
30 | float readings[SAMPLE_READINGS];
31 |
32 | void setup() {
33 | // Small delay to let eveerything get started
34 | delay(1000);
35 |
36 | FastLED.addLeds(leds, NUM_LEDS);
37 | FastLED.setBrightness(BRIGHTNESS);
38 | EEPROM.begin(2);
39 | Serial.begin(9600);
40 | Serial.println("Started");
41 | led_off();
42 |
43 | // Check to see if we have parking data in the eeprom
44 | uint16_t ee_distance = 0;
45 |
46 | // Query the parking distance from flash. If not 0, set
47 | // parking_distance to stored value.
48 | EEPROM.get(0,ee_distance);
49 | if (ee_distance){ parking_distance = ee_distance; Serial.println(parking_distance);}
50 | }
51 |
52 |
53 | void loop() {
54 |
55 | uint16_t distance = 0;
56 |
57 | // Mode sampling technique - slower but reduces outliers
58 | // Take n readings, store them in the array
59 | //for (int i=0; i 0 && distance <=RESET_DISTANCE)
92 | {
93 | parking_distance = reset_parking_distance();
94 | //Serial.print("New Parking distance is: ");
95 | //Serial.println(parking_distance);
96 | }
97 | }
98 | else if (distance <= parking_distance)
99 | {
100 | if ((!parked) || (timeElapsed < TIME_TO_OFF)){
101 | led_stop();
102 | parked = true;
103 | }
104 | else if(parked && (timeElapsed >= TIME_TO_OFF) && leds[0].getLuma())
105 | {
106 | led_fade_off(); //If lEDs are on after being parked for a few secs turn off
107 | }
108 | }
109 | else if (distance <= MAX_DISTANCE){
110 | led_show_value(distance);
111 | parked = false;
112 | timeElapsed = 0;
113 | }
114 | delay(10);
115 | }
116 |
117 | uint16_t reset_parking_distance(){
118 |
119 | led_countdown();
120 | uint16_t new_distance = round_to_base(sensor.convert_cm(sensor.ping_median(25)));
121 | new_distance += 5; // a little buffer to ensure we're "Red"
122 | timeElapsed = 0;
123 |
124 | EEPROM.put(0,new_distance); // write the new distance to Flash
125 | EEPROM.commit();
126 |
127 | return (new_distance);
128 | }
129 |
130 | uint16_t round_to_base(uint16_t value)
131 | {
132 | uint16_t base = 5;
133 | return uint16_t(base * round(float(value)/base));
134 | }
135 |
--------------------------------------------------------------------------------
/src/ledring.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void led_stop(){
4 | //FastLED.showColor(CRGB::Red);
5 | fill_solid(&leds[0], 16,CRGB::Red);
6 | FastLED.show();
7 | }
8 |
9 | void led_off(){
10 | //FastLED.showColor(CRGB::Black);
11 | fill_solid(&leds[0], 16,CRGB::Black);
12 | FastLED.show();
13 | }
14 |
15 | void led_show_value(uint16_t value){
16 | uint8_t no_of_leds = map(value,parking_distance,MAX_DISTANCE,16,0);
17 |
18 | for (uint8_t led = 0; led<=no_of_leds; led++){leds[led] = CRGB::Green;}
19 | for (uint8_t led = NUM_LEDS - 1; led > no_of_leds; led--){leds[led] = CRGB::Black;}
20 |
21 | FastLED.show();
22 | }
23 |
24 | void led_enter_setup()
25 | {
26 | // Blink 3 times
27 | for (int hue = 90; hue<255; hue++){
28 | fill_rainbow( leds, NUM_LEDS, hue, 5);
29 | FastLED.show();
30 | delay(20);
31 | }
32 | }
33 |
34 | void led_countdown()
35 | {
36 | fill_rainbow( leds, NUM_LEDS, 255, 5);
37 | FastLED.show();
38 | delay(300);
39 |
40 | for (int i = NUM_LEDS-1; i>=0; i--)
41 | {
42 | leds[i] = CRGB::Black;
43 | FastLED.show();
44 | delay(300);
45 | }
46 | }
47 |
48 | void led_fade_off(){
49 | for (int i = 0; i < 255; i++){
50 | for (int j = 0 ; j < NUM_LEDS; j++){leds[j].fadeToBlackBy(20);}
51 | FastLED.show();
52 | if (!leds[0].getLuma()){
53 | led_off();
54 | break;}
55 | FastLED.delay(30);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------