coin acceptor/A build and the thing that goes wrong/10. Count coins on an ESP32 or an UNO
A build and the thing that goes wrong · 10 of 11

Count coins on an ESP32 or an UNO

Three wires and one sketch. It prints a running count to the serial monitor, and getting it working proves the wiring, the rail, the switches and the training all at once — which is why it is worth doing before anything more ambitious.

What goes where

Three wires, and the rail to set
ESP32-S3 · GPIO17 · 3.3 V
Your board
Signal pin
GPIO17
Module rail
3.3 V
Wires
3
Default settings, three wires. The module is already set to 3.3 V, which is what this board wants, so nothing on the back needs changing. GPIO17 is the pin the library recommends for it; most other GPIOs on this chip will work too, but some cannot take an interrupt and the library quietly falls back to polling on those.

Three wires, and one of them goes on last. Pick your board in the figure and it names the pin the library recommends and the rail the module has to be set to.

The pins are the library's own, out of its #if defined block rather than chosen here: a pin it does not name is a pin whose interrupt support has not been tested. Other pins usually work, but some cannot take an interrupt at all, and on those the library silently switches to polling.

The sketch

It is counter mode on the COUNTER wire, which is the shortest path to a working system. No pulse plan to get right, no table of coins, nothing to program into the acceptor beyond the training you have already done.

Upload it with VCC disconnected, so your computer is the only thing powering the board.

What "ready" tells you

The sketch prints whether it got an interrupt or fell back to polling. That line is worth reading. With an interrupt, pulses are captured the instant they arrive and a slow loop only delays your reaction to them. Polling captures them inside update(), so anything slow in loop() — a delay(), a blocking network call, a screen redraw — is time during which a pulse can come and go unseen.

If it says polling and you expected an interrupt, move the wire to the pin the sketch names.

Then make it standalone

Once coins are counting:

  1. Unplug the USB cable from your computer.
  2. Connect the module's VCC to your board's 5V or 3V3 pin.
  3. Power the module from its USB-C adapter.

Now one adapter runs the acceptor and your microcontroller, and the whole thing works with no computer attached. Reverse those steps — VCC off first — every time you go back to uploading.

Where to go from here

Swapping the wire to COIN and the mode to COIN_MODE_VALUE or COIN_MODE_MAPPED gets you money totals or per-coin identification, with the pulse plan from coin types and pulse values. The library ships six examples covering all of it, under File > Examples > Lonely Binary Coin Acceptor once it is installed.

Whatever you build, put the action in its own function and call it from the if (coin.update()) block. Keeping loop() fast is the one constraint that does not go away.

The code

count_coins.ino

Counter mode, on the COUNTER wire. It prints a total every time a coin is accepted and nothing else, which makes it the shortest possible answer to “is any of this working”. The pin is chosen for your board at compile time, the same way the library's own examples do it.

// Wiring for this sketch.
//
//   Coin acceptor  ->  Module, COIN ACCEPTOR header
//     red wire     ->  12V
//     black wire   ->  GND
//     grey wire    ->  COUNTER
//
//   Module, MCU header  ->  This board
//     GND          ->  GND
//     COUNTER      ->  COIN_PIN, below
//     VCC          ->  leave disconnected while uploading
//
// Set the module's rail on the back: 3.3 V for any ESP32 or a Pico,
// 5 V for an Arduino UNO. It leaves the factory on 3.3 V.
//
// Power the module from a 5 V 2 A USB-C adapter, not a laptop port.
//
// Arduino IDE: install "Lonely Binary Coin Acceptor" from the Library
// Manager. Tools > Board: your own board. Tools > Port: your board's
// port. Serial monitor at 115200 baud.

#include <CoinAcceptor.h>

// The pin the library recommends for each board.
#if defined(ARDUINO_AVR_UNO)
#define COIN_PIN 2
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#define COIN_PIN 17
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#define COIN_PIN 4
#elif defined(ARDUINO_ARCH_ESP32)
#define COIN_PIN 27
#else
#define COIN_PIN 2
#endif

CoinAcceptor coin(COIN_PIN, COIN_MODE_COUNTER);

void setup() {
  Serial.begin(115200);
  delay(300);

  if (!coin.begin()) {
    Serial.println("coin.begin() failed - check the mode and its settings");
    while (true) {
    }
  }

  Serial.print("ready on pin ");
  Serial.print(COIN_PIN);
  Serial.println(coin.usesInterrupt() ? ", using an interrupt" : ", polling");
  Serial.println("drop a coin in");
}

void loop() {
  if (coin.update()) {
    Serial.print("coin accepted. total: ");
    Serial.println(coin.totalCoins());
  }

  // Nothing slow here. In polling mode a long delay() steps over a pulse,
  // and even with an interrupt a slow loop delays every reaction.
}

If the serial monitor says “ready” and then nothing happens when you drop a coin, the sketch is fine and the fault is upstream. Check GND is really connected, then that the wire is on COUNTER and on the pin below, then that the acceptor is trained. If it prints a count without any coin, the acceptor's output mode switch is on NC instead of NO.

When it does not work

It prints ready, and then nothing when I drop a coin

Work up the chain. Is the module's GND wired to this board's GND. Is the wire on COUNTER and not COIN — on the MCU header COIN is the pin next to VCC, one row above COUNTER. Is it on the pin the sketch names. Is the acceptor trained, and is the coin one of the types it was trained on. Each of those produces exactly this symptom.

It counts coins that were never inserted

The acceptor's output mode switch is on NC. The library counts falling edges on a line it holds high, and NC rests in the other state, so the idle level and the pulse are swapped. Move the switch to NO.

It says polling rather than using an interrupt

The pin you chose cannot take an interrupt on this chip, or another CoinAcceptor object claimed the interrupt first — the library allows one. Polling works, but only with a fast loop. Move the wire to the pin the sketch names for your board.

The serial monitor shows nothing at all, not even ready

That is a serial problem rather than a coin problem. Check the baud rate is 115200 and the right port is selected, and that your board's USB driver is installed. Getting a board to print at all is a different page.

It works, then stops after I connect VCC

Unplug the programming cable from your computer first. With both the module and the computer powering the board, the two supplies fight and the results are arbitrary. VCC is the last connection you make and the first one you remove.

Where this goes next

The 250 milliseconds of silence that decide whether two coins stay two coins.

Why fast coins get missed

Edit this page — content/books/coin-acceptor/count-coins-on-an-esp32.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Arcade Coin Acceptor Module Kit, USB-C Powered

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum