If you are interested on learning about LiDAR and how to use it with Arduino, you have come to the right place! In this post I will be going over how to use LiDAR with Arduino and will use the Benewake TF-Luna as the basis for the application.
What is LiDAR?
LiDAR stands for Light Detection and Ranging and is used to measure distance. It uses the TOF (Time-of-Flight) concept which basically use the time it takes for a light signal to travel to determine the distance to an object (based on already knowing the speed of light). The light signal will be emitted from the sensor and will return (traveling twice the distance between the sensor and the object of interest). We know the speed of light (3*108 m/s), so we can use these two to calculate the distance to the object.

Example LiDAR Sensor – TF-Luna from Benewake
The TF-Luna sensor is a LiDAR sensor based on the Time-of-Flight principle previously discussed. It is able to measure distances from 0.2 meters (7.8 inches) up to 8 meters (~26 feet) and has a resolution of 1cm (0.4 inches). The sensor accuracy is 6cm when measuring less than 3 meters (9.8 feet) and 2% when measuring between 3-8 meters (9.8 feet to 26 feet). Meaning that when measuring 8 meters, the accuracy would be 16 cm (6.3 inches). The power supply voltage is 3.7V – 5.2V.

TF-Luna Pin Connections
- Pin #1 – +5V – Power Supply
- Pin #2 – RXD/SDA – Receiving/Data
- Pin #3 – TXD/SCL – Transmitting/Clock
- Pin #4 – GND – Ground
- Pin #5 – Configuration Input
- Ground: I2C Mode
- Disconnected / 3.3V: Serial Mode
- Pin #6 – Multiplexing Output
- On/off mode: Output
- I2C Mode: Data ready signal

Connecting LiDAR (TF-Luna) to Arduino UNO or NodeMCU
The images below show how to connect the LiDAR sensor TF-Luna to an Arduino UNO or a NodeMCU. Both scenarios are based on running in I2C mode (connecting pin #5 of the TF-Luna to ground).
Arduino Code
Below is a simple example Arduino code of taking measurements with the TF-Luna and displaying them on the Arduino IDE serial monitor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <Arduino.h> #include <Wire.h> // Instantiate the Wire library #include <TFLI2C.h> // TFLuna-I2C Library v.0.1.1 TFLI2C tflI2C; int16_t tfDist; // distance in centimeters int16_t tfAddr = TFL_DEF_ADR; // Use this default I2C address void setup(){ Serial.begin(115200); // Initalize serial port Wire.begin(); // Initalize Wire library } void loop(){ if(tflI2C.getData(tfDist, tfAddr)){ Serial.println(String(tfDist)+" cm / " + String(tfDist/2.54)+" inches"); } delay(50); } |
Testing Results
The images below show readings from the LiDAR TF-Luna at varying distances from the object being measured. A tape measured is placed on the floor to show the distance between the object and the sensor, and you can also see the distance measured by the sensor as it is displayed within the Arduino IDE Serial Monitor.
Components used in this example
*As an Amazon & Ebay Associate I earn from qualifying purchases.
Component | Link |
Arduino UNO | https://ebay.us/veZdKX https://amzn.to/3uYVAMC |
LiDAR Sensor – Benewake TF-Luna | https://ebay.us/TB7e6a https://www.amazon.com/Benewake-TF-Luna-Single-Point-Ranging-Interface/dp/B086MJQSLR |
For some reason or another I cannot get the TFLuna to work with my UNO. I’ve tried this code/setup and another and I am struggling to get it to do anything. The other code I tried, posted below, would give me the “TFMini I2C Test” in the monitor but only at a 38400 baud rate. When trying your code I get a blank screen in the monitor. What am I doing wrong? Thanks
#include
#include
NeoSWSerial Serial1(2,3);
uint16_t distance = 0; //distance
uint16_t strength = 0; // signal strength
uint8_t rangeType = 0; //range scale
/*Value range:
00 (short distance)
03 (intermediate distance)
07 (long distance) */
boolean valid_data = false; //ignore invalid ranging data
const byte sensor1 = 0x10; //TFMini I2C Addres
// Define pins for LEDs
const int greenLED = 8;
const int yellowLED = 9;
const int redLED = 10;
int stopLimit = 160; //Change this number of cm to adjust stop distance
void setup()
{
Wire.begin();
Serial.begin(38400);
Serial.println(“TFMini I2C Test”); //For testing using Serial Monitor
// Set LED pins as outputs
pinMode(redLED, OUTPUT);
pinMode(yellowLED, OUTPUT);
pinMode(greenLED, OUTPUT);
}
void loop()
{
if (readDistance(sensor1) == true)
{
if (valid_data == true) {
Serial.print(“\stopLimit[“); //These Serial.print lines remain for testing and adjustment purposes
Serial.print(stopLimit);
Serial.print(“\tDist[“);
Serial.print(distance);
Serial.println();
if (distance stopLimit && distance (stopLimit + 199) ) { //change this number to adjust when yellow LED illuminates
digitalWrite(redLED, LOW);
digitalWrite(yellowLED, LOW);
digitalWrite(greenLED, HIGH);
}
}
// else {
// Serial.println(“Read fail”);
// }
delay(50); //Delay small amount between readings
}
}
//Write two bytes to a spot
boolean readDistance(uint8_t deviceAddress)
{
Wire.beginTransmission(deviceAddress);
Wire.write(0x01); //MSB
Wire.write(0x02); //LSB
Wire.write(7); //Data length: 7 bytes for distance data
if (Wire.endTransmission(false) != 0) {
return (false); //Sensor did not ACK
}
Wire.requestFrom(deviceAddress, (uint8_t)7); //Ask for 7 bytes
if (Wire.available())
{
for (uint8_t x = 0 ; x < 7 ; x++)
{
uint8_t incoming = Wire.read();
if (x == 0)
{
//Trigger done
if (incoming == 0x00)
{
//Serial.print("Data not valid: ");//for debugging
valid_data = false;
//return(false);
}
else if (incoming == 0x01)
{
Serial.print("Data valid: ");
valid_data = true;
}
}
else if (x == 2)
distance = incoming; //LSB of the distance value "Dist_L"
else if (x == 3)
distance |= incoming << 8; //MSB of the distance value "Dist_H"
else if (x == 4)
strength = incoming; //LSB of signal strength value
else if (x == 5)
strength |= incoming << 8; //MSB of signal strength value
else if (x == 6)
rangeType = incoming; //range scale
}
}
else
{
Serial.println("No wire data avail");
return (false);
}
return (true);
}