Testing out different sensor for pellet level monitoring

I tested the VL53L0x sensor to see how it works and if it makes a better choice for pellet level monitoring in my pellet boiler at home.
Apr 26, 2024 — 5 mins read — Home Assistant

Testing out different sensor for pellet level monitoring

When I made my initial version of the pellet level monitor for my pellet boiler, many of the comments that I got on the article and the video suggested that I use a VL53L0x, Time Of Flight sensor as supposedly it is a much more reliable and precise than the ultrasonic sensor that I used previously.

To see how the sensor works, I ordered it and in the video below, you can see me recreating the same device, but now we will be using light instead of sound to measure distances.



The video is sponsored by Altium Designer and Altium 365. You can get 25% discount on any new license by using this link: https://www.altium.com/yt/taste_the_code


Overview of the VL53L0X Time of Flight Sensor

The VL53L0X sensor is a laser-based distance measuring sensor, or a so-called Time Of Flight sensor. It uses an infrared laser to shine a light onto the object in front and then measures the reflection using an IR receiver to figure out the time difference between the sent and bounced light.

Since the speed of light is constant, the sensor then calculates the distance based on the time it took the light to travel to the object that we measured and back.


Materials and Tools Needed

The star of the project is the VL53L0x sensor, but we also need a few other components as well. Below are some affiliate links that you can check out and if you purchase through them, you are supporting my work and the channel at no extra cost to you! Any help is much appreciated!


Connecting the VL53L0X Sensor to a Microcontroller

The VL53L0x sensor uses I2C communication so other than power, we only need two wires to connect it to a microcontroller. The NodeMCU that we are using, uses pins D1 and D2 as defaults for I2C so we will connect D1 to SCL and D2 to SDA pins on the sensor.

For power, I connected the VCC of the sensor to the 3.3V output on the NodeMCU and GND to GND on both.


Programming the VL53L0X Sensor with Arduino

As a first step in making sure that the sensor works, I used the Arduino IDE where I installed the Adafruit library for the VL53L0x sensor.

The library provides an example sketch so I uploaded that and was immediately greeted with the measured distance in millimeters in the Arduino serial console.

The full sketch code is below.

#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  Serial.begin(115200);

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }
  
  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power 
  Serial.println(F("VL53L0X API Simple Ranging example\n\n")); 
}


void loop() {
  VL53L0X_RangingMeasurementData_t measure;
    
  Serial.print("Reading a measurement... ");
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }
    
  delay(100);
}


Integrating VL53L0X with ESPHome

Now that we had the sensor working, it was time to move to use it with ESPHome and luckily, there is already a pre-built component for it. The only requirement is to include the I2C bus component so that communication can be established.

There is no change in the wiring from before so I left it as is from the Arduino version.

i2c:
  sda: D2
  scl: D1
  scan: true
  id: bus_a  

sensor:
  - platform: vl53l0x
    id: distance_sensor
    name: "VL53L0x Distance"
    address: 0x29
    update_interval: 1s
    long_range: false

  - platform: template
    id: level
    name: Pellet Level TOF
    unit_of_measurement: '%'
    update_interval: 1s
    lambda: |-
      if (isnan(id(distance_sensor).state)) return 0;
      auto r = (id(distance_sensor).state - 0.8) * (100.0 - 0.0) / (0.1 - 0.8) + 0.0;
      if (r > 100) return 100;
      if (r < 0) return 0;
      return r;


To display the output in a nice card with a needle chart, I used the following code to generate it in the dashboard.

type: gauge
entity: sensor.pellet_level_tof_pellet_level_tof
name: Pellet Level TOF
min: 0
max: 100
needle: true
severity:
 green: 30
 yellow: 15
 red: 0


Future Enhancements and Standalone Version Development

As a next step in developing the sensor, I will add the VL53L0x to the same device with the ultrasonic sensor so I can at least for a while monitor the output of the two sensors in parallel on the same level and compare the values.

Additionally, when people first saw the pellet level monitor, they also asked for a standalone version that they can use at home even if they do not have a Home Assistant setup so I plan to work on that.

If that is something that might be interesting for you or if you want to see some other projects, feel free to subscribe to my YouTube channel to follow my journey.

pellet arduino esphome project test
Read next

Arduino Emergency Caller Prototype with NodeMCU and Crowtail-4G SIM A7670E

A few weeks ago, Elecrow reached out to me to see if I'm interested in creating a project with their Crowtail-4G SIM A7670E Module and since...

You might also enojy this

Making a Pellet Level Monitor with HC-SR04 and ESP8266

To heat my home, I use wood pellets and a big pellet boiler, that I need to top up every few days. This is usually not an issue but sometime...