← All projects
P—07 · Case study
Automated gas pump
Recreating the full experience of a 24/7 self-service gas pump, from inserting your card to the final receipt, on an Arduino board and a two-line screen.
Code on GitHub ↗One pump, seven steps.
The system is a state machine: each step has to clear before moving to the next, just like a real pump. Here’s the flow as the customer experiences it.
- Station open? A light sensor is read. If it’s dark out, the screen shows “Closed Station” and everything is locked.
- Card inserted. A sensor detects the card; until it’s there, the pump waits.
- PIN. Four digits on a 4×3 keypad, masked with “*” as you type. Three wrong attempts and the card is blocked.
- Card removed. Fueling can’t start while the card is still detected, just like at a card-operated pump.
- Nozzle lifted. The screen prompts you to pick up the nozzle as long as it’s still holstered.
- Fueling. As long as the trigger is held, fuel “flows”: liters and price update live on screen.
- Receipt. Once the nozzle is holstered, the pump shows a summary (liters + amount), then “See you soon!”.
Inputs and outputs.
| Component | Pin(s) | Purpose |
|---|---|---|
| 4×3 matrix keypad | 22–28 | PIN entry |
| 16×2 LCD | 8, 9, 2, 3, 5, 6 | Instructions, liters, amount |
| Light sensor | A1 | Opening hours |
| Card detection | 12 | Card inserted or removed |
| Nozzle detection | 10 | Nozzle lifted or holstered |
| Trigger | 4 | Held = fueling |
The fueling loop.
For every second the trigger is held, we add 2 L, recompute the price and refresh the screen. The tank caps at 45 L. Timing uses millis() instead of delay(), so the pump stays responsive while fueling.
float P_SP22 = 4.30; // price per liter while (digitalRead(10) == 1) { // nozzle in hand if (digitalRead(4) == 1) { // trigger pressed unsigned long t0 = millis(); while (digitalRead(4) == 1 && plein < 45) { if (millis() - t0 >= 1000) { plein += 2; // +2 L per second prix = (plein - LPT) * P_SP22; lcd.clear(); lcd.print(plein); lcd.setCursor(10, 0); lcd.print(prix); t0 = millis(); } } } }
Behaving like a real pump.
- Fraud protection: after three wrong PINs, the card is flagged as blocked and rejected.
- Card must be removed before fueling, so nobody leaves it in the machine.
- No fueling without the nozzle lifted, and no receipt until it’s holstered.
- Price recomputed continuously from the volume actually dispensed.
What I learned.
- Modeling a user flow as a state machine and allowing only valid transitions.
- Securing an interface that handles money: authentication, attempt limits, lockout.
- Writing non-blocking real-time loops.
- Guiding the user with 32 characters of screen: every message counts.