Bitcoin ATM (coins only) with lightning network support, running offline on an esp32. The lightning network is a 2nd layer protocol on top of the bitcoin protocol enabling trustless transactions with instant settlement and cheap fees.
@21isenough and contributors for the 3d models and inspiration
RPi based Lightning ATM repo
LNBits, Ben Arc and Stepan Snigirev for the cryptograpy used to make this ATM working without internet connection
Fossa ATM repository | LNBits Homepage
Axel Hamburch for the very detailed guide in german language on assembly of the electronics
Ereignishorizont Blog
@marcelhino for the OrangeClock project, whose code was used as reference for the "BlockClock" idle display mode. OrangeClock repository
All the parts are available on eBay and Aliexpress
- ESP32 NodeMCU Dev Board | Any "normal" esp32 dev board should do the job here | Example
- DC-DC Adjustable Step-up Boost Power Supply LM2587S 5V -> 12V | for the coin acceptor, runs on 12V Example
- Waveshare 1.54 inch e-Paper Display Modul with SPI Interface | Example
- Programmable Coin Acceptor (HX-616) - 6 Coin | Example
- 10mm Metal Push Button Switch 3-6V with Yellow LED, Self-reset Momentary | Example
- USB Type C socket | to plug in the power supply (i used a Raspberry Pi type C power supply) Example
- Little Mosfet modules ("15A 400W MOS FET Trigger") | To block the coin acceptor at certain points Example
- Orange PLA Filament for the 3D Printer | Example
- Jumper Wires | Example
- Heat-Set Threaded Inserts M3 | Example
All in all would calculate around $100 for the neccessary parts
Begin by connecting the Waveshare display to the ESP32 using the following pin assignments:
| Display Pins | ESP32 GPIO |
|---|---|
| Busy | 27 |
| RST | 33 |
| DC | 25 |
| CS | 26 |
| CLK | SCK = 18 |
| DIN | MOSI = 23 |
| GND | GND |
| 3.3V | 3.3V |
Ensure to adjust the voltage of the step-up converter before connecting the coin acceptor. Detailed programming instructions are available in the following guides:
- For the Coin <-> Pin 17 connection, use a cable as short as possible.
- Short circuit the two pins below the switch on the coin acceptor with the MOSFET on GND IN and GND OUT.
- Connect the MOSFET GND pin to the ESP32 GND and the PWM pin to the pin specified in
src/board.rs.
| Periphery Pin | ESP32 GPIO |
|---|---|
| Coin Acceptor 'Coin Pin' | 17 |
| Mosfet PWM Pin | 16 |
| Mosfet GND Pin | GND |
Connect the LED Button to the ESP32 according to the pin assignments specified in src/board.rs:
| Periphery Pin | ESP32 GPIO |
|---|---|
| Button LED Pin (+) | 21 |
| Button LED Pin (-) | GND |
| Button PIN 1 | 32 |
| Button PIN 2 | GND |
For wiring inspiration and guidance, refer to Lightning ATM Documentation.
Below are two possible wiring options. Depending on which ESP32 type and display / driver board you are using.
- Standard ESP32 with separate display / driver board
- Waveshare ESP32 with integrated driver board and separate display
Flash the firmware directly from your browser without installing any tools. Open the Web Flasher in Chrome or Edge, connect your ESP32 via USB, and click "Install Firmware".
Install the Rust ESP32 toolchain (if you don't have cargo yet, install Rust via rustup):
cargo install espup --locked
espup install
cat $HOME/export-esp.sh >> ~/.bashrc
source ~/.bashrc
cargo install espflash ldproxyClone this repository and build:
git clone https://github.com/f321x/offline-bitcoin-atm.git
cd offline-bitcoin-atm
cargo build --release
cargo run --release # flashes to the connected esp32-
Create an LNbits wallet. Add the FOSSA extension and create a new ATM connection in the Extension by clicking on NEW FOSSA.
-
Copy the FOSSA connection string. The ATM stores configuration in flash memory - on first boot it will start a WiFi access point for configuration where you can enter the connection string. Connect to the
LightningATMWiFi network and open http://atm.local in your browser.Tip: To reconfigure the ATM later, hold the BOOT button (GPIO0) on the ESP32 during power-on. The device will re-enter the WiFi configuration portal. The BOOT button is located on the ESP32 board inside the enclosure and is not accessible to end users.
If you need help ask me on Nostr @npub1z9n5ktfjrlpyywds9t7ljekr9cm9jjnzs27h702te5fy8p2c4dgs5zvycf
If this software and guide provided value to you feel free to send some sats to [email protected]








