ARM Cortex STM32 ECU Software

Engine Control Unit, Feb-2020

I’ve been wanting to expand the code in my ECU for quite a while but, although it’s a brilliant device, I decided the Arduino 2560 is too limited as a basis for future developments – there’s little spare CPU time, it has too few 16-bit timers and insufficient SRAM, for example. I also felt the Arduino IDE is no longer adequate for more complex developments as it lacks a comprehensive debugging capability.

I’ve been really impressed by the STM32 ARM Cortex NUCLEO boards and the CubeMX IDE from ST Microelectronics, so decided this was the way to go for developing the ECU software. I ported (as in completely rewritten) the existing ECU code from the Arduino C++ code into STM32 / CubeMX C code – IMHO C is better for embedded applications than C++. The NUCLEO-F411RE board would have been perfect for the ECU application, but I wanted to stick to the NUCLEO-32 board format (which is a 32 pin device with more limited IO) to ensure the board could fit into an existing ECU, so plumped for the NUCLEO G431KB. Once running on the bench, I did some performance tests to compare with the Arduino. Here’s how the cyclic functions (where the fuel calcs, 3D interpolation, ignition, auto AFR correction, etc are performed) matched up – the execution time is shown for each, in milli-seconds…

Arduino 2560NUCLEO-G431KB

You can see from the data that the G431KB is stonkingly quick and it has just enough IO so that I could implement the full code but limited to paired injectors used in semi-sequential mode. The main ECU board had to be modified for 3.3V operation which involved mainly component changes and a small adapter board was needed to match the NUCLEO-32 pins to the Arduino 2560 format. The NUCLEO-G431KB pinouts are as below:

I made a simple adapter PCB to match the required pins of the NUCLEO G431 board to the Arduino 2560 footprint . This is the 2nd version that includes an external EEPROM for configuration data and AFR data non-volatile storage. The reason for including an external EEPROM is given below. The PCB was made using the “toner transfer” method, that worked very well:

Assembled and ready to install:

After about 250 miles with the STM32 ECU, so far, it’s working really well. The engine starts more easily, idle is more stable and accelerating to high RPM is smoother. The initial STM32 ECU application code is here but watch out for further developments in the coming months.

Change to external EEPROM for Non-Volatile Data Storage

After an initial couple of hundred miles using the STM32 CPU I discovered a significant negative aspect of this CPU compared to Arduino. While driving, the ECU reported a regular and sustained number of trigger wheel sync errors, coupled with an occasional nasty misfire. There’s a facility for the ECU to self-tune the VE Map according to the air-fuel ratio (AFR) measurements as you drive along. The AFR correction data is periodically saved to non-volatile memory (NVM) and restored when the ECU is next switched on. In the STM32, there’s no separate EEPROM as in the Arduino so the NVM is implemented using the main Flash memory. I’ve since discovered that while writing to Flash, programme execution is stalled, hence it can’t keep up with the trigger wheel pulses, resulting in the sync errors. There’s no simple solution to this in software, so I’ve implemented an external I2C EEPROM for version 2 of the STM32 ECU design using the Microchip 24LC256 providing 32Kbytes capacity. This additional NV storage space means there’s scope for further developments, such a multiple configurations.