← 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.

RoleEmbedded systems
SettingSchool project · IMT Nord Europe
HardwareArduino · keypad · 16×2 LCD
LanguageC / Arduino
Code on GitHub ↗
01 — How it works

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.

  1. Station open? A light sensor is read. If it’s dark out, the screen shows “Closed Station” and everything is locked.
  2. Card inserted. A sensor detects the card; until it’s there, the pump waits.
  3. PIN. Four digits on a 4×3 keypad, masked with “*” as you type. Three wrong attempts and the card is blocked.
  4. Card removed. Fueling can’t start while the card is still detected, just like at a card-operated pump.
  5. Nozzle lifted. The screen prompts you to pick up the nozzle as long as it’s still holstered.
  6. Fueling. As long as the trigger is held, fuel “flows”: liters and price update live on screen.
  7. Receipt. Once the nozzle is holstered, the pump shows a summary (liters + amount), then “See you soon!”.
02 — Wiring

Inputs and outputs.

ComponentPin(s)Purpose
4×3 matrix keypad22–28PIN entry
16×2 LCD8, 9, 2, 3, 5, 6Instructions, liters, amount
Light sensorA1Opening hours
Card detection12Card inserted or removed
Nozzle detection10Nozzle lifted or holstered
Trigger4Held = fueling
03 — The code

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.

pompe.inoC / Arduino
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();
      }
    }
  }
}
04 — Safety

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.
05 — Takeaways

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.