[{"content":" A 25 cm aluminium rod pivots freely on a vertical motor shaft. Left alone, it falls over in roughly half a second. With the right control loop running, it stands upright indefinitely, and recovers from a push. This is the textbook \u0026ldquo;inverted pendulum\u0026rdquo; problem, and it has been a favourite of control engineering courses for half a century. What follows is what I built around it.\nWhy a pendulum, of all things? The inverted pendulum is the Hello, World! of nonlinear control. The upright position is an unstable equilibrium point, and with a well-designed controller, we can bring the system to that point and keep it there. The hardware is simple, fits on a desk, and the failure mode is dramatic but not destructive: the rod just falls over, but might swing around vigorously a few times as the controller tries to fight gravity. The inverted pendulum sytem strikes a balance where the theory is rich enough to teach, the hardware is cheap enough to scale, and the demo is satisfying enough to remember.\nWhat\u0026rsquo;s less common is building the whole stack around it: not just a controller that works, but a lab project that covers symbolic dynamics, physical modelling and simulation, state estimation, embedded firmware, and a way to grade students on how well they pulled it off.\nThe setup: one kit, two rigs The mechanics start from ST\u0026rsquo;s STEVAL-EDUKIT01, an off-the-shelf rotary inverted pendulum kit. The kit ships with a stepper motor and an L6474 driver, and that \u0026ldquo;stock\u0026rdquo; rig is the one most students get hands-on with first. I built a second variant that swaps the actuator for a brushless DC motor: a maxon ECX FLAT 42 M on ST\u0026rsquo;s X-NUCLEO-IHM08M1 power board. Both versions share the same NUCLEO-F401RE controller, the same kit frame, and the same 2400 CPR optical encoder on the pendulum joint. The BLDC variant adds a second encoder (8192 CPR, on the motor shaft) for field-oriented commutation, which the stepper handles open-loop through microsteps.\nThe two rigs aren\u0026rsquo;t redundant; they\u0026rsquo;re a pedagogical pair. The stepper is the cheap, simple, \u0026ldquo;it just works\u0026rdquo; option that ships in the box. The BLDC is the higher-bandwidth, closer-to-a-real-servo option. A final perk of the BLDC setup is the use of slip ring contacts in the pendulum encoder wire, which allows the motor shaft to rotate freely and indefinitely. Above the firmware, the framework (Pi, Simulink model, grading) treats them identically.\nStepper rig BLDC rig Motor Bipolar stepper (kit) maxon ECX FLAT 42 M Driver board X-NUCLEO-IHM01A1 (L6474) X-NUCLEO-IHM08M1 (FOC + shunt sensing) Control rate 1 kHz, acceleration command 16 kHz, torque command Motor encoder none (open-loop microsteps) 8192 CPR Pendulum encoder 2400 CPR (shared) 2400 CPR (shared) Firmware repo stepper firmware → BLDC firmware → That\u0026rsquo;s it for hardware: a microcontroller, a driver board, a motor, an encoder or two, and a Raspberry Pi sitting next to it as the brains.\nThe BLDC rig, assembled and at rest.\nBrain and muscle The architecture splits the work between two computers, on purpose.\nThe STM32 is the muscle. Its job is \u0026ldquo;make the motor do exactly what you ask for, and don\u0026rsquo;t catch fire.\u0026rdquo; On the BLDC rig that means ST\u0026rsquo;s Motor Control SDK running field-oriented control at 16 kHz, with shunt-resistor current sensing on the IHM08M1 and PI loops on the q- and d-axis currents The Pi sends torque commands and receives encoder angles. On the stepper rig it\u0026rsquo;s simpler: the L6474 handles current regulation in hardware, and the firmware exposes an acceleration command at 1 kHz instead. Either way, the firmware itself doesn\u0026rsquo;t know there\u0026rsquo;s a pendulum at all. Every cycle it bundles the latest pendulum encoder reading into an 8-byte SPI packet, ships it to the Pi, and waits for the next command back. Packets are CRC-protected; five corrupted in a row and the motor stops.\nThe Raspberry Pi is the brain. It runs the higher-level control: an LQR balance controller for keeping the rod upright, plus an energy-based swing-up controller that pumps energy into the system from the rod-down rest state until it\u0026rsquo;s near vertical, where the LQR takes over. Crucially, the Pi runs this as Simulink-generated C code, deployed straight from MATLAB.\nThis split has a teaching payoff: students can prototype their own swing-up logic in Simulink and Stateflow, sketching state machines and trying different control strategies, without recompiling a single line of embedded firmware. THey can also change the model structure and parameters, if they decide it does not sufficiently represent reality.\nThe digital twin Here\u0026rsquo;s the part I\u0026rsquo;m proudest of: the same Simulink model drives both the simulation and the real hardware.\nThe model contains the pendulum\u0026rsquo;s nonlinear equations of motion (implicit in Simulink, but also derived symbolically with Euler-Lagrange for controller and observer design), an Unscented Kalman Filter that reconstructs the full 4-D state (two angles plus two angular velocities) from the encoder readings, and the LQR + swing-up controllers. The simulated plant itself is built in Simscape Multibody: joints, transforms, and rigid bodies that mirror the bench geometry.\nThe simulated plant in Simscape Multibody, mirroring the geometry, joints, and dynamics of the bench rig.\nA Simulink \u0026ldquo;variant subsystem\u0026rdquo; sits in the middle: when you simulate, it routes the actuator command into the Multibody plant; when you deploy, it routes it out through the SPI interface to the real STM32. Those are the two targets in the title: simulation and real hardware, from one model file. (The choice of stepper vs BLDC at the bottom of the stack is a second variant switch, layered underneath: torque-out for one rig, acceleration-out for the other.)\nThe variant subsystem itself: top = simulated plant; bottom = SPI bridge to the real bench. Same ports, same controller upstream.\nIn practice this means: tune the controller in simulation, hit one button, and the same controller is now running on the Pi commanding the real motor, with no hand-translation step in between.\nA teaching lab built around it The whole stack (firmware, model, controllers, scoring tool) is set up as a course lab. Student teams get the framework and a brief: design a controller that swings the pendulum from rest to upright as fast as possible, and whose simulation matches the real hardware as closely as possible.\nTwo metrics, deliberately in tension. You can win on speed by being aggressive with the swing-up energy law, but if your model isn\u0026rsquo;t accurate enough to predict where the rod will end up, you\u0026rsquo;ll overshoot the catch window for the LQR and lose. You can win points on accuracy by meticulously tuning the model parameters and structure to match reality, but then you have less time to make a fast controller. The good teams have to do both: identify the plant accurately and push the controller hard.\nA grading script consumes each team\u0026rsquo;s submission (.mldatx files captured from the Simulink Data Inspector during their best hardware run), measures swing-up time, computes the Symmetric Mean Absolute Percentage Error between sim and hardware, and ranks the teams.\nTeam Theta (stepper rig): 4.68 s to upright, SMAPE 119%.\nTeam Pi (stepper rig): 5.74 s to upright, SMAPE 68%.\nLast cohort, two teams ran the stepper rig and tied at four points each by hitting opposite ends of the trade-off. Team Theta got the rod up a full second faster, but their digital twin spent the run drifting away from the real system (they did not spend as much time tuning the model parameters); a SMAPE near 120% means sim and hardware barely agreed on amplitude. Team Pi conceded that second and earned it back on accuracy: the two traces hug each other almost to the catch. Same total score, two opposite engineering bets.\nIt\u0026rsquo;s the part of the project I think about most. The hardware and the maths are well understood; teaching is where the value gets made or lost. Wrapping a competition around the digital-twin workflow forces students to take the simulation seriously, because their grade depends on its accuracy, not just on whether their controller eventually works.\nWhat it looks like running Numbers don\u0026rsquo;t quite carry the feel of the rig in motion (the BLDC variant, in this clip): the way the rod jitters with micro-corrections at the apex, the soft hum of the motor commutating at 16 kHz, the moment a push test shoves the rod off vertical and the controller catches it before it falls.\nSwing-up: rest to upright, then hold. The portability of the rig is illustrated by means of demonstrating it on my kitchen table. Please ignore the clutter.\nSame swing-up on the stepper rig. Uses empirical controller and takes longer How hard you can poke the rod before the LQR runs out of authority?\nPush test: a finger tap, a harder one, and finally one shove too many. And here\u0026rsquo;s the same loop in pure simulation. Swing-up trigger, Mechanics Explorer mirroring the model in 3D, two setpoint nudges, then the drop button:\nPure-simulation run: same controller, same gains, no motor. If you want to try it yourself, the Simulink model runs end-to-end on the same controller, gains, and code path as on hardware. You won\u0026rsquo;t feel the motor sing, but the trajectories will match. You will need MATLAB, Simulink and some add-ons. It\u0026rsquo;s free if you are a student at KU Leuven, but you may not be so lucky.\nTry it / source The repositories that make up the project are public:\nFirmware (BLDC variant): sadegroo/NUCLEO-F401RE-invpend-SPIslave-BLDC Firmware (stepper variant): sadegroo/NUCLEO-F401RE-invpend-SPIslave-stepper MATLAB framework + digital twin: sadegroo/digtwin_labo Build instructions, hardware bill of materials, and the lab worksheets live in each repo\u0026rsquo;s README. Both firmware variants use a modern CMake build (no STM32CubeIDE required), and the MATLAB project opens with a single digtwin_labo.prj double-click.\n","permalink":"https://sadegroo.github.io/portfolio/posts/bldc-pendulum/","summary":"A Simulink digital twin, an STM32 motor driver in two flavours (stepper and brushless), and a student competition, all built around a 25 cm pendulum that refuses to fall over.","title":"One Simulink Model, Two Targets: A Digital Twin for an Inverted Pendulum"},{"content":"I\u0026rsquo;m Sander. I live in Belgium and work as a postdoc at KU Leuven, Geel campus, in the RAM group (Robotics, Automation and Mechatronics), where I teach robotics, digital twins, and process automation.\nThe rest of the site is the work: embedded systems and motor control on STM32, plus simulation and digital twins in MATLAB/Simulink. The Posts section is the actual record.\nReach me at githubpages@alias.sadegroo.xyz, or find me on GitHub and LinkedIn.\n","permalink":"https://sadegroo.github.io/portfolio/about/","summary":"About Sander (sadegroo).","title":"About"}]