Miguelitos 5000x
Universidade Regional de Blumenau (FURB) — Blumenau, Brazil
The short version
This started as a college assignment about DC motors and LEDs. It ended up as a fake gym treadmill console called the MIGUELITOS 5000x, with 16 seven-segment digits, a spinning motor, and a control panel that looks like something you'd actually find at a gym.
We're not going to pretend this is a groundbreaking engineering project. It's a student project. But we had so much fun building it in Visuino Pro that our professor suggested we write the whole thing up and publish it — so here it is, the complete build.
And the best part? We never wrote a single line of Arduino code. Not one. Everything you're about to see was wired together with Visuino components.
The tools
| Tool | What it did for us |
|---|---|
| Visuino Pro | The entire firmware. Every counter, timer, gate, and math block. |
| SimulIDE | The circuit: Arduino Mega, 16 displays, transistors, L298N, DC motor. |
| Arduino Mega 2560 | We needed the pin count. A lot of pins. |
| A photo of a real treadmill panel | Dropped into SimulIDE as a background image. This is the trick that made the whole thing look good. |
That last row deserves a paragraph. SimulIDE lets you drop an image into the circuit canvas, and you can place components on top of it. So we took a photo of a real treadmill console and positioned our seven-segment displays exactly where the real display windows are. The push buttons went right on top of the printed START / STOP / +/- buttons.
We also replaced the original brand name on the panel with our own — hence MIGUELITOS 5000x.
How it works: everything runs on one heartbeat
The core idea of the whole project is dead simple: one pulse per second, and on every pulse we add whatever needs adding.
Distance grows by the current speed in m/s. Calories grow by the ACSM formula. Time counts up by one. Heart rate rerolls. That's it — that's the machine.
Here's the control section:
OneSecondPulse (Pulse Generator, 1 Hz) ──┐
├──> And1 ──> ActivePulses
RsFlipFlop (SR Flip-Flop) ───────────────┘ (Clock Multi Source)
│
StartButton ──> Inverter4 ──> RsFlipFlop.Set ├──> TotalSeconds.Up
StopButton ──> Inverter1 ──> RsFlipFlop.Reset ├──> RandomHeartRateSimulator.Clock
├──> Distance.AddValue
└──> Calories.AddValue (×2)
The SR Flip-Flop is the "is the treadmill running?" memory bit. START sets it, STOP resets it. The AND gate uses it to gate the 1 Hz pulse — so when you hit STOP, the pulses simply stop reaching everything downstream. Time freezes, distance freezes, calories freeze. No extra logic needed.
The ActivePulses component is a Clock Multi Source, which we ended up loving. It fires its outputs in guaranteed sequential order from a single clock event. That matters a lot here: we need distance and calories to be updated with a consistent view of the world on every tick, not in some random order.
There's a second Clock Multi Source called ResetPulses that handles the ZERO button — it fans one button press out into seven reset events (reset the seconds counter, reset the distance accumulator, reset the calories accumulator, reset the pulse generator phase, reset the speed, and so on). One button, seven synchronized effects, still zero code.
And a nice touch we're proud of: a Start component is wired into ResetPulses too, so the machine zeroes itself cleanly the moment the Arduino boots.
The time algorithm
A minutes-and-seconds clock looks like it needs two chained counters, but you can do it with a single one — and it comes out much cleaner. It's the approach the official Visuino countdown-timer tutorial uses: one counter, and the display values derived with math:
ActivePulses ──> TotalSeconds (Up/Down Counter, 0..3599)
│
├──> DivideBy60 ──────────> [ MINUTES display ]
│ │
│ └──> MultiplyBy60 ──┐
│ │ (binds to .Value)
└──> SecondsRemainder <───────┘
│
└──────────────> [ SECONDS display ]
TotalSeconds counts raw seconds. DivideBy60 (Divide Integer By Value) gives you minutes directly. Then MultiplyBy60 and SecondsRemainder (Subtract Integer Value) compute total − minutes×60, which is the seconds digit.
The neat part is how MultiplyBy60 connects to SecondsRemainder: it doesn't go into the data input, it binds to the Value property pin. Being able to drive a component's property from another component's output — instead of just its input — is one of those Visuino features that makes complicated things collapse into three blocks.
The minute rolls over mathematically on the 60th pulse — no Delay component and no timing assumptions anywhere along the way.
The speed algorithm
Speed is an Up/Down Counter, 0 to 30 km/h, driven by the + and − buttons.
SpeedUpButton ──> Inverter3 ──┐
├──> SpeedUpGate (And) ──> Speed.Up
RsFlipFlop.Out ─────────────────┘
SpeedDownButton ──> Inverter5 ──┐
├──> SpeedDownGate (And) ──> Speed.Down
RsFlipFlop.Out ─────────────────┘
The buttons are wired with IsPullUp = true on the Arduino pins, which is why each one goes through an Inverter — pressed reads LOW, and we want a rising edge.
The two AND gates make the speed buttons only work while the machine is actually running, which is how a real treadmill behaves — with the treadmill stopped, + and − do nothing.
Speed.Max is 30 with RollOver = False, so pressing + at 30 just stays at 30.
The motor
This is the part the assignment was actually about, and Visuino made it almost too easy.
Speed (0..30 km/h) ──> MotorSpeedMerger ──> MotorScale (÷60) ──> MotorOffset (+0.5) ──> MotorDriver
▲ (L298N, 3-pin bridge)
ZeroWhenStopped ────────────┘ │
(fires when RsFlipFlop Forward → pin 2
inverted output goes high) Reverse → pin 3
Speed → pin 4 (PWM)
The Dual DC Motor Driver 3 Pin Bridge (L298N) component takes a single analog input where 0.5 means stopped, 1.0 is full forward, and 0.0 is full reverse. So we just map our 0–30 km/h into 0.5–1.0: divide by 60, add 0.5. Two blocks, and the motor now physically follows the number on the display.
ZeroWhenStopped is an Integer Value clocked by the flip-flop's inverted output — the moment you press STOP, it injects a 0 into the merger and the motor cuts out immediately.
Distance and calories
Both are Accumulate (Integral) Analog components, which is a beautiful little component: you give it a list of elements (Add Value, Set Value), each with its own clock input, and it maintains a running total.
Distance:
Speed ──> ToMetersPerSecond (×0.277778) ──> binds to Distance's "Add Value" element ActivePulses ──> triggers the add, once per second ResetPulses ──> triggers "Set Value" (0) → zeroes it
Since we add the m/s value once per second, the accumulator is literally integrating speed over time. The result is meters. (We love that the physics just falls out of the wiring.)
Calories — and yes, we checked this formula properly:
kcal per second = 0.02042 + 0.035 × speed(m/s)
This is the ACSM walking equation, instantiated for a 70 kg person (we had to assume an average body weight, since the console has no way to know who's on it):
- VO₂ = 3.5 + 0.1 × speed(m/min) ml/kg/min
- kcal/min = VO₂ × body mass / 200
- Resting term:
3.5 × 70 / 200 / 60= 0.02042 kcal/s - Speed term:
0.1 × 70 / 200→ 0.035 kcal per m/s per second
In Visuino that's two Add Value elements on one accumulator: one constant, one bound to CaloriesFactor (Speed in m/s × 0.035). Fair warning to anyone copying this: the walking equation understates the burn above roughly 6 km/h, where the running equation doubles the speed coefficient. For a demo console we decided it was good enough, and we'd rather be honest about it than quietly wrong.
Heart rate is a Random Integer Generator between 60 and 120, clocked once per second. It's fake, 100%, and we're saying that up front — there's no sensor in this build. It's a placeholder for a real pulse sensor, and it makes the panel feel alive in the demo.
16 digits, 23 pins, one component
This is where the Mega earns its place.
The whole display is a single Display Dynamic 7 Segments component with 16 digits, split into 6 named groups:
| Group | Digits | Fed by |
|---|---|---|
| Seconds | 2 | SecondsRemainder |
| Minutes | 2 | DivideBy60 |
| HeartRate | 3 | RandomHeartRateSimulator |
| Speed | 3 | Speed |
| Distance | 3 | DistanceDisplayMerger |
| Calories | 3 | CaloriesDisplayMerger |
Seven segment pins (a–g) shared across all 16 digits, on A9–A15. Sixteen digit-select pins on 30–41 and A4–A7. The component handles the multiplexing scanning for you; on the SimulIDE side each digit's common cathode is switched by an NPN transistor with a base resistor.
Being able to say "this group is 2 digits, leading zeros on, and its value comes from that pin" and have the multiplexing just happen is, honestly, the single biggest reason this project got finished on time.
Credits and thanks
Big thanks to Professor Miguel Alexandre Wisintainer and Boian Mitov. Three students built a multiplexed 16-digit console with a motor driver, a state machine, and two integrators in a few hours — while learning the tool — and the "code" is a diagram you can read across the room.
The moment that sold us was watching the motor spin up as we pressed + on a panel that looked like a real product, and realizing we'd never opened a text editor.
Project files:
esteira.sim1
Nikolas Trapp · ntrapp@furb.br
Paulo Ricardo Machado · prmachado@furb.br
Universidade Regional de Blumenau (FURB), Santa Catarina, Brazil
Comentários
Postar um comentário