Garage Sensor–Code

image

This is a follow on post to my:

Garage Sensor overview

and

Garage Sensor – Genesis

What I want to do here is spend some time looking at the code, which can be found here:

https://github.com/directorcia/Azure/blob/master/Iot/Arduino%20Uno%20R3/Garage%20distance/main.cpp

First steps are to have the include statements, which are:

#include <Wire.h>
#include “SparkFun_Alphanumeric_Display.h”
#include <VL53L1X.h>
#define DISPLAY_ADDRESS 0x70

I then need to create an instance of both the display and distance sensor, which is done via:

HT16K33 display;
VL53L1X sensor;

by default, the display will be at address 0x70 and the distance sensor will be 0x29 for I2C communications.

Next, I define some constants:

const uint16_t POT_PIN = A0;             // Analog pin for potentiometer
const uint16_t mid_point = 1380;         // Optimal distance from wall
const uint16_t adjust = 334;             // potentiometer midpoint value;
const uint16_t average_number = 10;      // Number for averaging distance readings

The pot to allow distance trimming will be at analog port 0. I define the mid point of this pot. Anything past the middle will extend (i.e. add) the optimal distance and anything below will subtract from my optimal distance. I found the total value range (i.e. low and high) of the pot simply by measuring the input from the pot in different positions directly from the analog port.

I define my optimal distance from the wall. Here, 1380 mm.

I define the number of repetition I want to use and then average my readings across as 10 here.

int potvalue;
int SWITCH_PIN = 8;                 // Debug Switch pin
int LED_UNDER_RED = 3;              // LED pin for under red
int LED_UNDER_YELLOW = 4;           // LED pin for under yellow
int LED_WHITE = 5;                  // LED pin for white
int LED_OVER_YELLOW = 6;            // LED pin for over yellow
int LED_OVER_RED = 7;               // LED pin for over red

Next I define a variable for my pot and the digital pins on which each LED is connected.

// Initialize I2C communication
Wire.begin();


// Initialize the display
if (display.begin(DISPLAY_ADDRESS) == false) {
   Serial.begin(9600);
   Serial.println(“Display not found. Check wiring.”);
   while (1);
}


// Initialize the VL53L1X sensor
sensor.setTimeout(500);
if (!sensor.init()) {
   Serial.begin(9600);
   Serial.println(“Failed to detect and initialize sensor!”);
   while (1);
}
sensor.startContinuous(50);
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(100);


// Clear the display
display.clear();
display.write(“Boot”);

In my setup look I start I2C communications, initialise the LED display along with the distance sensor.

// pinmodes
pinMode(SWITCH_PIN, INPUT_PULLUP);
pinMode(POT_PIN, INPUT);
pinMode(LED_UNDER_RED, OUTPUT);
pinMode(LED_UNDER_YELLOW, OUTPUT);
pinMode(LED_WHITE, OUTPUT);
pinMode(LED_OVER_YELLOW, OUTPUT);
pinMode(LED_OVER_RED, OUTPUT);
delay(100);
digitalWrite(LED_UNDER_RED, HIGH);
delay(100);
digitalWrite(LED_UNDER_YELLOW, HIGH);
delay(100);
digitalWrite(LED_WHITE, HIGH);
delay(100);
digitalWrite(LED_OVER_YELLOW, HIGH);
delay(100);
digitalWrite(LED_OVER_RED, HIGH);
delay(100);

I define my pin modes for the LEDS and set them all to high so I know they work on each boot.

// average pot readings
unint16_t sum = 0;
for (int i = 0; i < average_number; i++) {
   sum += analogRead(POT_PIN);
   delay(2);
}

I then take a number of analog readings from the location of the pot and average them to come to a single value to be used to adjust the optimal distance.

In my loop

// average distance readings
uint16_t sum = 0;
for (int i = 0; i < average_number; i++) {
     sum += sensor.read();
     delay(2);
}
uint16_t stableDistance = sum / average_number;

I firstly get an average distance from my sensor.

uint16_t midvalue = mid_point + potvalue – adjust;      // Adjusted midpoint value
uint16_t under_red = 0.8 * midvalue;                    // Under red zone
uint16_t under_yellow = 0.96 * midvalue;                // Under yellow zone
uint16_t over_yellow = 1.04 * midvalue;                 // Over yellow zone
uint16_t over_red = 1.2 * midvalue;                     // Over red zon
e

I use this average distance, less any adjustment via the pot to set the distance zones for each LED.

int reading = digitalRead(SWITCH_PIN);

I then see if the debug switch has been set.

if (reading == LOW) { // if Debug mode
     int adjustvalue;
    
     // average pot readings
     uint16_t sum = 0;
     for (int i = 0; i < average_number; i++) {
         sum += analogRead(POT_PIN);
         delay(2);
     }
     potvalue = sum / average_number;


    // Turn on all LEDs
     digitalWrite(LED_UNDER_RED, HIGH);
     digitalWrite(LED_UNDER_YELLOW, HIGH);
     digitalWrite(LED_WHITE, HIGH);
     digitalWrite(LED_OVER_YELLOW, HIGH);
     digitalWrite(LED_OVER_RED, HIGH);
     delay(100);


    // Display the pot value          
     snprintf(buffer, sizeof(buffer), “%4d”, (potvalue – adjust));
     display.write(buffer);

If it has then I turn on all the LEDs and display the pot value on the display. The idea is that in debug mode you adjust the pot to set any desired offset in distance for your unique circumstance.

If the debug switch isn’t on then I display the current distance on the 4 digit LED display and turn teh appropriate LED on the and the others off. I manage that in a case statement.

Thus, I keep looping through reporting distance from teh sensor to the 4 digit LED display and setting the proximity LEDs unless the debug switch is on. If the switch switch is set, then I display the pot setting so that it can be adjusted.

The idea is you power up the unit in debug mode, ensure all LEDs are working and adjust the pot to setting to create an offset from the define optimal of 1380mm. You then turn off debug mode and the 4 digit LED display will show the distance from the wall in mm and the proximity LEDs will display based on the range from the wall.

Garage Distance Sensor–genesis

image

In a previous post I provided an initial overview of my Garage distance sensor.

The aim of the project is to provide a way to report the distance of a vehicle as it parks in a garage. It does this by sensing and showing the distance from a wall in the garage.

Initially, I was simply going to display a distance reading in millimetres, but the I thought that this may be confusing and at times hard to read if you were sitting inside the vehicle trying to park.

I settled on 4 digit LED display Sparkfun Qwiic Alphanumeric Display – pink because it was already pre-wired, relatively large digits and easy to read from a distance. Would I have liked larger digits? Sure, but for now, in test mode, these are more than adequate.

I also added a set of 5 LEDs to act as distance indicators. They are:

Red – Large away distance

Yellow – Medium away distance

White – Paring zone distance

Yellow – Medium close distance

Red – Large close distance

The driver is ultimately aiming to be in the white LED zone when parking. Anything else let’s them know, too far or too close. The idea with these LEDs on top of the distance display is that it is easier for the driver to see a single LED colour rather than having to read and then comprehend a distance in millimetres. If you are worried about parking you car, the less you have to worry about the better I believe.

To actually measure and report the distance I opted for a Adafruit VL53L1X Time of Flight Distance Sensor because its range is from 30 to 4000mm and it uses a Qwiic connector, which means less soldering. Given that I have already built projects with the VL53L0X sensor (30 – 1000mm):

Displaying distance on LCD screen

I would be able to reuse a lot of knowledge and code. The VL53L1X will give me out to four metres, which is right on song for something in a garage.

I decided to use an original Arduino Uno R3 controller for this project as well to gain some experience with the board. There are certainly more powerful and featured controllers, but it is more than adequate for this project.

As I developed the project I realised that I would need to work out the required distance manually and then code that in to the controller. This would mean that any adjustment of that parameter would mean updating the controller. Thus, I added a potentiometer that could used to make slight distance adjustments if required. That is, using the potentiometer, you can make the optimal distance either closer or further away. This means the distance can be adjusted without reprogramming.

To make this adjustment in distance if required, I added a simple switch to put the things into a ‘debug mode’. When the switch is ‘active’ you can use the potentiometer to adjust the sensor optimal distance offset. This offset is then detected when the unit returns to ‘normal mode’, and added (or subtracted) from teh coded optimal distance. Also, while in ‘debug mode’ all the LEDs will light so you know they are all operating.

The idea is then that you mount the garage distance sensor on a wall. When the the sensor detects the car it will display a distance in millimetres as well as display the appropriate LED based on the distance. The coded optimal distance value can be adjusted via an offset that is configured in ‘debug mode’ when the switch is set.

Hopefully, that gives you a better idea of what I was trying to achieve with my Garage distance sensor. In upcoming articles, I’ll break down each component and how I built it.

Garage distance sensor

20250316_040957232_iOS

My latest project is creating a garage distance sesnor. The idea is that as you drive yoru car into the garage it will tell the distnace to the wall, so you can get the alignment just right. It does this in two ways, firstly via an LED display of the distance in mm from the and secondly from a Christmas tree style set of lights to give you a visual idea of whether you are in the zone.

Screenshot 2025-03-17 212404

The rough circuit diagram is shown above.

For this project I’m using at:

Adafruit VL53L1X Time of Flight Distance Sensor – ~30 to 4000mm – STEMMA QT / Qwiic

SparkFun Qwiic Alphanumeric Display – Pink

Breadboard Compatible Potentiometer (10k Ohm)

Arduino Uno R3

some resistors, LEDs and a switch.

The code is here:

https://github.com/directorcia/Azure/blob/master/Iot/Arduino%20Uno%20R3/Garage%20distance/main.cpp

and now that I have it working, at least in beta, I’ll detail a bit more about the development process so far and what I’d like to ultimately achieve in upcoming posts, so stay tuned.