I2C implementation in Pixhawk HAL

3,309 views
Skip to first unread message

Francis Vierboom

unread,
Feb 17, 2014, 11:34:29 PM2/17/14
to drones-...@googlegroups.com
Hi all

Currently working on trying to get a Wii IR Camera to talk to the Pixhawk via the i2c connection (sensor which outputs the X,Y and intesity of four infra-red light sources in its FOV). Had it working on an Arduino board, and tried adding it as a new sensor with similar i2c code to the AP_Compass_HMC5843 i2c code. Spent two days but could get no sign of life - or even any errors - from calling the hal.i2c->readRegisters etc commands. Just zeros. 

After getting down to the wires with an oscilloscope, we finally realised that the Pixhawk does not have I2C implemented in the libraries/AP_HAL_PX4 code and the only hal.i2c methods compiled in the px4 build are the AP_HAL_Empty stub classes (at https://github.com/diydrones/ardupilot/blob/master/libraries/AP_HAL_Empty/I2CDriver.cpp). Which explained a lot! 

The PX4 compass is using AP_Compass_PX4 (derrr) which is using ioctl calls through to /dev/mag using a dedicated driver within the PX4Firmware stack that only then uses the NuttX i2c implementation.

Tridge, I can see you've been working on the Linux implementation from the notes at http://uav.tridgell.net/LCA2014/AP_Linux.pdf - but you skipped the I2C slide explanation in the video :). The presentation notes that there are some latency issues with the default I2C driver, although these are unlikely to affect this sensor which we only need at 20Hz or so.

Is the PX4/Nuttx implementation likely to be very similar to the Linux interface? Is it worth trying to implement an I2CDriver in AP_HAL_PX4 - would cutting over most of the code from AP_HAL_Linux/I2CDriver work?? I have briefly attempted this but the __s32 type and I2C_SMBUS constants used in that one seem to be in the linux-only i2c-dev.h, so I thought I would ask the community for any tips before really heading down the rabbit hole.

Have I even understood this correctly? Is there a different approach I should be taking? Was mildly surprised to find the PX4 I2C driver is unimplemented in the HAL_PX4. It's all a bit new to me, so please feel free to set me straight on anything here!

Thanks - Francis

Meier Lorenz

unread,
Feb 18, 2014, 2:11:48 AM2/18/14
to <drones-discuss@googlegroups.com> <drones-discuss@googlegroups.com>
Hi Francis,

I2C is a darn slow protocol and going through several abstraction layers trying to directly do it from the application layer will always be very inefficient and potentially block the flight code from executing while the I2C transfers run, if not done right.
If you do an user level driver ‚right‘ to not block during the transfer, you would implement this as a work queue entry running in parallel, but it would be still inefficient as you keep switching context for single bytes - operating systems want chunks and not flick between taks just for microseconds.

You are potentially better off writing a ‚real‘ driver for your device for each platform you are interested in. This allows you leverage all the efficiency and special features each platform offers and to adapt the I2C-facing code to the hardware layer you are using.

This would mean to write a driver based on e.g. this:
https://github.com/PX4/Firmware/blob/master/src/drivers/hmc5883/hmc5883.cpp

For PX4 and then do a Linux driver, adapted to Linux, once you need it.

As a side effect this would get you proper multithreading pub sub support for your driver data on PX4.

Cheers,
Lorenz

------------------------------------------------------
Lorenz Meier
Computer Vision and Geometry Group
Institute for Visual Computing
ETH Zurich
http://www.inf.ethz.ch/personal/lomeier/
--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com<mailto:drones-discus...@googlegroups.com>.
For more options, visit https://groups.google.com/groups/opt_out.

Jon Verbeke

unread,
Sep 16, 2014, 3:40:40 AM9/16/14
to drones-...@googlegroups.com
Hi Lorenz,

I think we have a similar problem. We implemented collision avoidance on a small quadcopter using an apm2.5 and 5 ultrasonic sensors and 1 infrared sensor. These 5 ultrasonic sensors were controlled though two i2c boards. The Sparkfun PCF8575 I2C expander was used for firing the ultrasonic sensors while a while the Gravitech I2C-ADC
7828 was used for reading the ultrasonic sensors' data. We got this working perfectly on the APM, but now we are trying to add it to the Pixhawk as we want to implement more advanced navigation algorithmes for which the APM is too slow. The problem is that we cannot get it to work. As soon as you add power to the boards all the ultrasonic sensors start firing, which is normal, but in the first part of our Usercode we try to write a do not fire command to the expander board and even this will not work.

Some pieces of code:

Initialisation:
#define PCF8575 0x20 //expander
#define ADS7828 0x48 //ADC
I2c.setSpeed(false); // low I2c speed for reading sensors
I2c.write(PCF8575,0x00,0x00);// Stop all sensors from firing!!!
AP_AnalogSource_Arduino adc_source5(A8); // port to read infrared sensor
AP_RangeFinder_SharpGP2Y IR(&adc_source5, &mode_filterIR); // infraredsensor
#define SONAR_TYPE2 AP_RANGEFINDER_MAXSONARLV      // 1 - LV (cheaper)
const int DAT[5] = {196,148,212,164,0x84};//i2c numbers to  fire ultrasonic sensors
const int ZEND[5] = {4,8,16,2,1};//i2c numbers to read ultrasonic sensors

@ runningtime:
infrarood = IR.read()*temp;
I2c.write(PCF8575,1,0x00);
I2c.read(ADS7828,DAT[4],2); //read sonar 5

I suspect we will have to write a driver as well for the PX4Firmware. Am I correct in this?
And also, you speak of a linux driver. Have you got an example for this as well?

Kind regards,

Jon Verbeke



Op dinsdag 18 februari 2014 08:11:48 UTC+1 schreef Lorenz Meier:
Hi Francis,

I2C is a darn slow protocol and going through several abstraction layers trying to directly do it from the application layer will always be very inefficient and potentially block the flight code from executing while the I2C transfers run, if not done right.
If you do an user level driver ‚right‘ to not block during the transfer, you would implement this as a work queue entry running in parallel, but it would be still inefficient as you keep switching context for single bytes - operating systems want chunks and not flick between taks just for microseconds.

You are potentially better off writing a ‚real‘ driver for your device for each platform you are interested in. This allows you leverage all the efficiency and special features each platform offers and to adapt the I2C-facing code to the hardware layer you are using.

This would mean to write a driver based on e.g. this:
https://github.com/PX4/Firmware/blob/master/src/drivers/hmc5883/hmc5883.cpp

For PX4 and then do a Linux driver, adapted to Linux, once you need it.

As a side effect this would get you proper multithreading pub sub support for your driver data on PX4.

Cheers,
Lorenz

------------------------------------------------------
Lorenz Meier
Computer Vision and Geometry Group
Institute for Visual Computing
ETH Zurich
http://www.inf.ethz.ch/personal/lomeier/

Am 18.02.2014 um 05:34 schrieb Francis Vierboom:

Hi all

Currently working on trying to get a Wii IR Camera to talk to the Pixhawk via the i2c connection (sensor which outputs the X,Y and intesity of four infra-red light sources in its FOV). Had it working on an Arduino board, and tried adding it as a new sensor with similar i2c code to the AP_Compass_HMC5843 i2c code. Spent two days but could get no sign of life - or even any errors - from calling the hal.i2c->readRegisters etc commands. Just zeros.

After getting down to the wires with an oscilloscope, we finally realised that the Pixhawk does not have I2C implemented in the libraries/AP_HAL_PX4 code and the only hal.i2c methods compiled in the px4 build are the AP_HAL_Empty stub classes (at https://github.com/diydrones/ardupilot/blob/master/libraries/AP_HAL_Empty/I2CDriver.cpp). Which explained a lot!

The PX4 compass is using AP_Compass_PX4 (derrr) which is using ioctl calls through to /dev/mag using a dedicated driver within the PX4Firmware stack that only then uses the NuttX i2c implementation.

Tridge, I can see you've been working on the Linux implementation from the notes at http://uav.tridgell.net/LCA2014/AP_Linux.pdf - but you skipped the I2C slide explanation in the video :). The presentation notes that there are some latency issues with the default I2C driver, although these are unlikely to affect this sensor which we only need at 20Hz or so.

Is the PX4/Nuttx implementation likely to be very similar to the Linux interface? Is it worth trying to implement an I2CDriver in AP_HAL_PX4 - would cutting over most of the code from AP_HAL_Linux/I2CDriver work?? I have briefly attempted this but the __s32 type and I2C_SMBUS constants used in that one seem to be in the linux-only i2c-dev.h, so I thought I would ask the community for any tips before really heading down the rabbit hole.

Have I even understood this correctly? Is there a different approach I should be taking? Was mildly surprised to find the PX4 I2C driver is unimplemented in the HAL_PX4. It's all a bit new to me, so please feel free to set me straight on anything here!

Thanks - Francis


--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com<mailto:drones-discuss+unsubscribe@googlegroups.com>.

Manu Barret

unread,
Jul 28, 2015, 12:05:26 PM7/28/15
to drones-discuss, j.g.r....@gmail.com
Hi all,
We were using i2c sensors on APM 2.6 with no issue, and now we cannot make them run with pixhawk. Did you find any solution or clue on a possible missing I2C driver for pixhawk?

Regards,
Manu
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com<mailto:drones-discus...@googlegroups.com>.

Jon Verbeke

unread,
Aug 5, 2015, 5:05:44 AM8/5/15
to drones-discuss, j.g.r....@gmail.com
Hi Manu,

We wrote a new driver that can handle multiple i2c sonars and uploaded it to the PX4/Firmware repository of which ardupilot is forked.
It's not yet implemented in the ardupilot fork yet, as far as I know.
You could do this your self based on the one in the PX4/firmware repository:

https://github.com/PX4/Firmware/tree/master/src/drivers/mb12xx

Cheers,

Jon

Op dinsdag 28 juli 2015 18:05:26 UTC+2 schreef Manu Barret:

Tom Pittenger

unread,
Aug 5, 2015, 7:41:38 AM8/5/15
to drones-discuss, j.g.r....@gmail.com

Sounds like we need to update our fork!

--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Message has been deleted

איתי גיא

unread,
Aug 5, 2015, 1:07:02 PM8/5/15
to drones-discuss
Hi Lorenz,

Can you please elaborate some more on how to implement new driver ,and on the workflow of between the device , through the nuttx , firmware , and hal . 

best 

Itay

On Tuesday, February 18, 2014 at 9:11:48 AM UTC+2, Lorenz Meier wrote:
Hi Francis,

I2C is a darn slow protocol and going through several abstraction layers trying to directly do it from the application layer will always be very inefficient and potentially block the flight code from executing while the I2C transfers run, if not done right.
If you do an user level driver ‚right‘ to not block during the transfer, you would implement this as a work queue entry running in parallel, but it would be still inefficient as you keep switching context for single bytes - operating systems want chunks and not flick between taks just for microseconds.

You are potentially better off writing a ‚real‘ driver for your device for each platform you are interested in. This allows you leverage all the efficiency and special features each platform offers and to adapt the I2C-facing code to the hardware layer you are using.

This would mean to write a driver based on e.g. this:
https://github.com/PX4/Firmware/blob/master/src/drivers/hmc5883/hmc5883.cpp

For PX4 and then do a Linux driver, adapted to Linux, once you need it.

As a side effect this would get you proper multithreading pub sub support for your driver data on PX4.

Cheers,
Lorenz

------------------------------------------------------
Lorenz Meier
Computer Vision and Geometry Group
Institute for Visual Computing
ETH Zurich
http://www.inf.ethz.ch/personal/lomeier/

Am 18.02.2014 um 05:34 schrieb Francis Vierboom <fra...@flirtey.com<mailto:fran...@flirtey.com>>:

Hi all

Currently working on trying to get a Wii IR Camera to talk to the Pixhawk via the i2c connection (sensor which outputs the X,Y and intesity of four infra-red light sources in its FOV). Had it working on an Arduino board, and tried adding it as a new sensor with similar i2c code to the AP_Compass_HMC5843 i2c code. Spent two days but could get no sign of life - or even any errors - from calling the hal.i2c->readRegisters etc commands. Just zeros.

After getting down to the wires with an oscilloscope, we finally realised that the Pixhawk does not have I2C implemented in the libraries/AP_HAL_PX4 code and the only hal.i2c methods compiled in the px4 build are the AP_HAL_Empty stub classes (at https://github.com/diydrones/ardupilot/blob/master/libraries/AP_HAL_Empty/I2CDriver.cpp). Which explained a lot!

The PX4 compass is using AP_Compass_PX4 (derrr) which is using ioctl calls through to /dev/mag using a dedicated driver within the PX4Firmware stack that only then uses the NuttX i2c implementation.

Tridge, I can see you've been working on the Linux implementation from the notes at http://uav.tridgell.net/LCA2014/AP_Linux.pdf - but you skipped the I2C slide explanation in the video :). The presentation notes that there are some latency issues with the default I2C driver, although these are unlikely to affect this sensor which we only need at 20Hz or so.

Is the PX4/Nuttx implementation likely to be very similar to the Linux interface? Is it worth trying to implement an I2CDriver in AP_HAL_PX4 - would cutting over most of the code from AP_HAL_Linux/I2CDriver work?? I have briefly attempted this but the __s32 type and I2C_SMBUS constants used in that one seem to be in the linux-only i2c-dev.h, so I thought I would ask the community for any tips before really heading down the rabbit hole.

Have I even understood this correctly? Is there a different approach I should be taking? Was mildly surprised to find the PX4 I2C driver is unimplemented in the HAL_PX4. It's all a bit new to me, so please feel free to set me straight on anything here!

Thanks - Francis


--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com<mailto:drones-discuss+unsubscribe@googlegroups.com>.

Randy Mackay

unread,
Aug 5, 2015, 8:19:23 PM8/5/15
to drones-...@googlegroups.com

 

    Yes, we’ve always implemented this kind of thing as Lorenz describes.

1.       A PX4Firmware layer driver that pulls data from the sensor at regular intervals.   Here’s one I did for the smart battery: https://github.com/diydrones/PX4Firmware/blob/master/src/drivers/batt_smbus/batt_smbus.cpp

2.       The above driver makes the data available by publishing to the Orb, an IOCTL call or via a read function  (sometimes we use multiple of these methods)

3.       Write an ardupilot driver to pull the data from the above PX4 driver.  Here’s the one for the smart battery:

a.       https://github.com/diydrones/ardupilot/blob/master/libraries/AP_BattMonitor/AP_BattMonitor_SMBus_PX4.h

b.      https://github.com/diydrones/ardupilot/blob/master/libraries/AP_BattMonitor/AP_BattMonitor_SMBus_PX4.cpp

4.       Call the ardupilot driver from the main ardupilot vehicle code

 

     By the way, what you’re doing sounds a lot like the IRLock work.  Maybe you’re planning to make the vehicle hold position or land based on the output of the sensor?   https://www.youtube.com/watch?v=2z14S_a6bNk

 

     The IRLock stuff is not yet integrated into master (although the IRLock driver is in the PX4Firmware layer) because of the AC3.3 delays but it’ll go in some time in the next month or so.

 

-Randy

Am 18.02.2014 um 05:34 schrieb Francis Vierboom <fra...@flirtey.com<mailto:fra...@flirtey.com>>:

Hi all

Currently working on trying to get a Wii IR Camera to talk to the Pixhawk via the i2c connection (sensor which outputs the X,Y and intesity of four infra-red light sources in its FOV). Had it working on an Arduino board, and tried adding it as a new sensor with similar i2c code to the AP_Compass_HMC5843 i2c code. Spent two days but could get no sign of life - or even any errors - from calling the hal.i2c->readRegisters etc commands. Just zeros.

After getting down to the wires with an oscilloscope, we finally realised that the Pixhawk does not have I2C implemented in the libraries/AP_HAL_PX4 code and the only hal.i2c methods compiled in the px4 build are the AP_HAL_Empty stub classes (at https://github.com/diydrones/ardupilot/blob/master/libraries/AP_HAL_Empty/I2CDriver.cpp). Which explained a lot!

The PX4 compass is using AP_Compass_PX4 (derrr) which is using ioctl calls through to /dev/mag using a dedicated driver within the PX4Firmware stack that only then uses the NuttX i2c implementation.

Tridge, I can see you've been working on the Linux implementation from the notes at http://uav.tridgell.net/LCA2014/AP_Linux.pdf - but you skipped the I2C slide explanation in the video :). The presentation notes that there are some latency issues with the default I2C driver, although these are unlikely to affect this sensor which we only need at 20Hz or so.

Is the PX4/Nuttx implementation likely to be very similar to the Linux interface? Is it worth trying to implement an I2CDriver in AP_HAL_PX4 - would cutting over most of the code from AP_HAL_Linux/I2CDriver work?? I have briefly attempted this but the __s32 type and I2C_SMBUS constants used in that one seem to be in the linux-only i2c-dev.h, so I thought I would ask the community for any tips before really heading down the rabbit hole.

Have I even understood this correctly? Is there a different approach I should be taking? Was mildly surprised to find the PX4 I2C driver is unimplemented in the HAL_PX4. It's all a bit new to me, so please feel free to set me straight on anything here!

Thanks - Francis


--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.

To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com<mailto:drones-discus...@googlegroups.com>.

--

You received this message because you are subscribed to the Google Groups "drones-discuss" group.

To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Zaborowski

unread,
Aug 6, 2015, 5:49:13 AM8/6/15
to drones-...@googlegroups.com
A generic I2C HAL support, possibly backed by a custom kernel driver,
would also be useful though. In many cases, with sensors or ESCs, you
only need a single I2C transfer at a time. When done correctly it'll
translate to a single context-switch or syscall whether you use a
specific or a generic i2C driver. In that case the additional effort
is not justified.

In fact, depending on the details the userspace interface it may be
slower to have a kernel driver digest the sensor data if it's exposed
through multiple small /proc or /sys files, or if it polls the sensor
at a higher rate than needed.

Best regards

On 6 August 2015 at 02:19, 'Randy Mackay' via drones-discuss

J.R.

unread,
Sep 12, 2015, 10:53:20 AM9/12/15
to drones-discuss
Hi all,

i am currently working on a i2c driver for pixhawk to read data from an external board.
I used the hmc5883 and mb12xx as guiding examples.
everything is compiling fine but when i try to write data to the external board the pixhawk returns "i2c::transfer returned -6" to nsh.

is this problem familiar to anyone?

Thanks in advance!

vittorio radalli

unread,
Oct 16, 2016, 8:43:39 AM10/16/16
to drones-discuss
hi all,
 sorry for basic question but i'm a beginner.
how can i include hmc5883.h library? every trial was a compile error (file not found or compile error).
Maybe i need to modify some make/cmake file to include but i don't know how.
thank you for your help
Vittorio

vittorio radalli

unread,
Oct 18, 2016, 2:16:37 PM10/18/16
to drones-discuss
hi all,
 some news.
I was able to import the library but i have compile error
/home/xxx/src/Firmware/src/drivers/hmc5883/hmc5883.h:51:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
 extern device::Device *HMC5883_SPI_interface(int bus);

why? how to fix?


thank you for your help


Reply all
Reply to author
Forward
0 new messages