5.5.21 · D2Embedded Systems & Real-Time Software

Visual walkthrough — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

2,774 words13 min readBack to topic

Before any symbols, look at the whole loop we are about to build.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

The real ECU (left, the thing we are testing) sends a command. The simulator (right, a computer pretending to be a motor) must answer with a sensor reading. The arrows form a closed loop: output feeds input feeds output, forever. Our whole job is the box labelled "physics maths" — turning one command into one honest reply.


Step 1 — Turn the ECU's command into a voltage

WHAT. The ECU does not send us a voltage directly. It sends a PWM duty cycle — a single number between and that means "what fraction of the time is the switch ON". See PWM (Pulse Width Modulation) for the signal itself.

WHY. A motor is driven by voltage, but a microcontroller cannot make a smooth analog voltage cheaply. Instead it flicks a switch on and off very fast; the average voltage the motor feels is the fraction-on times the battery voltage. So the very first thing the simulator must do is undo that trick and recover the average voltage.

PICTURE. Below, the square PWM wave (top) is ON for of each period. Its flat average (dashed line) sits at of the battery height. That average is what the motor actually "sees".

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

Edge case. If the motor gets (fully coasting); if it gets the full battery. The formula naturally covers both ends — no special code needed.


Step 2 — From voltage, work out the current

WHAT. Current is what actually flows through the motor's wire when we push it with voltage.

WHY this equation and not "just Ohm's law". A spinning motor fights back. As it turns, it generates its own voltage that opposes the supply — the back-EMF. So the effective push is not the full , it's minus the motor's own counter-voltage. Only that leftover push drives current through the wire's resistance .

We also drop the inductance term here. The full physics has an piece (the wire resists changes in current), but if that term is tiny compared to , ignoring it makes the maths instant instead of needing another differential equation. That trade — accuracy for speed — is exactly what real-time demands.

PICTURE. Think of a see-saw. The supply voltage pushes down on one side; the back-EMF pushes back on the other. The difference is what's left to drive current, and dividing by resistance tells you how much current squeezes through.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

Step 3 — Current becomes torque

WHAT. Torque is the twist the motor applies to whatever it's turning.

WHY. Current-carrying wire in a magnetic field feels a force (Lorentz force). Wind that wire into the motor's coils and the force becomes a twist. The beautiful part: the twist is directly proportional to current — double the current, double the torque. That gives us the simplest possible line.

PICTURE. A straight-line graph: torque on the vertical axis, current on the horizontal, passing through the origin with slope . It goes through the origin both ways: positive current → driving torque, negative current (regen, Step 2) → braking torque in the opposite direction.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

Step 4 — Torque changes the speed (Newton for spinning things)

WHAT. Now we let the twist actually accelerate the rotor to a new speed.

WHY this is a differential equation. Force doesn't set speed directly — it sets change of speed. Newton's second law for rotation says: net twist = inertia × angular acceleration. The net twist is the motor's push minus two things fighting it: an external load and friction that grows with speed. Because it tells us the rate of change of , we need to integrate to get the next — and the cheapest integrator is a single forward step (Euler).

WHY Euler and not something fancier. Euler says: "new value = old value + (rate) × (time step)". It's one multiply and one add — trivially fast, which the real-time deadline demands. It's less accurate than clever solvers, but with a small enough it's honest enough, and predictable in cost (no adaptive step that could blow the deadline).

PICTURE. The speed-vs-time curve. At each tick we stand on the current point, look at the slope (the net torque tells us the slope), and take a short straight step of length along that slope to land on the next point.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

Degenerate case — too big. If is so large that the straight step overshoots wildly, the simulated speed can oscillate or explode even though the real motor would be calm. This is numerical instability, not physics. Fix: shrink , or use an implicit (backward-Euler) step. This is exactly why HIL rigs run at .


Step 5 — Speed becomes position

WHAT. Add up speed over time to get how far the shaft has turned.

WHY. The ECU's sensor doesn't measure speed directly — it counts rotation. So we must track the accumulated angle . Same Euler idea: new angle = old angle + speed × time.

PICTURE. Position climbs like a staircase: each tick, speed sets how tall that step is.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

Step 6 — Fake the sensor the ECU expects

WHAT. The ECU has no idea what is. It only understands encoder pulses — a real motor has a wheel with slots, and a sensor clicks once per slot. We must convert our clean angle into that click count.

WHY the floor function. Pulses are whole clicks — you can't have pulses. The floor throws away the fraction, keeping only complete clicks, exactly like real hardware. This is the moment the simulation stops being pure maths and becomes something a real pin can produce.

PICTURE. A smooth angle ramp (top) chopped into a discrete pulse-count staircase (bottom). Each time the angle crosses another slice, the count ticks up by one.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

These pulses go out through the I/O box's digital output onto the ECU's timer pin — often over a bus like the CAN Bus Protocol for higher-level messages, but raw pulses for the encoder.


Step 7 — The deadline that ties it all together

WHAT. Steps 1→6 are one lap of the loop. The catch: they must all finish before the ECU's next control cycle begins.

WHY. The ECU has its own clock — say it thinks and acts every . If our seven steps take longer than to compute, the ECU gets stale sensor data. To the ECU it feels like time slowed down, and its PID Control loop can go unstable — even though the physics was perfect. Correctness in HIL means correct and on time. This is why HIL runs on an Real-time Operating Systems (RTOS) or an FPGA for Real-Time Simulation with hard, guaranteed deadlines.

PICTURE. A timeline: each slot must contain the whole compute block with room to spare. A slot that overflows (red) is a missed deadline — a bug even if the numbers were right.

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant

The one-picture summary

Everything above is one arrow chasing its own tail: command → voltage → current → torque → speed → position → pulses → back into the ECU, all inside one .

Figure — Hardware-in-the-Loop (HIL) simulation — real hardware, simulated plant
Recall Feynman retelling — say it back in plain words

The ECU shouts a number between 0 and 1 that means "push this hard". We (1) turn that fraction into an average voltage — trusting that the switch flips much faster than one tick, so the motor feels the average. But the motor is already spinning and pushing back, so (2) the real push is our voltage minus its back-push, divided by the wire's resistance — that's the current; and if the spin ever outruns the voltage, that current goes negative and the motor brakes. (3) More current means proportionally more twist (negative current → braking twist). (4) That twist, minus the load we're driving and the friction dragging it down, speeds the rotor up a tiny bit over one time-step — and the clock advances . (5) A tiny bit more spin means a tiny bit more angle turned. (6) We chop that angle into whole encoder clicks, because that's the only language the ECU understands. (7) We send those clicks back — but only if the compute time for all of that stayed under , before the ECU's next heartbeat. When push finally balances drag, the speed stops changing and the motor idles steadily, which is exactly the moment the ECU's controller was hunting for.

The single idea: a simulator is just a very disciplined mirror — it reflects the ECU's command back as the sensor reading a real motor would have produced, and it must do it before the ECU blinks.

Sibling deep-dive pages build the surrounding ideas: Model-in-the-Loop (MIL), Software-in-the-Loop (SIL) and Processor-in-the-Loop (PIL) show where HIL sits on the fidelity ladder; Fault Injection Testing and System Identification show what you do with the loop once it runs.