Scanning TOF10120 with output to OLED


Well-known member
I read a few weeks ago a thread about the TOF10120, which seemed a rather more useful proximity detector than the laser plus Hamamatsu S6986 that I initially tried. I then thought that it might be interesting to output the distance to a screen, and then even more interesting to have the sensor rotate in order to produce some kind of image of what's in front of a vehicle. I've learned a lot about stepper motors and multiple devices on i2c over the last few weeks, and had to delve back into trigonometry, last used a few decades ago for O-level maths.

It now seems to be working. There are some refinements still to come, but I thought others might be interested to see the progress so far.

In terms of set-up, I have a 28x2 at 64MHz, outputting the step codes to a TC4469 driver (the same chip I am using for my remote controlled vehicle). The TC4469 controls a very small bipolar stepper motor off ebay that does 0.18 degrees per step after the gearing (so 2000 steps per 360 degree rotation. The data sheet for the TC4469 has a set-up for a bipolar stepper (Fig. 5.1 here:, but I couldn't get it to work and couldn't reconcile the two input lines with the logic in the truth table, so I found another diagram (Fig 24 here: and used pins B.0 to B.3 to drive the 4 inputs of the TC4469. There seem to be a number of permutations of stepper codes - some driving one line at a time and others driving 2. I ended up with a full-step code that drives 2 lines at a time. I spent a long time getting the stepper codes, delay between steps, direction etc right. A set of 4 LEDs was useful for seeing what was happening. I also tried a slightly larger stepper with 1.25 degrees per step which was a better arrangement because it was faster, but after running happily for a while it became temperamental and kept sticking and jumping, so I parked it. It may be a dodgy contact somewhere that I will be able to track down and resolve.

Thanks to a couple of useful threads on the forum, particularly: addressing multiple i2c slaves from and I was able to set up both the SSD1306 display and the TOF10120.

The laser range sensor outputs a range up to 2000mm (limited in my case to 900mm in the interests of not exceeding the limits of the word variable during the calculations. The angle is known because each sensor reading corresponds to a specific step (or with this motor, the end of a known 5-step loop that covers 0.9 degrees). Range and angle are converted into x,y coordinates by two lookup tables that hold the sine and cosine of the angle corresponding to each of the 67 5-steps that cover the 60 degrees of a sweep. I'm assuming that a lookup table is quicker than going to scratchpad. x coordinates are measured from column 63 of the display, so coordinates to the left are deducted from 63. Y coordinates are divided by 8. The whole number gives the row and the remainder sets one of 8 byte patterns that lights the right dot in the row. It took quite a lot of trial and error to get it right. There may be a quicker way of addressing the right dot on the screen.

I attach the code as it currently stands.



Well-known member
So far it seems to work quite well. I want to add two pairs of LED/detectors at the limit of the sensor rotation in case it wants to overshoot, and also to permit an initialisation routine that sends the stepper to one of the extremities then counts back 60% to the centre. Ultimately it would be interesting to have the data sent back to the remote control module for the vehicle via IR, although I suspect that I will need to get the faster stepper working for that.

When I can upload a photo I'll do so


New Member
Thanks for the code - it will (hopefully) be useful in a project I have planned. I don't know if you need speed, and these are minor points, but ...
        hi2cin [TOF10120],(RangeHighByte,RangeLowByte) ;reads range up to 255mm as RangeLowByte, then increments
                                                       ; RangeHighByte and resets RangeLowByte to 0
        Range=255*RangeHighByte + RangeLowByte
If RangeLowByte (RLB) increments to 255 and then "rolls over", going back to zero and incrementing RangeHighByte (RHB) by 1, a 1 in RHB represents 256, not 255.
In fact, because RLB is b4 and RHB is b5, they are simply counting as the word variable w2. You can therefore either put
Range = w4,
or define the symbols RLB and RHB as the two halves of Range (b20 and b21), and dispense with b4 and b5 altogether


Senior Member
Whitespace: I like it all! Would love to see some pics & videos of your very interesting TOF10120 results.

I'm a huge fan of the S6986. Have you seen Philo's page about using it with a laser? He inspired me to do some stuff sensing reflectors:

Speaking of scanning and displaying the output on a screen, here's another project using a Waveshare laser sensor and "another" processor, could easily be done with a Picaxe too:

More Waveshare laser sensor fun:


Keith Baldwin shared his excellent work on the VL53LOX ToF sensor with a Picaxe at


Senior Member
BTW this PING-DAR ultrasonic project is also quite illuminating, displaying a radar-like display on a monitor.



Well-known member
Thanks @erco I'll certainly share some pictures, although the project is currently misbehaving and not showing a range, and intermittently restarting the Picaxe, so it will be a few days. I suspect that a connection has come loose or got crossed or something. While I check everything I'm taking the opportunity to solder and glue the various parts of the sensor rather than use Blu-Tak and the connectors that the stepper and scanner came with. Hopefully that will fix things. Yes I have seen your posts on the S6986, and it was Philo's project that originally put me on to the sensor. I got it working a little unreliably a few months ago, with the lens out of one of those miniature pen telescopes. The disadvantage of the S6986 is that it only gives a high/low output, whereas the TOF outputs an actual range. Before I got carried away thinking about scanning and outputting to a display, I had started with comparing the TOF range with a variable range set by a pot and readadc. Closer than the pre-set range and it would shut down the motor.


Well-known member
Here you are @erco and anyone else interested - a short YouTube video showing the scanner in action
. I've refined the code quite a lot. The scanner now includes a LED/detector pair at each end limit - the LED on the scanning sensor and the detector fixed to the body, to detect overshoot and apply a correction, and also to allow initialisation if the sensor has been switched off anywhere other than 0 degrees (centre). On starting, it now tracks right until it hits the right stop, then back 60 degrees to the centre, then starts. However, I've just been thinking today that it might be easier with a couple of microswitches. A complete scan (from centre clockwise 60 degrees, then ACW 60 to the centre, then another 60 ACW to far right, then 60 ACW back to centre) takes a little under 5 seconds. It scans on the two clockwise legs. The video shows how quickly it responds to a change in the landscape (a bent piece of cardboard about 20cm in front of the scanner.


I need to experiment a little to see if there is scope for speeding up the scan. The motor I'm currently using does 0.18 degrees per step, which means that I need a cycle of 7 steps (1.26 degrees) per sensor reading. I suspect that slows things down a bit. I have two more stepper motors en route, with 0.9 degrees and 1.25 degrees per step, so I'm hoping that one of them will allow a faster scan. Using the LED/detector combination also adds delay, because there are a few lines of code on each step to check the sensor values and work out whether they are increasing or decreasing, so using microswitches (which will just be on/off) may be quicker.

The next challenge is to transmit the angle/distance data to another Picaxe to display there.

If anyone is working on a similar project and has any suggestions for speeding up the code, I would be interested and grateful to hear them.