Arduino Projects

TOF10120 Laser Rangefinder + Arduino + Display, Interfacing & Code

TOF10120 Laser Range Sensor, Description:

 

TOF10120 Laser Range Sensor with Arduino– So far I have been using Ultrasonic Sensor for the distance measurement and used this sensor in so many amazing projects including the Ultrasonic Sensor based water level monitoring system, Social distancing project against the Covid-19 Corona Virus, in an Automatic car deceleration system to maintain the safe distance, Smart Dustbin,  IoT based Flood Monitoring System, and in so many other cool projects. No doubt the Ultrasonic Sensor is an amazing sensor and is most frequently used throughout the world. If you compare the Ultrasonic Sensor with the TOF10120 you will find that the Ultrasonic Sensor is cheaper than the TOF10120 Laser distance sensor. But personally, the only thing I like about the TOF10120 is that the TOF10120 Laser range sensor is small in size and is very fast. You can clearly see the size difference in the image given below.

TOF10120

In this tutorial, we will use the ToF10120 Laser Range Sensor module for measuring distance. So, before I am going to explain anything, first a few words about the sponsor for sending these beautiful and high quality PCBs.

TOF10120


About the Sponsor PCBWay:

TOF10120

High quality & Only 24 Hours Build time

The PCB boards used in this project are sponsored by the PCBWay Company. Only 5 dollars for 10 PCBs and 30 dollars in total for 20 PCBs Assembly.  Besides this PCBWay also provides a great variety of services including Aluminum PCB, Rigid-Flex, Metal Core, flexible, High Frequency, High-TG, Thick-Copper, HDI, and LED PCBs. The sign up process hardly takes 1 minute and you are welcomed with a 5 dollars welcome bonus, what are you waiting for go and get your first prototype order for free.

TOF10120

As usual, before I am going to use the TOF10120 Laser Range sensor in some intermediate and advanced level projects, first I will cover the extreme basics to help you get started with this small tiny beautiful piece of hardware.

 

TOF10120

I performed a series of experiments and displayed the values on the serial monitor and once satisfied, I further modified the code and displayed the measured distance in millimeters and Inches on the Oled Display module.



Unlike the Ultrasonic Sensor the TOF10120 Laser distance Sensor can also be used for monitoring the water level, it can be used in security systems, obstacle avoidance robots, and so on.  Anyhow, I continued with the experiments, modified the code one more time and this time I was able to control a 110/220Vac light Bulb.

TOF10120

Caution!!! Make sure you wear protective gloves as 220Vac can be really dangerous.

You can replace this bulb with a water pump, or any other electrical device that you want to control. The Bulb is turned ON when the distance is less than 5 inches and remains ON until the distance is greater than 10 inches.

TOF10120

While performing the experiments, when the TOF10120 Laser distance Sensor was facing the camera, I could see this light coming out of the sensor which you can’t see with naked eyes, if you have this sensor go ahead and check.

In this tutorial, we will cover,

  1. ToF10120 Laser Range Sensor Module Pinout and technical specifications.
  2. Complete circuit diagram explanation.
  3. Arduino Programming, and finally
  4. Testing

Without any further delay, let’s get started!!!


Amazon Purchase Links:

tof10120 laser range sensor

12v Adaptor:

Arduino Uno

Arduino Nano

Mega 2560:

SSD1306 128×64 Oled i2c display Module

Other Tools and Components:

Super Starter kit for Beginners

Digital Oscilloscopes

Variable Supply

Digital Multimeter

Soldering iron kits

PCB small portable drill machines

*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!

ToF10120 Specs, Feature, Applications, Pinout:

TOF10120

TOF10120 range sensor provides accurate and repeatable long-range distance measurement for high-speed autofocus (AF). The innovative time-of-flight technology allows performance independent of object reflectance.

TOF10120’s time-of-flight sensing technology is realized by Sharp’s original SPAD (Single Photon Avalanche Diodes ) using low-cost standard CMOS process. It enables accurate ranging results, higher immunity to ambient light and better robustness to cover-glass optical cross-talk by special optical package design.

TOF10120 Features:

・940nm laser classified as class 1 under operation condition by IEC 60825-1:2014-3rd edition

・Small ceramic package(20×13.2×2.0mm)

・Long range absolute range measurement up to 1.8m within 5% accuracy at indoor.

・Reported range is independent of the target reflectance

・Operates in high infrared ambient light levels

・Advanced optical cross-talk compensation

・High speed ranging MAX 30ms

・Standard solder reflow compatible

・No additional optics

・Single power supply

・Txd interface for device control and data transfer

・Lead-free, RoHS compliant


TOF10120 Applications:

・High-speed AF

・Continuous AF for video

・User detection for Personal Computers/Laptops/Tablets

・Robotics (obstacle detection)

・Contactless Switch

・White goods (hand detection in automatic Faucets, refrigerator etc.)

TOF10120 Recommended Operating Conditions:

TOF10120

As per the datasheet the recommended ranging range of the TOF10120 is between 100 and 1800 the unit is in mm (millimeters). The TOF10120 Laser Range Sensor Module can be easily powered up using 3 to 5 volts. Due to this wide range of input voltages the TOF10120 can be easily used with 5V and 3.3V compatible controller boards like Arduino boards, ESP8266, and ESP32 etc. The current consumption of the TOF10120 is 35mA. The ideal temperature range of the TOF10120 is from -20 to +70 Centigrade. Due to this wide temperature range, this module can be used in extreme weather conditions indoor and outdoor.

TOF10120 Ranging Conditions:

TOF10120

The range accuracy change as per the above conditions which depends on the Target Reflection and environment.


TOF10120 Pin Description:

TOF10120

From the signal names of the TOF10120 it’s quite clear that this RangeFinder supports both the UART and the I2C communication. Pin number1 is the ground. Pin number2 is the VDD. Pin number3 is the RXD. Pin number4 is the TXD. Pin number 5 is the SDA and finally pin number6 is the SCL. Out of the 6 pins of the TOF10120 I will use only 4 pins. GND, VDD, SDA, and SCL.

TOF10120 I2C Address:

As per the datasheet the I2C address of the TOF10120 is 0xA4. But i2c addressing uses the high 7 bits so it’s 0x52 which is equivalent to 82. You can also find the I2C address of the TOF10120 by using the I2C Scanner code which is available below in the programming section.

For more details download the TOF10120 datasheet.

SSD1306 Oled Display Module:

TOF10120

This is the 128×64 I2C supported SSD1306 Oled Display Module. It has a total of 4 male headers, clearly labeled as GND, VCC, SCL, and SDA. This Oled display module can be easily powered up using 3.3 to 5 volts. If you have never used the Oled display module or if you face any problem in displaying data on the Oled display module then I highly recommend read my article “Arduino Oled i2c Display 128×64 with examples, Wiring, and Libraries issues solved”.

As both the modules supports I2C communication, so using only 2 pins A4 and A5 of the Arduino which are the SDA and SCL, we can communicate with both the modules.



TOF10120 Laser Range Sensor Interfacing with Arduino, Circuit Diagram:

TOF10120

The regulated 5V power supply based on the LM7805 linear voltage regulator is used to power up all the electronics. A DC female Power jack J1 is connected with the regulator input and ground pin. J1 female power jack is used to connect the input power supply. Two 470uF capacitors are connected at the input and output sides of the voltage regulator. These are decoupling capacitors. The regulated 5 volts from the output of the voltage regulator are connected with the VIN pin of the Arduino Nano.

The SCL and SDA pins of both the modules are connected with the Arduino’s A5 and A4 pins. A5 is the SCL and A4 is the SDA. While the power supply pins of Oled display and the TOF10120 are connected with the Arduino’s 5V and ground.

A 110/220Vac light bulb is connected with the relay common and normally open contacts. This relay is controlled using the 2n2222 NPN transistor. This relay is turned ON and turned OFF using the Arduino pin number 13. You can use a readymade relay module or you can build a one by yourself by following the same connections. Read my article on types of relays and how to use them.

PCB designing:

TOF10120

Download Arduino Nano Gerber files:

Next, I designed a PCB for the Arduino Nano, which I will use as the Development board. I added female headers for the 3.3V, 12V, 5V, and ground. The right side area can be used as the Vero Board for soldering other electronic components. I also added female headers on the left and right sides of the Arduino Nano for connecting the jumper wires.

TOF10120

Download one-channel Relay Module Gerber files:

I also designed a one channel relay module. I double checked all the connections and finally generated the Gerber files. As usual I used the PCBWay online Gerber viewer for checking the generated Gerber files. I checked all the layers and once satisfied I placed an online order on the PCBWay official website.

TOF10120

These are the PCBs I received from the PCBWay Company. As you can see the quality is really greater, the silkscreen is quite clear. Finally, I started off by placing the components and completed the soldering Job.

TOF10120

I completed the soldering job carefully, checked the continuity and short circuit. Then I connected the input and ground wires of the relay module with the Arduino pin number 13 and ground as per the circuit diagram. I also connected the Oled display module and the TOF10120 with the Arduino Nano. This is how it looks after connecting the Laser Range Sensor and the Relay Module. Finally I connected the Bulb holder with the relay module as per the circuit diagram already explained and with this my interfacing just completed. Now it’s time to take a look at the Arduino programming.

Before I am going to explain the entire project code, first I would like to share with you the i2c scanner code which you can use to find the i2c address of any i2c supported device. You can the Oled display module and the TOF10120 laser range sensor both are i2c supported devices. You will need to find their i2c addresses. Remove the Oled display module and leave the TOF10120 Laser distance sensor and upload the following i2c scanner code into the Arduino board. You will need the Wire.h library, the download link is given below.


I2C Scanner Code:

#include <Wire.h>
 
void setup()
{
    Wire.begin();
    Serial.begin(115200);
    Serial.println("\nI2C Scanner");
}
 
void loop()
{
    byte error, address;
    int nDevices;
 
    Serial.println("Scanning...");
 
    nDevices = 0;
    for(address = 0; address <= 127; address++ )
    {
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
        if (error == 0)
        {
            Serial.print("I2C device found at address 0x");
            if (address<16)
                Serial.print("0");
            Serial.print(address, HEX);
            Serial.println(" !");
            nDevices++;
        }
        else if (error==4)
        {
            Serial.print("Unknow error at address 0x");
            if (address<16)
                Serial.print("0");
            Serial.println(address,HEX);
        }
    }
    if (nDevices == 0)
        Serial.println("No I2C devices found\n");
    else
        Serial.println("done\n");
    delay(30000);
 }

After uploading the above code. Open the serial monitor and you will see the i2c address of the TOF10120 Laser Rangefinder sensor. As per the datasheet the I2C address of the TOF10120 is 0xA4. But i2c addressing uses the high 7 bits so it’s 0x52 which is equivalent to 82.

TOF10120

This is equivalent to 82. Now, you can disconnect the TOF10120 Laser Range Sensor and connect the Oled display module. Turn on the Arduino and open the serial monitor. This time you will see the i2c address of the SSD1306 Oled display.

Before, you start the programming; first of all, make sure you download all the necessary libraries.

SimpleTimer

After downloading the SimpleTimer library, simply extract the winrar file, open the folder and inside that folder you will see the zip folder. Simply add that zip library using the Arduino IDE. Go, to the sketch Menu, then to include library, and click on the add .zip library. then browse to the location and select the SimpleTimer.zip folder and add it. that’s it. Download the same steps for the following libraries too.

Adafruit_GFX

Adafruit_SSD1306

The purpose of the following program is to measure the distance using the time-of-flight 10120 Laser Rangefinder sensor and display the distance value in millimeters and inches on the Oled display module and also to control the Light Bulb.


TOF10120 Laser Range Sensor Arduino Programming:

/* This code is to use with ToF10120 Laser Range Sensor to measure distance in (mm)and (inches) and shows it on the Serial monitor and also on the I2C LCD using I²c inteface
 * Modified and adapted from a code found on some dodgy chinese website
 * Refer to https://www.electroniclinic.com/ for more details
 */

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SimpleTimer.h>

SimpleTimer timer;

unsigned char ok_flag;
unsigned char fail_flag;

unsigned short lenth_val = 0;
unsigned char i2c_rx_buf[16];
unsigned char dirsend_flag=0;

int x_mm; // distance in millimeters
float y_inches; // distance in inches

// for the OLED display

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
 
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int relay = 13; 
int relay_flag = 0; 

void setup() {
  Wire.begin(); 
  Serial.begin(9600,SERIAL_8N1); 
  pinMode(relay, OUTPUT); 
  digitalWrite(relay, LOW);
  printf_begin(); 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(WHITE);         

timer.setInterval(500L, display_measurement);
}

void loop() {
  
timer.run(); // Initiates SimpleTimer

   x_mm = ReadDistance();
   Serial.print(x_mm);
   Serial.println(" mm");

   // You can convert millimeters to inches in one of two ways: divide the number of millimeters by 25.4, or multiply the number of millimeters by 0.0394
   y_inches = x_mm * 0.0394;
   Serial.print(y_inches); 
   Serial.println(" inches");

if( (y_inches > 10 ) && (relay_flag == 0))
{
  digitalWrite(relay, LOW); 
  relay_flag = 1; 
}

if( (y_inches <= 5 ) && (relay_flag == 1))
{
  digitalWrite(relay, HIGH); 
  relay_flag = 0; 
}
 
}

int serial_putc( char c, struct __file * )
{
  Serial.write( c );
  return c;
}

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}



void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) 
{
  unsigned short result=0;
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com
  // the address specified in the datasheet is 164 (0xa4)
  // but i2c adressing uses the high 7 bits so it's 82
  Wire.write(byte(addr));      // sets distance data address (addr)
  Wire.endTransmission();      // stop transmitting
  // step 2: wait for readings to happen
  delay(1);                   // datasheet suggests at least 30uS
  // step 3: request reading from sensor
  Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)
  // step 5: receive reading from sensor
  if (cnt <= Wire.available()) { // if two bytes were received
    *datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)
    *datbuf++ = Wire.read(); // receive low byte as lower 8 bits
  }
}

int ReadDistance(){
    SensorRead(0x00,i2c_rx_buf,2);
    lenth_val=i2c_rx_buf[0];
    lenth_val=lenth_val<<8;
    lenth_val|=i2c_rx_buf[1];
    delay(300); 
    return lenth_val;
}

void display_measurement()
{
     // display on Oled display

   // Oled display
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0); // column row
  display.print("mm:");

  display.setTextSize(2);
  display.setCursor(55, 0);
  display.print(x_mm);

    display.setTextSize(2);
  display.setCursor(0,30);
  display.print("In:");

  display.setTextSize(2);
  display.setCursor(60, 30);
  display.print(y_inches);
  display.setCursor(95, 50);

 display.display();
}

TOF10120 Arduino code explanation:

You will need the Wire.h library for the I2C communication. You will need the Adafruit_GFX.h and Adafruit_SSD1306.h for the SSD1306 Oled display module. The SimpleTimer.h library is used for defining multiple software timers.

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <SimpleTimer.h>

I started by defining a timer, which I will use for controlling the Oled display module.

SimpleTimer timer;

unsigned char ok_flag;

unsigned char fail_flag;

unsigned short lenth_val = 0;

unsigned char i2c_rx_buf[16];

unsigned char dirsend_flag=0;


I defined the following two variables for storing the distance values in millimeters and inches. You can also define variables for centimeters and feet if you want.

int x_mm; // distance in millimeters

float y_inches; // distance in inches

// for the OLED display

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

To control the relay module I defined a pin. Relay module is controlled using the Arduino pin number 13. I also defined a variable relay_flag which I will use as the flag. This will be used to stop the unnecessary repetition of code.

int relay = 13;

int relay_flag = 0;

void setup() {

Wire.begin();

Serial.begin(9600,SERIAL_8N1);

pinMode(relay, OUTPUT);

digitalWrite(relay, LOW);

printf_begin();

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.clearDisplay();

display.setTextColor(WHITE);

timer.setInterval(500L, display_measurement);

}



void loop() {

timer.run(); // Initiates SimpleTimer

x_mm = ReadDistance();

Serial.print(x_mm);

Serial.println(” mm”);

// You can convert millimeters to inches in one of two ways: divide the number of millimeters by 25.4, or multiply the number of millimeters by 0.0394

y_inches = x_mm * 0.0394;

Serial.print(y_inches);

Serial.println(” inches”);

The following two conditions are used to control the relay.

if( (y_inches > 10 ) && (relay_flag == 0))

{

digitalWrite(relay, LOW);

relay_flag = 1;

}

 

if( (y_inches <= 5 ) && (relay_flag == 1))

{

digitalWrite(relay, HIGH);

relay_flag = 0;

}

 

}

 

int serial_putc( char c, struct __file * )

{

Serial.write( c );

return c;

}


void printf_begin(void)

{

fdevopen( &serial_putc, 0 );

}

void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt)

{

unsigned short result=0;

// step 1: instruct sensor to read echoes

Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com

// the address specified in the datasheet is 164 (0xa4)

// but i2c adressing uses the high 7 bits so it’s 82

Wire.write(byte(addr));      // sets distance data address (addr)

Wire.endTransmission();      // stop transmitting

// step 2: wait for readings to happen

delay(1);                   // datasheet suggests at least 30uS

// step 3: request reading from sensor

Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)

// step 5: receive reading from sensor

if (cnt <= Wire.available()) { // if two bytes were received

*datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)

*datbuf++ = Wire.read(); // receive low byte as lower 8 bits

}

}

int ReadDistance(){

SensorRead(0x00,i2c_rx_buf,2);

lenth_val=i2c_rx_buf[0];

lenth_val=lenth_val<<8;

lenth_val|=i2c_rx_buf[1];

delay(300);

return lenth_val;

}

display_measurement() is a user-defined function. it has no return type and does not take any argument as the input. As in the beginning I said, this function is controlled using the timer. This function is called after every half second to display the distance values on the Oled display module.

void display_measurement()

{

// display on Oled display

 

// Oled display

display.clearDisplay();

display.setTextSize(2);

display.setCursor(0,0); // column row

display.print(“mm:”);

display.setTextSize(2);

display.setCursor(55, 0);

display.print(x_mm);

display.setTextSize(2);

display.setCursor(0,30);

display.print(“In:”);

display.setTextSize(2);

display.setCursor(60, 30);

display.print(y_inches);

display.setCursor(95, 50);

 

display.display();

}

I uploaded the program and I was able to measure the distance in millimeters and inches using the TOF10120 Laser Range Sensor module. I already demonstrated how the whole project works. For the step-by-step explanation and practical demonstration watch the video tutorial given below. If you have any questions regarding this article let me know in a comment.


Watch Video Tutorial:

 

Engr Fahad

My name is Shahzada Fahad and I am an Electrical Engineer. I have been doing Job in UAE as a site engineer in an Electrical Construction Company. Currently, I am running my own YouTube channel "Electronic Clinic", and managing this Website. My Hobbies are * Watching Movies * Music * Martial Arts * Photography * Travelling * Make Sketches and so on...

4 Comments

  1. This was amazing thank you so much. I’m having issues with my program u was wondering if you could give me a tip or 2.

    I have my laser telling me the distance but I’m trying to connect another to tell me the same distance but for opposite sides. I know there’s only one i2c bus for arduino uno. Is there a way where I can get both of them to talk at different tines?

  2. Hi there, I am very new to this. I’m glad I came across your site, it’s very helpful.
    I just wanted to confirm, does the TOF10120 range sensor have to have a solid reflective surface to be accurate? I am looking for something that can measure the distance to the ground (any conditions. carpet, concrete or grass) from a sensor like this which will be raised and lowered by a person. As this will be attached to something then onto the person. So when they move it up or down (with 6 pre-set height levels) an alarm will sound to say it is at the correct height from the ground. Am I looking at the right sensor for this task?
    I was also wondering if this is able to be used with a rechargeable battery?
    Thanks in advance, warm regards
    Sarah

  3. Good morning
    Thanks for sharing this build.
    I don’t know how to stabilize the measurement.
    the fixed sensor, the fixed obstacle, the measurement does not remain fixed,
    it goes up and down, for example, I measure an obstacle at 50mm
    the measurement m indicates 48, 50,57,47,50…….
    Is there a way to stabilize the measurement?
    THANKS

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button