Add to cart
Board Type : GerberFile :
Layer : Dimensions :
PCB Qty :
Different PCB Design
PCB Thickness : PCB Color :
Surface Finish : Castellated Hole :
Copper Weight : 1 oz Production Time :
Total: US $
Elecrow community is a shared platform and we are not responsible for any design issues.

PCB Assembly

PCBA Qty: BomFile:
NO. OF UNIQUE PARTS: NO. of Components:
Assembly Cost: US $
Elecrow community is a shared platform and we are not responsible for any design issues.
Add to cart
3dPrintingFile : Size :
Unit : Volumn :
3D Printing Qty : Material :
Total: US $12.99
Elecrow community is a shared platform and we are not responsible for any design issues.
Add to cart
Acrylic Type : AcrylicFile :
Dimensions: Engrave:
Acrylic Qty :
Acrylic Thickness:
Acrylic Color:
Total: US $12.99
Elecrow community is a shared platform and we are not responsible for any design issues.
Add to cart
CNC Milling File : Size:
Unit: Volumn:
CNC Milling Qty : Material:
Type of Aluminum: Surface Finish:
Tolerance:
Surface Roughness:
Total: US $12.99
Elecrow community is a shared platform and we are not responsible for any design issues.
closed
user-img

Stefan Maetschke

Published: Oct 05,2024

Parking sensor with CrowPanel ESP32 Display

Build a Parking Sensor with the TOF10120 IR Laser Distance Sensor and a CrowPanel 3.5" ESP32 Display. A parking sensor helps you to avoid obstacles while parking, for instance, by measuring the distance between your car and the garage wall. This Parking Sensor accurately measures the remaining distance and shows it in big, color-coded digits. It furthermore features a set button that allows you to set the warning distance.

ccc ccc
Copyright Info

Attribution-ShareAlike (CC BY-SA)

Read More⇒
  219
  2
  0
cover-img
 
  • thumbnail-img
  • thumbnail-img
  • thumbnail-img
  • thumbnail-img
 

Hardware Components

  • CrowPanel 3.5" ESP32 Display

    Elecrow
    X 1 fenxiang
  • TOF10120 Laser Range Sensor

    X 1 fenxiang

Story

In this tutorial you will learn how to build a Parking Sensor with the TOF10120 IR Laser Distance Sensor and a CrowPanel 3.5" ESP32 Display. A parking sensor helps drivers avoid obstacles while parking, for instance, by measuring the distance between the car and the garage wall.

The short video clip below demonstrates the parking sensor. It shows how distances are measured in centimetres, and how to set the distance for the proximity alarm (red color):

Demo Parking Sensor on CrowPanel Display with TOF10120

The TOF10120 sensor uses time-of-flight technology. It emits an infrared laser beam and measures how long it takes for the beam to return after hitting an object. This time is converted into a distance.

The ESP32 microcontroller within CrowPanel Display then processes the data from the TOF10120 sensor. It calculates the distance and prepares the information for display.

Finally, the CrowPanel TFT display shows the distance in real-time. It provides the visual output, allowing the driver to see how far they are from obstacles.

In the next view sections you will learn how to connect the TOF10120 sensor to the CrowPanel Display and how to program it to display distance information. Let's start with the required parts

Features of the CrowPanel 3.5" ESP32 Display

The CrowPanel 3.5" ESP32 Display is a resistive touch screen with a 480*320 resolution TFT display and a built-in ESP32-WROVER-B as control processor. You can get the display with an acrylic shell (see picture below), which means you don't have build a housing yourself.

CrowPanel 3.5" ESP32 Display with Housing
CrowPanel 3.5" ESP32 Display with Housing (source)

Beyond that, the board comes with a TF card slot, an UART interface, an I2C interface, a speaker interface, a battery connector with charging capability and a small GPIO port with two GPIO pins. See the pinout below:

Pinout of CrowPanel 3.5" ESP32 Display
Pinout of CrowPanel 3.5" ESP32 Display

The following table lists which GPIO pins are assigned to which of the three IO interfaces.

GPIO_D IO25; IO32
UART RX(IO16); TX(IO17)
I2C SDA(IO22); SCL(IO21)

The board can be powered via the USB port (5V, 2A) or by connecting a standard 3.7V LiPo battery to the BAT connector. Just watch out for the polarity of the connector and the battery. If the USB cable and the battery are connected at the same time, the board will charge the battery (maximum charging current is 500mA).

You can program the board using various development environments such as Arduino IDE, Espressif IDF, Lua RTOS, and Micro Python, and it is compatible with the LVGL graphics library. However, in this tutorial we will use the Arduino IDE and the TFT_eSPI graphics library.

Features of the TOF10120

The TOF10120 Time-of-Flight Distance Sensor is a is a very small (10mm x 13mm), high-precision sensor that uses infrared light to measure distances.

Dimensions of TOF10120
Dimensions of TOF10120 (source)

It is based on the Time-of-Flight (ToF) principle, where the sensor emits light pulses and measures the time it takes for the light to reflect back to calculate the distance. The TOF10120 has a range of up to 180 cm and operates at a wavelength of 940nm. The picture below shows the cone of the laser LED that emits the light pulse and the view cone of the detector that registers the reflected light.

Working Principle of TOF10120
Working Principle of TOF10120 (source)

The TOF10120 operates on 3V to 5V, with a low, average current consumption of only 35 mA. The following list summarizes its main features:

- Working range: 100-1800mm
- Measurement error: up to 5%
- High speed ranging: max 30ms
- Communication interface: UART / I2C
- UART transmission parameters: 9600 8n1
- Wavelength: 940 nm
- Field of view: 25°
- Ambient light immunity: 50k lux
- Voltage range: 3V to 5V
- Average current consumption: 35 mA

The above specification and the datasheet state that the minimum distance that can be measured is 100mm. However, I found that you actually can get measurements as close as 10mm and as far as 2000mm but under 30mm the readings become very inaccurate.

The TOF10120 communicates with microcontrollers via an I2C or UART interface. The picture below shows the pinout. SDA and SCL are for the I2C interface and RxD and TxD for UART communication.

Pinout of TOF10120
Pinout of TOF10120

In the next section you will learn how to connect the TOF10120 to the CrowPanel Display.

Connecting TOF10120 to the CrowPanel Display

The CrowPanel Display has an I2C port and comes with a color coded connector. Ground is black, 3.3V power supply is red, SCL is white (gray) and SDA is yellow. Connect Ground to pin 1, 3.3V to pin 2, SDA to pin 5 and SCL to pin 6 of the TOF10120 as shown below:

Connecting TOF10120 to CrowPanel Display
Connecting TOF10120 to CrowPanel Display

Note that pin 3 and 4 (RxD, TxD) of the TOF10120 are not connected, since we are not using the UART interface but I2C.

The picture below shows the, admittedly messy, wiring of the TOF10120 with CrowPanel using the provided connectors and some Dupont cables.

Wiring of TOF10120 with CrowPanel
Wiring of TOF10120 with CrowPanel

The good news is, you don't need a breadboard or have to solder any wires.

Testing the TOF10120 Sensor

Before implementing anything complex, we better test that the sensor is correctly connected and works. For that, we first need to install a library to read distance measurements from the TOF10120 sensor.

Install TOF10120 library

To install the TOF10120 library go to the tof10120_arduino_lib repo here and click on the green "Code" button. Then click on "Download Zip" as show below:

Download TOF10120 library
Download TOF10120 library

In the Arduino IDE create the following test code:

#include "TOF10120.h"

TOF10120 sensor = TOF10120();

void setup() {
  Serial.begin(9600);
  sensor.init();
}

void loop() {
  Serial.print("distance:");
  Serial.println(sensor.distance());
  delay(100);
}

Then go "Sketch" -> "Include Library" -> "Add .Zip Library.." and select the "tof10120_arduino_lib-main.zip" file you just downloaded before:

Adding TOF10120 library to sketch
Adding TOF10120 library to sketch

The test code is very simple. First it includes the TOF10120 library and creates the TOF10120 sensor object. In the setup() function the sensor then gets initialized and in the loop() function we finally call sensor.distance() to read the distance measured by the sensor.

Run test code for TOF10120 Sensor

In the Arduino IDE select "ESP32 Dev Module" as board and make sure the CrowPanel Display is connected to the USB port and visible in the Arduino IDE.

ESP32 Dev Module selected as board
ESP32 Dev Module selected as board

Now upload the code to your CrowPanel Display and you should see distance values printed to the Serial Monitor. If there is no object in front of the sensor, you will see a distance of 2000mm printed and if the sensor was not found you will see a -1.

Distances printed on Serial Monitor
Distances printed on Serial Monitor

If you have issues and the sensor doesn't seem to work make sure that the wiring is correct and that the correct SDA and SCL pins are used. You can also check the laser diode of the sensor by taking a picture with a digital camera (mobile phone). While IR light is invisible to the human eye, the camera can see it. The picture below shows the TOF10120 with the IR diode clearly illuminated:

Illuminated IR Diode of TOF10120
Illuminated IR Diode of TOF10120

If the TOF10120 sensor works and you see distance measurements displayed, we can start with the project structure for the main code.

Create Project Structure

In this section we create the project structure and the setup for the TFT_eSPI library that is needed to control the TFT display.

Open your Arduino IDE and create a project "parking_sensor_display" and save it (Save As ...). This will create a folder "parking_sensor_display" with the file "parking_sensor_display.ino" in it. In this folder create another file named "tft_setup.h". Your project folder should look like this

Project Folder Structure
Project Folder Structure

and in your Arduino IDE you should now have two tabs named "parking_sensor_display.ino", and "tft_setup.h".

Arduino IDE with two Tabs
Arduino IDE with two Tabs

Click on the "tft_setup.h" tab to open the file and copy the following code into it:

// tft_setup.h
#define ILI9488_DRIVER
#define TFT_HEIGHT  480
#define TFT_WIDTH   320 

#define TFT_BACKLIGHT_ON HIGH
#define TFT_BL   27 
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15
#define TFT_DC    2 
#define TFT_RST  -1
#define TOUCH_CS 33

#define SPI_FREQUENCY        27000000
#define SPI_TOUCH_FREQUENCY   2500000
#define SPI_READ_FREQUENCY   16000000

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

This code tells the TFT_eSPI library, which display are we using. Specifically, we let the library know the dimensions of the display (TFT_WIDTH, TFT_WIDTH), its display driver (ILI9488_DRIVER), which SPI pins are used to control it and what fonts to load. Without these settings, you will not be able to show anything on the display.

For more detailed information have a look at the tutorial CrowPanel 2.8" ESP32 Display : Easy Setup Guide. There we explain how to setup the 2.8" Display. But the steps and descriptions apply to the 3.5" Display in the same way. Just the settings for the screen dimensions and driver are different.

Calibrating Touchscreen

The CrowPanel 3.5" Display comes with a resistive touch screen that you need to calibrate first, before you can used it with the TFT_eSPI library. Copy the code below into the "parking_sensor_display.ino" file, compile it and upload it to the CrowPanel 3.5" Display. As before, use the ESP32 Dev Module as board.

#include "tft_setup.h"
#include "TFT_eSPI.h"

TFT_eSPI tft = TFT_eSPI();

void setup() {
  Serial.begin(9600);
  tft.begin();
  tft.setRotation(3);
}

void loop() {
  uint16_t cal[5];
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(20, 0);
  tft.setTextFont(2);
  tft.setTextSize(1);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.print("Touch corners ... ");
  tft.calibrateTouch(cal, TFT_MAGENTA, TFT_BLACK, 15);
  tft.println("done.");

  Serial.printf("cal: {%d, %d, %d, %d, %d}\n",
                cal[0], cal[1], cal[2], cal[3], cal[4]);
  delay(10000);
}

When the code is running the displays shows an arrow and tells you to touch the corner it points to. This will be repeated for the other three corners as well. Use the little yellow pen that comes with Display to do this and try to touch the corners as precisely as possible.

Calibration of touch screen
Calibration of touch screen

At the end of the calibration process the code prints out the 5 calibration parameters (corner coordinates and screen orientation) to the Serial monitor. You should see something like this:

cal: { 273, 3534, 286, 3615, 4 }

Copy the parameters somewhere, since you will need them in the main code. The calibration repeats itself every 10 seconds, so you can have several tries to get the most accurate parameters. For more detailed information on the calibration process have a look the CrowPanel 2.8" ESP32 Display : Easy Setup Guide tutorial.

Code for Parking Sensor

In this section, we write the main code for the parking sensor system using the CrowPanel ESP32 display and the TOF10120 laser distance sensor. The system continuously measures the distance to an object and displays it on the screen, changing colors based on the proximity of the object. A button on the display allows the user to set a minimum distance threshold.

The following screenshot shows the main elements of the user interface:

User Interface for Parking Sensor
User Interface for Parking Sensor

Have quick look at the complete code first, and then we dive into its details:

#include "stdarg.h"
#include "tft_setup.h"
#include "TFT_eSPI.h"
#include "TOF10120.h"

TFT_eSPI tft = TFT_eSPI();
TOF10120 sensor = TOF10120();

uint16_t cal[5] = { 273, 3534, 286, 3615, 4 };
int minDist = 50;


int getDistance() {
  return sensor.distance() / 10;
}

void drawString(int16_t x, int16_t y, uint8_t font, const char* format, ...) {
  static char buf[64];
  va_list args;
  va_start(args, format);
  vsnprintf(buf, 64, format, args);
  tft.setTextDatum(MC_DATUM);
  tft.drawString(buf, x, y, font);
}

void drawDistance() {
  static char buf[32];
  int dist = getDistance();
  uint32_t color = TFT_GREEN;
  if (dist < minDist * 1.5) color = TFT_YELLOW;
  if (dist < minDist) color = TFT_RED;
  tft.setTextColor(color, TFT_BLACK);
  tft.setTextSize(3);
  drawString(tft.width() / 2, 120, 7, "   %d   ", dist);
}

void drawButton() {
  static bool oldTouch = true;
  int cx = tft.width() / 2;
  int bw = 140, bh = 50, bt = 3;
  int x = cx - bw / 2, y = tft.height() - bh - 10;

  uint16_t tx, ty;
  bool isTouch = tft.getTouch(&tx, &ty);
  isTouch = isTouch && (abs(tx - cx) < bw / 2) && (ty > y);
  if (isTouch == oldTouch) return;
  oldTouch = isTouch;

  tft.fillSmoothRoundRect(x, y, bw, bh, 10, TFT_WHITE);
  if (isTouch) {
    tft.setTextColor(TFT_BLACK, TFT_WHITE, true);
    minDist = getDistance();
  } else {
    tft.fillSmoothRoundRect(x + bt, y + bt, bw - 2 * bt, bh - 2 * bt, 10, TFT_BLACK);
    tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  }
  drawString(cx, y + bh / 2, 1, "set");
  tft.setTextColor(TFT_SILVER, TFT_BLACK, true);
  drawString(cx, y - 30, 1, "  %d  ", minDist);
}

void setup(void) {
  sensor.init();
  tft.init();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
}

void loop() {
  drawDistance();
  drawButton();
  delay(100);
}

Let's break down the code into its components for a better understanding.

Library Inclusions

We start by including the necessary libraries for our project. These libraries provide the functionality needed to interact with the display and the distance sensor.

#include "stdarg.h"
#include "tft_setup.h"
#include "TFT_eSPI.h"
#include "TOF10120.h"

 

Object Initialization

Next, we create instances of the display and the sensor. The TFT_eSPI object tft is used to control the display, while the TOF10120 object sensor is used to interact with the laser distance sensor.

TFT_eSPI tft = TFT_eSPI();
TOF10120 sensor = TOF10120();

 

Calibration and Minimum Distance

We define an array cal for calibration values and an integer minDist that sets the minimum distance threshold for the sensor. This threshold will be used to change the color of the displayed distance based on how close an object is. The calibration values come from the touch screen calibration process described before.

uint16_t cal[5] = { 273, 3534, 286, 3615, 4 };
int minDist = 50;

Get Distance Function

The getDistance() function retrieves the distance measured by the sensor and converts it from millimeters to centimeters by dividing it by 10.

int getDistance() {
  return sensor.distance() / 10;
}

 

Draw String Function

The drawString() function is a utility to display formatted text on the screen. It uses variable arguments to format the string and then draws it centred at specified coordinates with a specified font.

void drawString(int16_t x, int16_t y, uint8_t font, const char* format, ...) {
  static char buf[64];
  va_list args;
  va_start(args, format);
  vsnprintf(buf, 64, format, args);
  tft.setTextDatum(MC_DATUM);
  tft.drawString(buf, x, y, font);
}

 

Draw Distance Function

In the drawDistance() function, we first get the current distance using getDistance(). We then determine the color of the text based on the distance: green for safe distances, yellow for caution, and red for danger.

void drawDistance() {
  static char buf[32];
  int dist = getDistance();

  uint32_t color = TFT_GREEN;
  if (dist < minDist * 1.5) color = TFT_YELLOW;
  if (dist < minDist) color = TFT_RED;

  tft.setTextColor(color, TFT_BLACK);
  tft.setTextSize(3);
  drawString(tft.width() / 2, 120, 7, "   %d   ", dist);
}

Finally, we display the distance in a large font on the screen. The following three screen shots show three distances (in centimetre) in the three different colors:

Screen shots of Display
Screen shots of Display

 

Draw Button Function

The drawButton() function handles the display of a button on the screen. It checks for touch i

void drawButton() {
  static bool oldTouch = true;
  int cx = tft.width() / 2;
  int bw = 140, bh = 50, bt = 3;
  int x = cx - bw / 2, y = tft.height() - bh - 10;

  uint16_t tx, ty;
  bool isTouch = tft.getTouch(&tx, &ty);
  isTouch = isTouch && (abs(tx - cx) < bw / 2) && (ty > y);
  if (isTouch == oldTouch) return;
  oldTouch = isTouch;

  tft.fillSmoothRoundRect(x, y, bw, bh, 10, TFT_WHITE);
  if (isTouch) {
    tft.setTextColor(TFT_BLACK, TFT_WHITE, true);
    minDist = getDistance();
  } else {
    tft.fillSmoothRoundRect(x + bt, y + bt, bw - 2 * bt, bh - 2 * bt, 10, TFT_BLACK);
    tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  }
  drawString(cx, y + bh / 2, 1, "set");
  tft.setTextColor(TFT_SILVER, TFT_BLACK, true);
  drawString(cx, y - 30, 1, "  %d  ", minDist);
}

The button's appearance changes based on whether it is pressed or not. The picture below shows the "set" button when not pressed:

"set" button
"set" button

 

Setup Function

In the setup() function, we initialize the sensor and the display

void setup(void) {
  sensor.init();
  tft.init();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
}

 

Loop Function

Finally, the loop() function continuously calls drawDistance() and drawButton() to update the display with the current distance and handle button interactions. A short delay is added to prevent excessive updates.

void loop() {
  drawDistance();
  drawButton();
  delay(100);
}

 

Conclusions

In this tutorial you learned how to build a Parking Sensor with the TOF10120 IR Laser Distance Sensor and a CrowPanel 3.5" ESP32 Display. There are many possible extensions to this project. For instance, you could connect a bright LED to the GPIO port and activate it, when the minimum distance is reached.

Similarly, you could use the speaker port of the CrowPanel Display to sound an alarm, if an object gets too close. There is actually a RP2040 based CrowPanel Pico 4.3" Display that has a built in buzzer you could use instead, or of course, you connect a buzzer to the GPIO port. See the Scribble on CrowPanel Pico 4.3" Display for more details.

Finally, instead of the TOF10120 you could use other infrared distance sensors such as the common GP2Y0A710K0F or the GP2Y0A21YK0F. Also commonly used is the ultrasonic distance sensor HC-SR04 hat use sound waves to measure distance. However, IR laser sensors are more precise and have a longer range compared to ultrasonic sensors.

If you have any questions feel free to leave them in the comment section.

Happy Tinkering ; )

 
user-img

Stefan Maetschke

+ Follow

Topic

View All
CrowPanel
  • Comments( 0 )
  • Like( 2 )
/1000
Upload a photo:
You can only upload 1 files in total. Each file cannot exceed 2MB. Supports JPG, JPEG, GIF, PNG, BMP

You May Also Like

View All