Piggy bank on an Arduino Uno
A CH-926 coin acceptor counts each coin’s pulses on an interrupt, and a TM1637 display adds up the savings in dollars and cents. The whole build, an Arduino Uno and 2 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate Runs in your browser. Free, and no account needed.
The parts retail for about $47. On Mokxi they're free.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Piggy bank: a CH-926 coin acceptor and a TM1637 display.
//
// pin 2 the acceptor's COIN (white), with the Uno's pull-up
// GND the acceptor's GND, shared with its 12 V supply
// pins 13, 12 the display's CLK and DIO
//
// The acceptor is taught each coin and the pulses it is worth; here a nickel
// sends 1, a dime 2, a quarter 5 and a dollar coin 10. COIN pulls low for
// each pulse, so an interrupt counts falling edges, and a burst is over once
// the line has been quiet for longer than any gap inside one (the acceptor's
// gaps are as long as its 50 ms pulses here, so 200 ms is plenty).
#include <TM1637Display.h>
const int COIN = 2;
const int CLK = 13;
const int DIO = 12;
const unsigned long QUIET_MS = 200;
TM1637Display display(CLK, DIO);
volatile int pulses = 0;
volatile unsigned long lastPulse = 0;
long cents = 0;
void onPulse() {
pulses++;
lastPulse = millis();
}
int centsFor(int count) {
switch (count) {
case 1: return 5;
case 2: return 10;
case 5: return 25;
case 10: return 100;
default: return 0;
}
}
void show() {
display.showNumberDecEx((int)(cents % 10000), 0b01000000, true);
}
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: piggy bank");
pinMode(COIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(COIN), onPulse, FALLING);
display.setBrightness(0x0f);
show();
Serial.println("saved $0.00");
}
void loop() {
noInterrupts();
int count = pulses;
unsigned long last = lastPulse;
interrupts();
if (count > 0 && millis() - last > QUIET_MS) {
noInterrupts();
pulses = 0;
interrupts();
int value = centsFor(count);
Serial.print(count);
Serial.print(" pulses: ");
if (value == 0) {
Serial.println("not a coin I know");
} else {
cents += value;
Serial.print(value);
Serial.print(" cents, saved $");
Serial.print(cents / 100);
Serial.print('.');
if (cents % 100 < 10) Serial.print('0');
Serial.println(cents % 100);
show();
}
}
delay(10);
}
Parts list
4 parts, plus the jumper wires. They retail for about $47; on Mokxi they're free.
How it is wired
7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Ground: Arduino Uno R3 pin GND; Coin acceptor, CH-926 pin GND
- Arduino Uno R3 pin 13; Four-digit display, TM1637 pin CLK
- Arduino Uno R3 pin 12; Four-digit display, TM1637 pin DIO
- Arduino Uno R3 pin 2; Coin acceptor, CH-926 pin COIN
- Arduino Uno R3 pin 5V; Four-digit display, TM1637 pin VCC
- Ground: Arduino Uno R3 pin GND; Four-digit display, TM1637 pin GND
- 12 V: Coin acceptor, CH-926 pin DC12V
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.