Download PDF Parts List View on YouTube Download Code

Time-of-Flight (ToF) LiDAR sensors are gaining popularity in robotics, drones, automation, and IoT projects due to their ability to provide fast and accurate distance measurements in a compact, low-cost package. 

Today, we’ll examine Benewake’s TF-Luna LiDAR sensor. We’ll explain its fundamental operating principle and show you how to get it up and running on three platforms – a Windows PC, an ESP32 S3 Dev Kit, and a Raspberry Pi Pico. 

Introduction

LiDAR (Light Detection and Ranging) sensors have become indispensable in various applications, including robotics, automation, and distance measurement. The TF-Luna LiDAR Time-of-Flight (ToF) sensor is a compact and affordable device that enables precise distance measurements using laser pulses.

In this article and its accompanying video, we’ll explore how this versatile sensor works and demonstrate its implementation across multiple platforms, providing you with the knowledge needed to integrate the TF-Luna into your own projects.

TF-Luna LiDAR

The TF-Luna is a compact, single-point LiDAR sensor designed for short-range distance measurement. The unit is a miniature Time-of-Flight (ToF) sensor that measures distances by timing the round-trip of infrared laser pulses.

This single-point ranging sensor is designed for applications that require precise distance measurements in a compact form factor. It is ideal for robotics, drone navigation, liquid level sensing, and proximity detection systems.

Principle of Operation

The TF-Luna operates on the principle of time-of-flight (ToF). It emits modulated near-infrared laser pulses (around 850 nm) and measures the time it takes for the light to travel to a target and reflect back to the sensor. 

The integrated photodiode detector captures the reflected light, and sophisticated signal processing algorithms within the TF-Luna calculate the precise distance based on the time delay.  

Since the speed of light is constant, the distance to the object can be calculated using the formula:

Distance=(Speed of Light×Time of Flight)/2

The division by two is necessary because the measured time represents the round-trip of the light pulse.

The TF-Luna features advanced noise filtering and ambient light rejection, ensuring reliable measurements even in challenging conditions. The modulated laser approach allows the sensor to distinguish its own signal from ambient infrared sources, providing consistent performance across varying lighting conditions.

The TF-Luna’s compact size and low power consumption make it suitable for a wide range of applications, including:

  • Drone Altitude Hold – Providing accurate height data for stable flight.
  • Robot Obstacle Avoidance – Detecting objects in the robot’s path to prevent collisions.
  • Level Measurement – Monitoring the level of liquids or solids in a container.
  • Presence Detection -Sensing the presence of an object or person in a specific area.

The TF-Luna is inexpensive and, as you’ll soon see, very easy to work with.

TF-Luna Technical Specifications

Here is a list of the specifications of the TF-Luna:

  • Measurement Range – 0.2m to 8m (typical conditions)
  • Accuracy – ±6cm @ 6m, ±2cm @ 2m
  • Resolution – 1cm
  • Field of View – 2°
  • Measurement Frequency – Up to 250Hz
  • Operating Voltage – 3.3V to 5V DC
  • Current Consumption – <150mA
  • Communication Interfaces – UART and I2C
  • Operating Temperature – -10°C to +60°C
  • Dimensions – 35mm × 20mm × 21mm
  • Weight – Approximately 5g

TF-Luna Pinout

The TF-Luna has a 6-pin connector. Many pins have multiple functions, depending on the mode (UART or I2C) in which the TF-Luna operates.

Pin 1 – +5 V

  • Power supply input (3.7 V to 5.2 V) 

Pin 2 – RXD / SDA

  • UART mode: RXD (receives serial data)
  • I²C mode: SDA (I²C data line) 

Pin 3 – TXD / SCL

  • UART mode: TXD (transmits serial data)
  • I²C mode: SCL (I²C clock line) 

Pin 4 – GND

  • Ground reference 

Pin 5 – Mode Select Input

  • Tie to GND: I²C mode
  • Leave open or tie to 3.3 V: UART mode 

Pin 6 – Multiplexing Output

  • UART mode: general-purpose output (on/off)
  • I²C mode: data-ready signal indicating a new measurement is available

The TF-Luna is typically packaged with cables to connect to its 6-pin interface. Note that these cables do not have a standard color code, so always go by the connector pin-out when wiring your TF-Luna.

TF-Luna with Windows

Although we intend to use the TF-Luna with a microcontroller, we’ll first take a quick diversion and use it with a Windows GUI provided by Benewake. 

This utility, available on Benwakes’ website, allows us to test the TF-Luna’s performance and change its parameters. 

The software does not include an installation utility. I copied all the files to my Program Files (86) folder (after providing the appropriate permissions) and ran the utility from there.

TF-Luna with Windows Hookup

To test the TF-Luna with a Windows PC, you’ll need to convert its UART (serial) interface into a USB-compatible signal. This is easily done with an FTDI adapter, also known as a “UART to TTL” adapter.

The following diagram illustrates the connection process for the FTDI adapter and TF-Luna. 

Note that neither the Mode nor Multiplex connections on the TF-Luna are used.  Leaving Mode open puts the TF-Luna into UART mode, which is the desired state.

Many FTDI adapters allow you to select either 3.3 or 5-volt logic. The TF-Luna uses 3.3-volt logic, although it can be powered by up to 5 volts. Set your FTDI adapter to 3.3 volts (many units have a switch or jumper for this purpose).  A 5-volt setting may damage the sensor as the “data in” levels would be too high.

TF-Luna with Windows Demo

Start the GUI application after hooking up the TF-0Luna to your computer via the FTDI adapter.

In the upper corner, there is a drop-down selector box for the model of LiDAR sensor you have. Select “TF-Luna.”

Next, you’ll need to select the COM port. The Baud rate should remain at 115,200.

Now, click the Connect button.

The application will show live distance readings updated several times per second, along with signal strength indicators and internal temperature readings. You can test the sensor by placing objects at various distances and observing how the measurements change in real time.

The GUI also provides advanced configuration options, allowing you to adjust measurement frequency, output format, and communication parameters to suit specific applications.

You can also use the Custom Command section to send data to the TF-Luna to reset some parameters. The documentation from Benewake, which you downloaded with the GUI utility, has details for doing this.

The GUI application is a great way to test out and, if necessary, reconfigure your TF-Luna LiDAR sensor.

TF-Luna with ESP32 (I2C Mode)

Of course, we really want to use our TF-Luna with a microcontroller. 

An ESP32 is ideal for the job, as it can communicate using UART or I2C and operates with 3.3-volt logic.  Let’s see how we can use it with an I2C hookup.

TF-Luna with ESP32 Hookup

I’m using the TF-Luna with an ESP32 S3 Dev Kit, a huge ESP32 with many I/O pins and two USB ports. However, any ESP32 should work with the TF-Luna. 

We will be using the device in I2C mode, so we are hooking up with an SDA and SCL line. If you use a different ESP32 and it doesn’t have the same GPIO pins I used, just substitute two different pins and adjust the code accordingly.

I powered the TF-Luna with the 3.3-volt outputs from the ESP32, and it worked perfectly. You could also use the 5-volt output if you wish.

TF-Luna with ESP32 Code

There are no popular libraries available for the TF-Luna LiDAR ToF sensor. I did find an older one that was still in alpha, but it didn’t come with any sample code. It’s obviously an abandoned product, as it hasn’t been updated for several years.

However, that isn’t a significant issue, as Benewake has documented all the communication parameters of the TF-Luna for both serial and I2C modes.  We can simply exchange data manually with the TF-Luna.

Here is a sketch that does just that. It extracts the three data fields (distance, light intensity, and chip temperature) from the TF-Luna and displays the values on the serial monitor. 

The sketch starts by loading the Wire library, which is the built-in library for using the I2C bus.  We then define the SDA and SCL connections to the ESP32. If you used different pins, then you need to edit the sketch to reflect these changes.

Next, we define some communication parameters. We will be using the default I2C address, and the TF-Luna transmits nine bytes of information.

After that, we define a character buffer that will contain five bytes. This is a command packet that instructs the TF-Luna to trigger a measurement and send it.  You can break it down as follows:

  • 0x5A – Start byte
  • 0x05 – Command ID: “take one reading”
  • 0x00 – Low byte of register/count address (unused here, set to 0)
  • 0x01 – Number of measurements requested (1)
  • 0x60 – Checksum (0x5A + 0x05 + 0x00 + 0x01 = 0x60)

In Setup, we initialize the I2C bus and serial port.

Next, we jump into the Loop, where we send the packet to the TF-Luna to extract one packet of data.  We also initialize some variables to hold that data.

When the data comes back, we verify that it is exactly nine bytes. If it is, then we extract the three measurements and display them on the serial monitor.

Load the sketch up onto the ESP32 and check it out. You should see the readings on the serial monitor, and they should change when you move the TF-Luna sensor around.

You can use this sketch as the basis of any TF-Luna-based application.

TF-Luna with Raspberry Pi Pico (UART Mode)

Now we will move on to another microcontroller and another programming language.

We will be using a Raspberry Pi Pico running in MicroPython to essentially duplicate the previous ESP32 C++ sketch.  While I used an original Pico, any of the four current models (Pico, Pico W, Pico 2, and Pico 2W) will work.

MicroPython

MicroPython is a streamlined implementation of the Python 3 language, specifically designed to run on microcontrollers and other resource-constrained devices, such as the Raspberry Pi Pico. MicroPython provides direct access to hardware features such as GPIO pins, I2C, UART, PWM, and ADC through its intuitive Python-style interface.

Installing MicroPython on a Raspberry Pi Pico is a straightforward process that involves downloading the firmware and flashing it to the device’s onboard memory. The installation process consists of putting the Pico into bootloader mode, downloading the appropriate firmware file, and copying it to the device. After this, the Pico will be ready to run MicroPython programs directly.

  • Download the latest rp2-pico-*.uf2 from micropython.org.
  • Plug the Pico into your PC’s USB port while holding the BOOTSEL button.
  • Wait for the “RPI-RP2” mass-storage drive to appear in your file manager.
  • Drag & drop the UF2 file onto the “RPI-RP2” drive (no other files needed).
  • The Pico will automatically reboot and is ready to use with MicroPython.

I used Thonny IDE for editing MicroPython; it’s a simple editor that works with Linux, macOS, and Windows.

TF-Luna with Pico Hookup

As with the ESP32, hooking up a TF-Luna to the Raspberry Pi Pico is pretty simple. This time, we are using serial UART mode, so we want to connect to one of the Pico’s internal UARTS.

As we are operating in Serial Mode, the Mode pin on the TF-Luna is left disconnected; it is internally pulled HIGH. This puts the TF-Lunal into UART mode.

We wire the TF-Luna transmit pin (pin 3) to the Pico UART 1 Receive Pin, which is physical pin 12 and GPIO pin 9. We also wire the TF-Luna receive pin (pin 2) to the PIco UART 1 transmit pin, physical pin 11, and GPIO pin 8.  

Ground and power are the only other connections. You can power the TF-Luna with either 3.3V or 5V. I used the Picos 3.3-volt output.

TF-Luna with Pico Code

We are using MicroPython for our test, so I will assume that you have loaded the Pico with MicroPython and are using an editor with a REPL, such as Thonny IDE.  Connect the Pico to the computer and connect to the Pico MicroPython.

Here is the code we will be using with our TF-Luna and Raspberry Pi Pico:

We begin by importing the necessary libraries to work with the I/O pins and UART. The time library is used to allow for delays.

Next, we set up two UARTS:

  • UART1 – The UART that we have connected the TF-Luna to.
  • UART0 – The UART connected to the USB port for serial data.

Next, we have a function called getLidarData. As its name implies, it retrieves data from the TF-Luna connected to UART1.

It starts by defining an empty array to store the incoming data. It then checks UART1 to see if any data is there. If it is, then the incoming data is tested to see if it is nine bytes long.  It then checks the data packet header to see if it matches the value 0x59.

If the data is valid, then it is broken down to retrieve the distance in centimeters, the signal strength, and the temperature of the internal sensor.  The data is then forwarded to UART0.

The program calls this function with a 10 ms delay between readings and prints the results to the console. 

Load the program and run it directly on the Pico. Observe the console; it should resemble the readings displayed in the serial monitor for the ESP32.

Once again, use this code as the basis for working with the TF-Luna LiDAR sensor using MicroPython.

Conclusion

In this article, we explored the TF-Luna LiDAR sensor and demonstrated how easy it is to get started on a Windows PC using Benewake’s GUI and an FTDI adapter, providing live distance, signal strength, and temperature data in real-time.   After that, we moved on to using the sensor with microcontrollers – the ESP32 with C++ and a Raspberry Pi Pico using MicroPython.

In every case, the TF-Luna was easy to use and performed admirably.

Whether you’re building obstacle-avoiding robots, level sensors, or interactive installations, TF-Luna’s compact size, low power draw, and easy serial interfaces make it a great choice. 

Now that you have working examples for the ESP32 and Pico, you can start experimenting. Dive into the TF-Luna User Manual to unlock advanced settings, including output rate, distance filtering, and power modes, and take your projects to the next level with reliable, precise distance sensing.

With the right wiring and a few lines of code, users of all experience levels can harness powerful time-of-flight distance data in their projects. As LiDAR technology continues to evolve and become more affordable, sensors like the TF-Luna are opening up new opportunities for makers, educators, and engineers to bring intelligent sensing into their everyday builds.

Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.

TF-Luna – AmazonMouser

ESP32 S3 Dev Kit – AmazonMouser

Raspberry Pi Pico – AmazonMouser

 

Resources

Code Samples – All the code used in this article in one easy-to-use ZIP file!

Article PDF – A PDF version of this article in a ZIP file.

TF-Luna Download Page – Benewake official documentation and GUI download

TF-Luna Product Manual – User’s Guide to TF-Luna.

MicroPython for Raspberry Pi Pico – MicroPython download for Pico

Thonny IDE – Python & MicroPython IDE for Linux, macOS & Windows

TF-Luna I2C Address Changer – Arduino Sketch for changing TF-Luna I2C Address

 

TF Luna LIDAR with ESP32 & Raspberry Pi Pico
Summary
TF Luna LIDAR with ESP32 & Raspberry Pi Pico
Article Name
TF Luna LIDAR with ESP32 & Raspberry Pi Pico
Description
The TF-Luna is a low-cost, high-performance LiDAR ToF Sensor. Today we will see how to use the TF-Luna with an ESP32 and Raspberry Pi Pico. We'll also look at a Windows GUI that can be used to test and configure the device.
Author
Publisher Name
DroneBot Workshop
Publisher Logo

5 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Philip Reichel
4 months ago

This is a neat little device. Thank you for showing!

One question to the ESP32 C++ code:
Wouldn’t it be possible to define a union for the receive buffer and thus read in the values directly
without recalculation? It is not necessary for that little example but since memory space matters
in the microcontroller world it would maybe be a good tutorial addition?

Bob Vines
4 months ago

Bill, the links to download the PDF of the article & the .zip file with code don’t work. Can you fix it?

Jerry Gooch
2 months ago

This is a very interesting demo. However, as Mr. Vines noted, the links to the PDF and the zip file do not work. It would be appreciated if you could take a look (in your copious amounts of spare time!!!). As always, I am appreciative of all you give to the community.

Thai Son
2 months ago

Appreciate it !!!
One thing that i still not understand is the buf1 in your code with esp32, how do you know the command like ” 0x5A, 0x05, 0x00, 0x01, 0x60 ” is read value from lidar luna, i have readed the datasheet but i can’t see the instruction about that, can you explain for me, thank you.

Robert
1 month ago

Thanks for an interesting and useful article.

I’m testing this lidar with my Raspberry pi 3 board.
Initial tests seem to suggest that the unit tends to detect any object anywhere within a wide field of view.

But the brief specification mentions ” 2° Sensing Field-of-View (FoV) “.
What does that technical statement mean ?

Has anyone else tested this unit and observed if it can discern or indicate the distance to only objects that are directly in front of it, within a narrow field of view ?

let us know,
Thanks
Robert