ESP32 S2 S3 C3 Time of flight Wifi positioning

I have noticed that there is a feature in some esp32 versions that support time of flight wifi positioning, Has anyone ever used something like this before? it would be a very cheap alternative to the other systems out there at the moment like pozxy.

My understanding is that it can measure the distance to any access point that supports Wi-Fi Round Trip Time (Wi-Fi RTT) so it could even work in wifi dense environments without extra hardware. or esp32s can be used as responders

1 Like

got the Arduino example running on a pair of esp32 S2 mini boards and the results are ok, I have it set on the floor at 4m, its not terribly accurate at 4 meters but if it can hold ±1m over several hundred meters then it could still be useful.

It also seems to have a strange bug where it offline after a while, im going to try it with an esp32 C3 and see if it does the same.

FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.29 m, Return Time: 28 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.68 m, Return Time: 31 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.68 m, Return Time: 31 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.29 m, Return Time: 28 ns
FTM Estimate: Distance: 4.29 m, Return Time: 28 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.68 m, Return Time: 31 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.42 m, Return Time: 29 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns
FTM Estimate: Distance: 4.55 m, Return Time: 30 ns

I have made a test program that converts it into a i2c rangefinder for ardupilot.

2 Likes

hi @geofrancis, thanks for this repo. Do you directly communicate with the FCU without Mavlink?

Its using i2c as i was just testing it as a single range sensor. the bug in the espresiff example was just because its running in setup so any disruption stopped it, moving it to loop fixed it.

Interesting that it works so well for you. I tried it with an ESP32 S3 which should also be supported according to this page: esp-idf/examples/wifi/ftm/README.md at master · espressif/esp-idf · GitHub

Although it could be that it hasn’t been ported to Arduino yet… It kinda works, but I have a nearly constant offset of 40m and my return time is at least 260ns. What exact boards did you use? Because I’m thinking about ordering some if there is a chance. Always wanted to build a cheap indoor localization system, maybe it is about time…

I used S2 boards for testing but I’m sure I also tried a C3 board. I cant remember it was a while ago now.

Sorry to bring it up again, but I’m astounded by your measurements. I ordered two S2 and two C3 boards and performed ten measurements every half meter, starting from 0.5m to 3.5m. Always line of sight and every possible combination. And the results are nowhere close to the actual distance:


I’m not sure about the S2 measurements, my board seemed dead once I wanted to make the measurements for Host C3 and Init S2…
At least the trendline is always pointing in the right direction, but apart from that, I don’t see how the data would be usable without post processing, which contradicts your experience… Or did you change anything?

Used S3 board: https://vi.aliexpress.com/item/1005006266375800.html
Used S2 board: https://vi.aliexpress.com/item/1005006157693055.html
Used C3 board: https://vi.aliexpress.com/item/1005006170575141.html

1 Like

I just flashed a pair of s2 boards the same as you linked to, i can only get it to accurately range with the antennas in specific orientations when i move them around it starts to fluctuate so im not sure if its a polarisation issue other wifi routers close by might also be effecting it.

I have been trying to think back and im sure it was more stable than this recent test, try changing:

// FTM settings
// Number of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0 (No pref), 16, 24, 32, 64)
const uint8_t FTM_FRAME_COUNT = 16;
// Requested time period between consecutive FTM bursts in 100’s of milliseconds (allowed values - 0 (No pref) or 2-255)
const uint16_t FTM_BURST_PERIOD = 2;