Ardupilot Linux Based System — STM32 as a Breakout Module Part #2

Mohammad Hefny
5 min readMar 6, 2023

In this article I am going to build on what I wrote in my previous article. I have continued to explore the ability of STM32 as a slave I2C breakout.

Vision

As I am getting more deeper into this project I have started to get clearer view of what this enables me to do. I can list this in the following items:

1- To convert interfaces that were previously requires GPIO to I2C or SPI based interface, such as RCInput & RCOutput functions, as well as GPIO for LEDS.
2- Enable functions that were not available on RPI, such as DShot output.
3- Being independent on GPIO & DMA of RPI which enables you to run Ardupilot on other boards with minor or no modification at all.

OBAL-GY91 version (100% open source)

Being able to replace breakouts into I2C & SPI controller components will lead to convert OBAL to become The Board of All Boards i.e. you can use OBAL as a hat for RaspberryPI, BananaPI, OrangePI and more. Because once you no longer need to access GPI and DMA your code is independent of the board.

What is New ?

The new part is that I have replaced ADC (ADS1115) breakout with STM32, and moved the function of reading RCInput from RPI to STM32.

The below diagram shows STM32 replaced the OBAL ADC & PCA9685 breakout modules as well as the RC_Input function that was implemented before using DMA on RPI.

Current Functions Replaced by STM32

Now my BlackPillV2 is capable or performing three functions, and with high flexibility.

RCOUT_I2C — this module generates signal for ESC using different protocols adjusted from Ardupilot parameters. The module is capable of controlling 8 motors with refresh rate up to 400Hz. This module is discussed in details in the first article, however minor updates have been implemented.

PCA9685 is no longer needed in OBAL-STM32

ADS_I2C — this module uses ADC pins in STM32 to read voltage. This provides analog pins for Ardupilot for batteries current and ampere and other sensors that use analog voltage as an output. I am no longer using ADS-1115 for ADC anymore.

ADS1115 replaced by STM32

RCINPUT_I2C — this modules replaces RCInput_RPI driver. Class RCInput_RPI driver is very specific to Raspberry PI, while the new module is called via I2C, and can be used by any Linux based board easily. Also the module shows much more stable input signal that the original RPI driver.

RCInput using STM32 Signal Stability.

Actually in the video you will see some crosstalk between rudder and throttle and between roll and pitch but this is because my hand as I am using TX mode-2, but if you just leave the sticks it is very stable.

STM32-Pinout

BlackPillV2 Pinout

There are many pinout varieties one can use. This is the beauty of this solution you can assign different functions to the same pin based on your needs. For example here I am flying a quadcopter so I need only four motors, and RC-in of 6-CH in pwm. I could have used a PPM and would have increase the number of motors if I had wanted to. This is only matter of settings you need to write in a single file.

Now lets us discuss the current design. I use STM32 here to emulate three device ADC, RCOut & RCInput. Each device is attached to its own I2C bus, and has its own address as you can see in the following image.

I2C Addresses of STM32 Modules

The I2C addresses are defined in target.h:

As you can see changing the addresses and even having a secondary I2C is a piece of cake. Adderess 0x77 is for an external baro.

I2C Registers

RCOUT_I2C

RCOUT_I2C Registers

Almost the same as in the previous article but I added the ability to write a word when feeding motors to save unnecessary cycles. Also added 0xFC to get number of available motors.

Ardupilot driver code is here. It is a typical I2C driver very easy to understand.

STM32 Library code is here.

ADS_I2C

ADS_I2C Register

Ardupilot driver code is here. Notice that ADC can be used in connecting wind sensor not only as a voltmeter or ammeter.

STM32 library code is here.

RCINPUT_I2C

RCINPUT_I2C

Ardupilot driver code is here.

STM32 Library code is here.

Flying with STM32 as RC-INPUT, RC-OUTPUT and ADC

This is the very first flight of the board.

All Source code and Resources

1- OBAL board: https://ardupilot.org/copter/docs/common-obal-overview.html. Full Wiki including PCB gerber file and all installation instructions are in https://github.com/HefnySco/OBAL/wiki

2- Ardupilot with STM32 drivers: https://github.com/HefnySco/ardupilot/tree/pr_obal_stm32_adc_rcinout branch: pr_obal_stm32_adc_rcinout

3- STM32 library code: https://github.com/HefnySco/betaflight/tree/pr_obal_rcout_adc_rx
branch: pr_obal_rcout_adc_rx
Important: I am not using any betaflight based flight controller logic. I use it as a framework for accessing devices only from STM32. All flight control logic is Ardupilot only.

git clone https://github.com/HefnySco/betaflight.git
git checkout pr_obal_rcout_adc_rx
make OBAL_RCOUT

Now you can use STM32CubeProgrammer to download code on BlackPill.

--

--