View on GitHub

ECE4160 - Fast Robots

Spring 2024

Back

Lab 3: Time of Flight Sensors

Prelab

This lab involved setting up the VL53L1X ToF (time of flight) sensors. After skimming the datasheet I found that the I2C address of the sensor is 0x52. The address comes hard-wired on the board, so at the start both sensors have the same address. To communicate with the two sensors separately, I will need to change one of the address’s. To do this I will use the shutdown pin of one sensor to turn it off, and then communicate with the active sensor to programmatically change its address. Then I can power on the other sensor and communicate with each separately.

I decided it would be best to put one sensor on the front of the robot and the other on one of the sides. I believe it is most important to detect obstacles in front of the robot since driving forward is the more common action. One sensor on the side will be helpful for turning. Using two sensors on the same side could cause interference in the signals and doesn’t optimize the range of obstacles you could detect. However, I could miss obstacles on the other side or behind.

Below is a sketch of a simple wiring diagram to connect both ToF sensors to the Artemis. The sensor’s pins need to be soldered to QWIIC cables to connect to the main QWIIC breakout board which is connected to the Artemis’ QWIIC port. For one sensor, I will need to solder a wire from the XSHUT pin to a GPIO pin on the Artemis.

Connecting the Sensors

The image below shows the soldered connections mentioned above. The green wire is soldered from the XSHUT pin of one sensor to GPIO pin A1 on the Artemis.

Scanning I2C

I then ran an example code file to scan the I2C channel to find the ToF sensor attached. The address found was 0x29, which was not the 0x52 address I expected from the data sheet. This is because the address has an 8th bit to designate a read/write. The datasheet includes this bit in the address which gives 0x52. In Arduino IDE, it seems that this read/write bit is ignored and only the upper 7 bits are taken instead of 8. This changes the address to 0x29, meaning the I2C did find the ToF sensor.

Sensor Mode and Data Collection

The sensor can be in short mode or long mode. Long mode can detect objects up to 3.6 m away but is very sensitive to ambient lighting. Short mode can only read up to 1.3 m away but is very immune to ambient lighting. For now I think it is better to use short mode for the robot since I want measurements to be as accurate as possible. Also, my robot will likely have to navigate a room with ambient lighting, which could cause noise in long mode.

I set up objects away from my ToF sensor at distances of: 0.25, 0.5, 0.75, 1.0, and 1.25 m away. I collected 100 measurements at each distance, took the averages, and then plotted them against the correct distance. The figure and data are included below.

Actual Distance (mm) ToF Average (mm) ToF Standard Deviation (mm)
250 238.13 0.87
500 485.6 1.63
750 761.23 2.34
1000 1087.49 6.04
1250 1261.14 2.44

As seen in the data the sensor is fairly accurate. It is typically around 0.1-0.2 m off of the true distance. The standard deviations were also fairly low indicating that the sensor has good repeatability. There is a trend of higher noise at larger distances which makes sense. I also have to consider that there is human error in how far away I placed objects from the sensor, and it is possible the sensor picked up other objects in the area. The range of the sensor was also sufficient as it measured objects up to 1.25 m away, and in short mode the maximum distance is 1.3 m.

Hooking Up Both ToF Sensors

Now, I connected my second ToF sensor. I created two global variables in my Arduino code to represent each sensor. Then, in the setup function I set pin A1 as an output, and then wrote LOW to it to turn off one sensor. This is because the XSHUT pin is active low. Now,I used the setI2CAddress() function to change the address of the active sensor to 0x16. After changing the address I wrote HIGH to pin A1, turning that sensor back on. The below video demonstrates the both sensors working in parallel.

Speed of Data Collection

I wrote a loop that printed out the run-time in milliseconds of the Arduino clock each iteration. Also, in the loop I checked if data was ready at each sensor and printed the distance readings only if it was available. The goal was to measure the run-time of the loop. I found that if data from neither sensor was available one iteration took around 3-4 ms to run. However, if data from a sensor was available, then one iteration took around 9ms to run. The limiting factor seemed to be the internal delay to start/stop ranging, clear interrupts, and retrieve the data from the sensor. There is also the delay introduced from printing to the monitor also when data is ready. Below is the code I used.

5 Seconds of Data

For the last part of the lab I modified my code from lab 2 to record 5 seconds of data from each sensor and store them in arrays along with the timestamps for each entry. I then sent all the data over bluetooth to my computer and plotted the readings against time using matplotlib. Below is the resulting plot.