Multiple airspeed sensors


I have the issue related to this topic. I understand that I cannot connect multiple sensors with same i2c addresses, and seems like I cannot use more than one airspeed sensor (because of calibration issues, and also if I connect two only one appears in the log and among the uORB topics).

Has anyone tried i2c multiplexer to get around this problem? I know I need a custom driver for it, but can it theoretically work? If anyone has any ideas or experience on multiplexers and px4, their help would be much appreciated.

I saw @SalimTerryLi introducing new driver recently for ADS1115, do you know anything of multiplexer (TCA9548A) driver for px4? Is it in work, or are there any source helping to implement it?

/Sorry if you are not the person to ask, in that case do you know who should it be?/

No, at now. PX4 mainly focus on functional drivers, that is, anything which collect and publish sensor data or subscribe to existing topics and do the actual outputting. This kind of multiplexer is a little difficult to be absorbed into PX4 under current architecture.
I mainly works on Linux platform, so my solution would be as simple as a device tree overlay. It provides virtual I2C buses which works out of the box.

It should theoretically work with TCA9548A - you could reuse the existing driver code with very little changes - just add additional configuration params for the number of sensors etc. and invoke the code to select the downstream I2C bus of interest before each measurement. An equivalent example in the Arduino land is as follows:

void tcaselect(uint8_t i) {
  if (i > 7) return;

  _i2c.write(1 << i);

and the rest of the driver code could stay the same. This is the simplest case where you’d want to inspect/dump the data into a log.

In order to be able to do something more meaningful with the data from multiple sensors you’d have to make more modifications to the driver, and perhaps QGC as well since as you said currently only one measurement is captured/displayed = supported.

What are you using multiple airspeed sensors for?

Thanks for all the inputs @SalimTerryLi and @adzio !

I am actually trying to copy an Arduino driver (has this same tcaselect() method, might be from the same source), with not much success so far, the driver just simply doesn’t start without any error message. But I will try to proceed this way I think, as I basically don’t have knowledge on device trees, and also I am using PX4 on NuttX platform (not sure how much difference it makes, though).

I mean that this kind of multiplexing function should come from OS side. The best solution would be adding more logical I2C buses on Nuttx, then let PX4 executes multiple driver instances. PX4 now supports multiple instances of the same driver with different address or bus so you may want to dig into Nuttx and see whether it is possible. This is the most practical solution under Linux. If you try to directly modify existing drivers, you may face much more problems and your work won’t become a long term solution.

@SalimTerryLi in his case the airspeed sensors all have the same I2C address and it can’t be changed. The multiplexing solution is simpler (just a few lines of driver code change to read the data) and relieves the FMU and the OS from dealing with the extra I2C traffic, which blocks the bus (or buses as you’re suggesting).

We were able to work it out (at least partially) without multiplexer.
SDP3X sensors has changeable i2c address with resistor soldered to them. Tricky thing is that PX4 does not see the sensors automatically (not even with i2cdetect) if they have not-default address. But if you start the sdp3x driver with correct bus and address option, it actually finds it and logs differential pressure data from it. So with this method it is possible to use 6 sdp3x sensors (3 on both bus, as there is 3 possible address setting).
However you still only have one airspeed instance, but if needed you can figure out all airspeed data from the differential pressure log. Also, the sensor that is used to calculate airspeed in the firmware is the first one whose driver is started at boot.
Probably this is the solution that needs the smallest amount of change in the code, though still far from perfect.