Atair Rahman Alvi — Arduino Uno + Stepper Motor, simulated in Proteus
elevator-controller/
├── src/
│ └── elevator.ino # Arduino firmware (main source)
├── project_files/
│ ├── elevator.pdsprj # Proteus simulation project
│ └── elevator.hex # Compiled HEX (for direct Proteus load)
├── report.pdf # Project report (2 pages)
└── README.md
| Component | Details |
|---|---|
| MCU | Arduino Uno |
| Stepper driver | L293D H-bridge |
| Motor | 28BYJ-48 (2048 steps/rev) |
| Display | 16×2 LCD, 4-bit mode (D2–D7) |
| Floor buttons/LEDs | Multiplexed on D8–D11 (G, 2, 3, 4) |
| Direction buttons | UP → D12, DOWN → D13 |
| LCD contrast | 10 kΩ potentiometer on V0 |
- Open
project_files/elevator.pdsprjin Proteus 8 or later. - The HEX file (
project_files/elevator.hex) is already linked in the Arduino component. If it isn't, double-click the Arduino Uno component → set Program File toelevator.hex. - Press the Play button to start simulation.
- Interact via the on-screen buttons (UP / DOWN / G / 2 / 3 / 4).
- Open the Virtual Terminal in Proteus to see serial debug output.
- Install the Arduino IDE (1.8.x or 2.x).
- Open
src/elevator.ino. - Required libraries (both bundled with Arduino IDE):
LiquidCrystalStepper
- Select Board → Arduino Uno and the correct COM port.
- Click Upload.
setup()
└─ zero stepper, blink Ground LED ×3 (ready signal)
loop()
├─ display current floor on LCD
├─ waitForDirection() ← 6 s timeout, blinks current-floor LED
├─ doorCycle() ← latches extra floor requests into queue
├─ waitForFloorButton() ← 3 s window to pick destination
└─ moveTo(destination)
├─ steps motor floor-by-floor
├─ updates LCD each floor
├─ turns off indicator LED on arrival
└─ runs doorCycle() + serves queued floors recursively
After multiple round-trips the motor drifts from true zero. Root cause: the Arduino Stepper library counts 512 integer steps per floor, but the Proteus 28BYJ-48 model registers only ~508 due to its internal gear-reduction ratio. The fractional residual accumulates with every trip.
Workaround (not yet implemented): apply a calibration factor to stepsToMove on each return-to-ground command, e.g.:
// Instead of:
stepsToMove = -totalSteps;
// Use a corrected factor:
const float GEAR_CORRECTION = 508.0 / 512.0;
stepsToMove = (long)(-totalSteps * GEAR_CORRECTION);| Feature | Status |
|---|---|
| 4-floor motor travel (up/down) | ✅ Functional |
| LCD floor + direction display | ✅ Functional |
| LED indicators (multiplexed) | ✅ Functional |
| Door open/close with queuing | ✅ Functional |
| Multi-floor request queue | ✅ Functional |
| Direction timeout / idle return | ✅ Functional |
| Stepper zero-return accuracy | ❌ Drifts |