![]()
This is a follow on post to my:
and
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 zone
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.
