A build and the thing that goes wrong · 11 of 11

Why fast coins get missed

A coin is a burst of pulses, and the library decides the burst has ended after 250 milliseconds of silence. Two coins closer together than that arrive as one coin with the wrong value — sometimes as an error, sometimes as a confident lie.

The boundary is silence

Nothing in the pulse train says "this coin is finished". The library infers it: once no pulse has arrived for 250 ms, the group is closed and its pulse count is handed to your loop.

That works because a coin's own pulses are much closer together than 250 ms — 50 ms apart at the Medium switch position. It stops working when the next coin starts before the silence has elapsed.

Two coins, and the silence that separates them
120 ms apart · 1 group
Gap between the two coins120 ms
First coin takes
50 ms
Gap
120 ms
Groups seen
1
The two coins became one. The library ends a pulse group after 250 ms of silence, and 120 ms is not enough, so 1 + 3 pulses arrive as a single group of 4. Here no coin is set to 4 pulses, so hasError() goes true and you at least know something went wrong. That is luck, not protection: with a different pulse plan the sum lands on a real coin and the sketch reports one wrong coin, confidently, with no error at all.

Drag the gap below 250 ms and the two bursts become one group whose count is the sum.

Two failures, and one of them is silent

With a 5c at one pulse and a 25c at three, a merged pair makes four pulses. Four is not a coin in that table, so hasError() goes true and you know something went wrong. You lose both coins, which is bad, but you find out.

Now suppose you had also mapped a coin at four pulses. The same merge is reported as that coin, with no error, and there is no test anywhere in your sketch that could tell the difference — because on a single wire carrying a pulse count, there genuinely is no difference. The wire said four pulses both times.

What actually helps

Lower the pulse values. This is the lever with the most travel in it. A dollar at 5 pulses takes about a quarter of a second at Medium; at 20 pulses it takes about a second. Shorter bursts mean the silence arrives sooner and the window in which a second coin can collide is smaller.

Use Fast if you have already done that. 20 ms a pulse instead of 50 shrinks every burst by more than half.

Renumber so no two coins sum to a third. If 1, 3 and 5 are your counts, 1 + 3 = 4 and 1 + 5 = 6 and 3 + 5 = 8 — none of which is a coin, so any pair that merges becomes a detectable error rather than a wrong answer. Three coins in a row can still land on a real count, but two is the case that actually happens, and it is worth laying the numbers out deliberately.

Or use value mode. This is the real escape. Value mode does not recognise coins; it multiplies pulses by a rate. Two coins merging into one group of the summed count still adds up to exactly the right amount of money, because the pulses are all still there. The event count is wrong and the money is right, and for most projects the money is what matters.

What does not help

A faster loop(). It is worth keeping fast for other reasons — in polling mode a slow loop loses pulses outright — but that is a different fault. Here every pulse was counted correctly. The question was only where one coin ended and the next began, and no amount of processor time answers it.

The library holds up to eight completed groups while your loop is busy, so a slow reaction does not lose coins that were properly separated. It just delays them.

When it does not work

Coins are missed only when people drop them in quickly

That is this page. Lower the pulse values programmed into the acceptor so each coin's burst is shorter, and the 250 ms of silence arrives sooner. Moving the signal width switch to Fast helps too, but the pulse count is the bigger lever.

The total is short by exactly one coin, occasionally

In mapped mode a merged group that matches no coin is reported with hasError() set and nothing is added, so a fast pair costs you both coins rather than one. Check hasError() and, if the total matters more than knowing which coin it was, use value mode — merged or not, it adds up the same pulses.

It reports a coin nobody inserted

Two coins merged into a pulse count that happens to be a coin in your table. 1 + 3 is 4; if you also mapped a 4-pulse coin, that pair is indistinguishable from it. Nothing in your sketch can catch this. Renumber the coins so no two of them sum to a third, or move to value mode.

Can I make the library wait longer or shorter?

setTiming(debounceMs, groupGapMs) changes both, before begin(). A shorter gap separates coins sooner and risks splitting one coin's burst into two; a longer one is safer per coin and merges more pairs. The defaults are 5 ms and 250 ms and there is rarely a good reason to move them.

Does a faster loop() fix it?

No. A slow loop loses pulses, which is a different fault, and an interrupt fixes that one. This is not about capture — every pulse was captured correctly. It is about where the boundary between two coins is, and that is a timing question about the wire, not about your code.

Where this goes next

The reference page: specifications, downloads, and the rest of the handbook.

Back to the coin acceptor kit

Edit this page — content/books/coin-acceptor/why-fast-coins-get-missed.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