This is an old revision of the document!


Engine Control Unit for Formula Student

Author: Timotei-Iosif Cicu

Introduction

This is an on-going project that I have been working since the the 30th of October 2025. The following sections represent the documentation I have made along the way for the V-Cycle of the whole system, branching into the V-Cycle for Hardware and V-Cycle for Software

ECU as a Concept

Background and Context

I am a member of UPB Drive, our university's Formula Student team. We are currently using an ECU from ECUMaster (ECUMaster Black), however this ECU is very expensive and we are required to re-use the same ECU each year, thus making last year’s vehicle inoperable. In addition to this problem, I want to make my bachelor thesis project about this subject.

Our ECU line will be called TimoECU and the first revision is called “TimoECU TimoUnu”, so that by the third revision it will be called “TimoECU TimoTrei”

Our team and DR-06 car at FSBalkans2025

Target Audience and Beneficiaries

The first target audience for this product is our Formula Student team, but this product could be sold to other Formula Student teams, as well as hobbyists looking for a cheap alternative for projects that don’t require all the features available in aftermarket ECUs.

ECU definition

An Engine Control Unit (ECU) is the brain of the car an electronic system meant to control an internal combustion engine. It takes inputs from engine sensors and then actuates the injectors, spark plugs, and cooling fans for optimal control of the engine.

The roles of my ECU are as follow:

  • Monitor engine sensors
  • Injection control (multipoint injection)
  • Ignition control
  • Fan control
  • Monitor CAN stream
  • Send CAN messages with engine parameters
  • Have shift-cut control
  • Have launch control
  • Stop the engine if unsafe conditions arise
  • Be adaptable to multiple engine types (1 and 4 cylinder)
  • Be able to customize engine parameters via a graphical user interface while the engine is running, or at the very least via a configuration file; and provide real-time data through the GUI
  • Have onboard storage for its parameters and be able to log data on this onboard storage
  • The system must be able to operate under harsh conditions
  • Have auxiliary analog inputs with overvoltage protection
  • Be cheaper than our current ECUMaster solution

The engine sensors that are needed to be monitored are:

  • Crank and cam sensors
  • MAP
  • TPS
  • Fuel pressure sensor
  • IAT
  • Coolant temperature
  • Oil temperature and pressure
  • Lambda (via external lambda controller)
  • Battery voltage
  • Vehicle speed sensor
  • Knock sensor (optional)

Market Analysis

In this section I compare what I had set out to achieve with two common ECUs available for purchase.

- TimoECU TimoUnu ECUMaster Black LinksECU G5
Engine Support 1 to 4 cylinders at >13000 RPM Up to 12 cylinders Up to 12 cylinders
Injection outputs 4 8 12
Ignition outputs 4 6 16
Analog inputs 12 (12-bit) 9 (10-bit) 14
Launch control yes yes yes
Shift cut yes yes yes
Digital inputs Analog inputs can be used as digital 10
CAN 1 1 2
Data logging Via CAN and onboard storage Via CAN yes
Lambda External controller (CAN or Analog) 1 internal and 1 external controller 2
Knock sensor yes yes yes
Tuning software yes yes yes
Price ? 1128 Euro 2901 Euro

Hardware Requirements

This part outlines the requirements for the TimoECU TimoUnu:

  • the injectors and spark plugs functioning principle, current draw, and actuating frequency
  • the crank and cam sensors signal
  • analog sensor types of the vehicle
  • the lambda sensor
  • the vehicle speed sensor
  • the current draw of the cooling fans
  • the CAN bus specifications
  • the working principle of launch control
  • shift-cut and rpm limit
  • configuration and data logging
  • microcontroller specifications
  • preliminary block diagram
  • integrated cooling for mosfets

Our Engine

The engine used on our Formula Student car is a CBR600F4i from Honda. It idles around 2000 RPM and has a rev limit of 13000 RPM.

Oscilloscope image showing

  • Ch1: The cam signal
  • Ch2: The crank signal
  • Ch3: The current draw of the injector on cylinder 1
  • Ch4: The current draw of the spark plug on cylinder 1

Injectors and Spark plugs

The injectors and spark plugs are actuated at 12V and actuating them is done by drawing the line to GND via a mosfet. For simplicity of implementation, I will use the same mosfet type for both. 8 identical blocks will be used for both the injectors and the spark plugs.

We tested the current draw and the frequency of the injectors and spark plugs using an oscilloscope with current probes. From our tests we determined that:

  • The current draw for
    • The injectors is a maximum of 2 Amps, recommended mosfet specs: 3 Amps
    • The spark plugs is a maximum of 12 Amps, recommended mosfet specs: 15 Amps
  • The actuating frequency of both is 15Hz at idle and 55Hz at red-line
  • The output stays on for (at idle) from the start of rising of the signal until the signal stops
    • Injectors: 4.94ms
    • Spark plugs: 3.34ms

Resulting mosfet specifications:

  • Propagation time: below 33.4uS
  • Maximum current: above 15 Amps

Resulting microcontroller specifications for injectors and spark plugs:

  • 8 digital outputs
  • 8 timers with a resolution of below 3.34uS with a frequency of at least 300kHz and 11 bits

Crank and Cam

The crank sensor was measured using an oscilloscope.

Flywheel:

  • 12 teeth
  • No missing teeth

Sensor output:

  • Hall effect sensor
  • VR signal
  • Pk-Pk: 35V centered at 0
  • Frequency at idle: 467.1Hz
    • Due to the 12 teeth per revolution ⇒ at 13000 RPM ⇒ 156000 pulses per minute ⇒ 2600 pulses per second
  • Used to calculate the RPM

ECU input circuit:

  • Passive components scale and translate the signal into the 0…5V range, later read by an ADC
  • A comparator transforms the VR signal into a square wave signal in the range 0…5V used for interrupts

The cam sensor was measured using an oscilloscope.

Cam sensor wheel:

  • 1 BDC
  • 1 TDC
  • 1 15*BTDC

Sensor output:

  • Hall effect sensor
  • VR signal
  • Pk-Pk: 15V
  • Frequency at idle: 38.834Hz
    • Due to 3 teeth and 2:1 reduction ratio ⇒ at 13000 RPM ⇒ 19500 pulses per minute ⇒ 325 pulses per second
  • Used for timing

ECU input circuit (same circuit as the crank circuit):

  • Passive components scale and translate the signal into the 0…5V range, later read by an ADC
  • A comparator transforms the VR signal into a square wave signal in the range 0…5V used for interrupts

Resulting comparator specifications:

  • VR signal maximum frequency 2600
    • then the period of the VR signal is 384.6uS
    • the square wave period should be half of this, so 173uS
    • the propagation time of the comparator should be below 1% of this, so less than 1.73uS

Resulting microcontroller requirements for crank and cam:

  • More than 2925 interrupts per second
  • Interrupt queue
  • Interrupt controller with priorities
  • 2 timers with a resolution smaller than 1.73uS, frequency above 600kHz, and at least 11 bits
  • 2 ADC inputs to monitor the VR signal after conditioning

Analog sensors

All the analog sensors on the engine work the 0 to 5 voltage range. Below is a description of each sensor:

  • MAP
    • The ECU should have an on-board MAP sensor and support an external one aswell
  • TPS
    • Three wire sensor
  • Fuel pressure sensor
    • Two wire sensor
    • Needs pull-up in-series resistor
  • IAT
    • Two wire-sensor
    • Needs pull-up in-series resistor
  • Coolant temperature
    • Two wire sensor
    • Needs pull-up in-series resistor of 3 to 4kOhm
  • Oil temperature and pressure
    • Combined sensor.
    • Four wires
    • Doesn’t need in-series resistor
  • Battery voltage
    • Measured through a voltage divider

As specified in the concept definition document, besides these analog inputs, the ECU should have 4 additional programmable analog inputs. These additional inputs should have an in-series resistor that can be enabled or disabled via a dip-switch.

The resulting microcontroller requirements are:

  • 12 more ADC inputs

Lambda sensor

For ease of implementation, an external lambda controller will be used. We have available:

  • a LAMBDA2CAN module from ECUMaster

The specification of which can be found in its datasheet

The resulting microcontroller requirements or an external lambda controller are:

  • CAN controller

Vehicle speed sensor

  • Square wave
  • 0 to 5V
  • Frequency of a maximum of 2kHz (chatgpt)
  • Used to calculate the speed of the car

The resulting microcontroller requirements are:

  • 2000 more interrupts per second
  • 1 additional timer (specifications mentioned for the crank and cam timers are sufficient)

Cooling Fans and other outputs

Cooling fan specifications:

  • 12V
  • Current draw (total): 14.8 Amps, max 20.8 Amps

Actuating them is done through a mosfet. The chosen mosfet should be able to support more than 16 Amps.

Auxiliary digital outputs will have the same specifications. In the concept definition document, I have outlined that I want 3 auxiliary programmable outputs.

Resulting microcontroller requirements for cooling fans and auxiliary outputs:

  • 3 more digital outputs

CAN

The CAN network of our Formula Student car works at a baud rate of 500 kbps and has doesn’t use extended identifiers. Our previous ECU could send and decode custom CAN packets, so our custom ECU solution should do the same. It is recommended that the microcontroller chosen should have an internal CAN controller.

For the programmable CAN packets, another timer is needed to be able to send these packets at a specified time interval.

A terminator resistor will be able to be activated or deactivated using an on-board dip-switch

Launch Control

A launch control system is used with an enable/disable switch. When the vehicle is stopped and the accelerator fully pressed, the revs are limited so that the engine is in the power-band. When the car has started moving, the system monitors the vehicle speed sensor and might cut fuel/spark to prevent wheel slipping.

An analog input will be used as the switch input. Programmable via the GUI

Shift-Cut and Rev Limiter

The rev-limiter and shift-cut features are implemented by cutting both injection and spark. For the shift-cut feature, a programmable timer should be used to disable injection and spark.

Configuration and data logging

ECU configuration should be stored inside of an on-board flash or ROM chip (might be integrated inside of the microcontroller). The ECU should be easily configurable. The configuration file should contain:

  • Engine map
  • CAN packet decoding (with custom endianness and scale and be able to modify ECU parameters)
  • Custom CAN packets to send (with custom endianness and scale)
  • Analog inputs decoding
  • Digital outputs programming

Data logs should be stored on a MicroSD card and they should contain a timestamp, so an RTC is needed. Data logging should be done at up to 50Hz.

Interfacing a general purpose computer with the ECU is done through UART.

Resulting microcontroller requirements:

  • One UART
  • One SPI for MicroSD

Power regulator

  • Input: 9V to 21V
  • Output: 5V/~1A used for powering the microcontroller, other ICs, and external sensors with two separate 5V outputs in order to separate the digital chips from the analog sensors

Microcontroller specifications

  • 5V
  • Core:
    • 1 or 2 cores
    • >25 MHz
      • If each interrupt takes 500 cycles and I want 4x headroom for other processing besides interrupts
  • Peripherals:
  • 4 digital inputs
  • 13 digital outputs
  • 15 to 18 analog inputs (at least 12 bits)
  • 12 timers
    • Resolution: < 1.73uS
    • Frequency: > 600kHz
    • Number of counter bits: > 11 bits
  • Interrupt controller
    • > 4 external interrupts
    • CAN interrupts
    • Timer interrupts
    • Interrupt queue
    • Interrupt priorities
    • > 7000 interrupts per second
  • CAN controller with speed of at least 500kbps
  • UART
  • I2C/SPI

Preliminary Block Diagram

Hardware Component Selection and Simulations

This part outlines the chosen components for the ECU system as well as further design considerations. LTSpice simulations were done using most of these components to validate them.

Injectors and Spark Plugs control blocks

For the spark and injection blocks I have chosen to use a configuration like that of MyECU

  • Npn transistor: BC847
    • Smd
    • 100MHz transition frequency
  • N channel mosfet: IAUCN04S7N040D
    • Able to provide enough current
    • 2 channel so smaller footprint on pcb
    • Doesn't need heatsink
    • Maximum 24nS response time, maximum 26nS when controlled by the above mentioned npn transistor
  • Schottky diode for flyback protection: MBRS360 (T3)

Image showing simulation of the Injectors and Spark Plugs control block using the chosen components at 143Hz (almost triple the speed of the engine at red-line)

Crank and Cam blocks

The crank and cam blocks are similar to the design of MyECU vr signal detector. Comparator: MAX9092

Other components: see simulation

Image showing LTSpice simulation of my VR Signal decoding circuit using the crank and cam signals at idle

Analog inputs

Each analog input will have a customizable pull-up resistor that can be activated or deactivated using a dipswitch for different types of sensors. Each input on the MCU will be protected against overvoltage using a resistor + Zener diode

Zener diode: EDZVFHT2R5.1B (5.1V, 2%) ⇒ 4.89 max voltage read on adc

Resistor value: 1820 to 2500

Image showing the performance of the Zener diode used. It actually clamping below 5V is not a problem, automotive sensors work in the 0.5V to 4.5V range so that a short to GND or 5V is detectable via the same pin.

Vehicle speed sensor

The input into the MCU should be done using a resistor + Zener diode

Zener: EDZVFHT2R5.1B (5.1V, 2%)

Resistor value: 1820 to 2500

For simulation, see the analog input simulation. The circuit is exactly the same, but a square wave signal is fed into it.

Digital output block

  • Npn transistor: BC847
    • Smd
    • 100MHz transition frequency
  • P channel mosfet: IPD50P04P4_13
    • Able to provide enough current
    • Needs heatsink
  • Schottky diode for flyback protection: MBRS360 (T3)

Image showing the Digital output block in LTSpice, the mosfet can handle 12Amps switching at a frequency of 10Hz

Microcontroller

The microcontroller chosen is the S32K344 or S32K324 since I am already familiar with this family of microcontrollers, and I have an abundance of resources for any problem I might encounter. The disadvantage however is that it requires a very expensive programmer/debugger.

Features:

  • 72 timers (24 per channel)
  • 24 12-bit analog inputs (8 high precision inputs per channel)
  • Dual core (S32K324) or 1 lockstep core (S32K344)
  • 160 MHz
  • Interrupt controller
  • FPU
  • RTD autosar drivers
  • CAN controller
  • I2C/SPI/UART on-board
  • 3 internal analog comparators (not used in my design)
  • As far as I can tell there is no input clamp diode, but this can be done using an external 5.1V zener

Can Transciever

TJA1462AT/0Z due to it being pin compatible with ATA6563 which we have in stock

Configuration and data logging

At a first glance I thought I could put a FRAM chip for both configuration and data logging, but high-capacity FRAM chips are very expensive. Therefore, I will use the on-board data flash of the Microcontroller for storing the configuration file and a MicroSD with FatFS or a more appropriate filesystem for data logging. The MicroSD is more susceptible to corruption. As mentioned in the requirements gathering document, the data logs should contain a timestamp, so an on-board RTC is needed.

SD card holder: DM3CS-SF

  • Hinged holder so more resilient to vibrations

RTC: MAX31334 with S8411-45R battery holder

Power regulator

TLF35585: Has 2 separate 5V outputs, one for digital logic @600mA and one for analog sensors @200mA.

Schematics and PCB

Full schematic: https://github.com/timothy-joseph/timoecu-timounu-open-hardware/blob/main/timoecu_timounu_schematic.pdf

Images showing the PCB fully assembled:

The front of the PCB

The back of the PCB

PCB Assembly

The PCB was assembled manually in about 8 hours of work.

I assembled the PCB with the help of my department leader. For the top layer I was able to use a stencil and then place each component using tweezers and solder them using a heating bed and reflow soldering station. For the bottom layer, I manually soldered each component individually by first soldering the first pin and then the rest for each. At the end I reflowed the whole back layer so that the components would be centered perfectly in their footprint.

Quality assurance

After soldering, we inspected each component using a microscope and we tested for shorts between any of the power nets and any of the ground nets. Below are images of the defects that we found and we were able to fix

The first image shows that a pin from my microcontroller broke, I was able to fix this by finding a unused GPIO pin and routing that signal to it using a strand of wire. The second image shows a bent pin of the microcontroller, which I ignored because no signal was routed to that pin. The third image shows a solder bridge on the USB port, which I fixed using soldering wick. The fourth image shows a pin that was left unsoldered on the PMIC.

Hardware Validation

PMIC

After assembling the PCB and validating that every component was soldered correctly, I tried to power on the ECU, but unfortunately nothing happened. I looked over the PCB again and saw that I forgot to place the 47uF decoupling capacitor on the 12V line going to the PMIC.

After soldering this capacitor, I tried powering the PCB with 12V again, and the power indicator LED briefly lit up and then quickly turned off. After unplugging the PCB and retrying to power it, this kept happening. I was instructed by my department leader to test the 5V_DIGITAL and 5V_SENSORS lines to see what was happening. In the image attached below, it can be seen that the 5V digital lines very briefly produces the right voltage, before quickly being turned off internally by the PMIC entering into a fault mode.

We tested multiple test points on the PMIC before finally testing the QST pins and seeing this

The QST line is unstable and goes over 6V triggering a fault in the PMIC and it turning off all of its outputs. This was fixed by adding a decoupling capacitor to this pin like how its reference manual calls for. This fixed the issue and I finally had power indicating LED that wouldn't turn off after a few milliseconds

Afterwards I checked with the oscilloscope that the 5V outputs are stable.

Microcontroller programming

After confirming that the microcontroller receives power, I quickly adapted the Dio blinking example given in the RTD release to use my status led pin and programmed my board, then I plugged in my debugger and uploaded the project to the board, thus validating that the S32K344 microcontroller is working and I integrated it correctly into my project.

Injectors and spark plugs outputs

I tested the injectors and spark plugs outputs using a programmable load set at 10 Amps.

I first tried toggling one of the outputs at 6Hz and tracked that the output was switching using an oscilloscope and using a thermal camera I checked the temperature of the mosfet and PCB. As can be seen in the image below, the mosfet heated up to only around 33.8 C. I can increase this frequency to around 100Hz with the same results.

Then I made a stupid mistake, I know that our engine's red-line is at 13000, so I quickly did the calculation 13000 / 4 (divided by 4 due to it being a 4-stroke engine), so i tried switching the same load at 3250 Hz. The TimoEcu could not handle it. The PMIC entered into a fault mode and I had to restart the power-supply to get it to turn back on. After a few tries, I discovered that this began happening at around 600Hz (@1Amp). I then spent hours talking to two colleagues about how I could fix my schematic to work at 13000. We came to the conclusion that this was happening because the mosfet was not fully saturated before being turned off. A colleague told to change two resistors; After changing these 2 resistors, the output block could now operate to around 6000Hz (@10 Amps). See the image below for the changed resistors.

Changing only the resistor at the collector of the npn resulted in my mosfet never really turning off, this lead to me burning one of my mosfets in about 10 seconds without a heatsink on it (however, with a heatsink, it could last well over 1:30 minutes; I didn't test any further). Below is a image showing the mosfet reaching 100C; after I took the picture, it instantly shot up to 140C. With both resistors changed, the maximum temperature reached on the whole PCB is 40C (with an ambient of 25C).

I don't know if you caught the mistake that I made, but the engine's redline 13000 RPM (as in rotations per minute) which translates to around 216-217 rotations per second, so a maximum switching frequency at around 54-55Hz which even my original hardware could handle at 10Amps while only reaching a temperature of around 40C (with 25C ambient). I only realized this mistake while writing this documentation because I had to go back to my Requirements Gathering document and I spotted that I only intended to make a circuit that works below 100Hz, but I guess with minimal modifications I can control an engine that has a red-line of 1440000 RPM, or at the very least the injector and spark plug outputs can handle it.

So in conclusion, my injector and spark plug output blocks work as they are, but I still ordered the new resistors and I have changed them.

With the 100Ohm resistors, I require a heating on them as they reach 80C at 25C ambient.

Crank and Cam inputs

When my first order from mouser came, I noticed that the comparator was missing (as can be seen in some of the images), so I placed another order. After it arrived, I soldered the comparator to the PCB. I tested the crank and cam inputs using a signal generator set at Pk-Pk 20V centered at 0V using multiple types of signals at multiple types of frequencies. On the software aspect of things, for the low speed runs I blinked the LED at the same frequency as the signal that I was reading, and at higher frequencies I divided that frequency so that I could visually see that the comparator was reading fast enough. I tested the VR detection circuit at up to 3000Hz. I also confirmed with an oscilloscope that I was detecting the VR signal at the right frequency.

TODO: Insert image of the setup.

Analog inputs, internal MAP and battery voltage

For the analog inputs, I checked them using a potentiometer and compared the readings from them to the readings on my multimeter. I did the same for the internal MAP and battery voltage. Afterwards, for the latter two, I converted the reading to their respective units and representations and confirmed that for the MAP I was reading around atmospheric pressure and for the battery voltage I was reading 12V (the value that I set my power supply at).

CAN transceiver

To test the CAN transciever, I wired up a CAN network with two devices on them: my ECU with the internal termination resistor turned on, and one of my old projects that also had CAN on it, with another termination resistor near it. For the first test I confirmed using an oscilloscope (that can decode CAN packets) that my ECU was sending the correct information, and in the second test I set my other project to send CAN packets and using the debugger I confirmed that my ECU was receiving the correct CAN packets

VSS

To test the VSS input, I used a singal generator at 60KHz using a square wave between 0V and 5V. I created a blinking LED with a divider from the frequency of my VSS input. And confirmed with an oscilloscope that all of the interrupts were caught.

TODO: Insert image of the setup

UART

I could not buy the Uart-to-USB chip because it was out of stock when I placed the order, instead I ordered an external Uart-to-USB module and I confirmed using it that my ECU can communicate to a computer using UART over USB.

Internal flash

To validate that I could write data inside of the microcontrollers flash for storing the configuration, I wrote 100 bytes of data at an address and then read it back to confirm that it was written correctly.

MicroSD

To validate that the MicroSD is working, I wrote 100 bytes of data at a specific address and then read it back to confirm that it was the same data.

RTC

I have used this RTC IC in the past with great success. Inorder to validate that the RTC is wired correctly, I first tried getting the vendor id from it using an I2c command, then I tried setting the clock and reading it back a few seconds later to see if it has increased.

Digital outputs

To test the digital outputs, I turned them on and placed a 9 Amp load on one of them, then I measured the temperature rise on them. After 2 minutes, they never reached above 60C with an ambient of 25C

Hardware validation conclusions

(TODO)

Software requirements and architecture

(TODO)

Software implementation (so far)

(TODO)

Conclusions

Download

O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).

Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.

Resources

Special Thanks

A special thank you to my department leader, ing. Alexandru Anastasiu, for his guidance on this project and in electronics, and for the opportunity to be part of the coolest project at Politehnica - UPB Drive

Export to PDF

pm/prj2026/bianca.popa1106/timotei_iosif.cicu.1778335860.txt.gz · Last modified: 2026/05/09 17:11 by timotei_iosif.cicu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0