The problem
The operator wanted cashless payment across a fleet without recertifying the vending controller on every machine. New dispense firmware would mean a fresh safety review and a slip in the rollout. Machines could not sit in a workshop either. The vendor protocol document was not handed over, so the key map had to be recovered from the live keypad.
What I did
The ESP32-S3 sits between the cashless host and the keypad bus. The host sends a SKU code over USB-CDC or RS-232. The firmware maps it to the key sequence the keypad uses and drives those lines through a six channel matrix. The controller sees a press, walks its normal dispense path, and the machine pours. NVS holds per slot inventory so the bridge refuses an out of stock SKU before touching the keypad.
A separate keypad observer firmware sat on the row and column matrix during bring up and decoded every manual press, which gave me the SKU map without a protocol document. A Python OTA flasher runs from a phone tethered field tablet in about a minute. I also wrote a three tier proposal for adding an MDB level 3 cashless slave on the existing header without a new board.
Decisions that shaped it
- Press the existing keypad, do not replace it. The vendor's safe state logic is the audit trail the operator already has.
- Two host transports in one build, because one site has a USB kiosk PC and another an RS-232 terminal.
- Inventory in NVS, because the controller does not expose stock counts.
- Bench firmwares kept separate from the production deliverable.
Result
Cashless dispense on the existing machine with no change to dispense, change return or emergency stop logic, reversible in under five minutes.



