Garage sensor–Version 1 summary

image

Video link = https://www.youtube.com/watch?v=MBYtc1O-l94

I’ve rounded off version 1 of the Garage sensor and am about to start work on version 2. There is a short video summary of what he sensor does in the video above.

I’m not happy with the daughter board that runs the 5 LEDs. It is cumbersome, challenging and time consuming to build. I plan to replace this with something pre-built. I’ll also opt for a cheaper Arduino board. The process will also require me to rework the 3D printed board all the components are mounted on.

Stay tuned for Version 2 coming soon!

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

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.

Robot with distance

As I detailed in a previous post:

Mecanum motion

I had my robot moving and taking commands from an Internet based dashboard. The missing piece was to get the distance sensor operational, which I have now achieved.

I firstly need to print a mount to allow the distance sensor to be mounted to the buggy frame. I have uploaded that to the CIAOPSLabs repo here:

https://github.com/directorcia/ciaopslabs/blob/main/3dprint/mounts/VL53L0X-distance.stl

image

With the VL53L0X sensor now mounted and connected to the processor the layout now looked like the above image.

Basically, the motor controller, distance sensor and LCD display all communicate with the ESP32-S2 processor via the SDA/SCL bus. They achieve this by all being on a different address.

It was also important to ensure that I connected up the wheel in a know sequence because to drive the mecanum motion I needed to turn different wheels to make it move in certain directions per:

I’ve uploaded the initial code with it all working here:

https://github.com/directorcia/ciaopslabs/blob/main/Projects/14/moveanddistance-v1.c

The commands on the keyboard are:

image

1 = Left forward 45

2 = Forward

3 = Right forward 45

4 = Left 90

5 = Stop/Start

6 = Right 90

7 = Left back 45

8 = Back

9 = Right back 45

* = Slower

0 = Spin on the spot

# = Faster

As the robot moves it displays the distance on the LCD display like so:

image

The robot starts with speed = 0 (i.e. stationery). You press 5 to set the speed to 100 but it will not yet move until you give it a direction. If you now press 2, the robot will move forward at a speed of 100. You can then happy go along changing directions via the keypad. If you press 5 again, the robot will stop moving.

With all this now working, the next update will be for the robot to use the distance sensor to determine how far away it is from object (at the front), slow and stop if necessary to avoid hitting these objects.

I want to also optimise the code to make it more responsive if I can and I’ll post the updates here and to the CIAOPSLabs repo when I get it all working.

Beyond that I’m still trying to decide what to get the robot to do? If you have any suggestions, let me know but I’m kind of thinking that the robot needs to have ‘vision’ next!