Multicoin Acceptor/Piggy Bank

Hi all!

A couple years ago, I used an Arduino board for a project in school. After re-sparking my interest and looking up some projects, I found one that interested me and seemed relatively easy to do. However, I have very little experience in C++. I didn’t do any of the coding on my last project, so debugging this code that I got from Github (https://github.com/adafruit/Adafruit-Programmable-Piggy-Bank/blob/master/piggybank.ino) has been an immense challenge.

The project that I’m trying to construct is a piggy bank that accepts up to 4 coins (this code was meant for a 1 coin acceptor) and keeps track of the total amount of money along the way. The original code also includes an LED, which I am deciding to leave out. The code compiles and uploads just fine, but when I try it out, nothing happens. This is the original code:

/*********************
* connect the COIN wire to digital 2
* set the side switches to "FAST" "NC"
**********************/

// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

// attach coin wire to digital 2
#define COIN 2
int coins;
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
int fadebrightness = 0;    // how bright the LED is when it's flashing

void setup() {
    // declare pin 11 to be an output for LED:
  pinMode(11, OUTPUT);
  // Debugging output
  Serial.begin(9600);
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);

  pinMode(COIN, INPUT);
  digitalWrite(COIN, HIGH); // pull up
  coins = 0;
}

void loop() {
  lcd.setCursor(0,0);
  lcd.print(" PLEASE INSERT ");
  lcd.setCursor(0,1);
  lcd.print("  ONE QUARTER  ");
    // set the brightness of pin 11:
  analogWrite(11, brightness);

  // while the coin pin is low (no coin detected), do nothing
  while (! digitalRead(COIN)) {
    delay(1);
  }

  // while the pin is high, we'll track the length with a counter
  uint8_t counter = 0;
  while (digitalRead(COIN)) {
    delay(1);
    counter++;
  }
  Serial.print(counter);
  Serial.println(" ms long pulse");
  
  if ((counter > 60) || (counter < 20))
      return;
      
  coins++;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("   OINK OINK! ");
  lcd.setCursor(0,1);
  lcd.print("YOU HAVE $");
  lcd.print(coins*.25);
  lcd.print("  ");
    // loop through to flash the LED
  fadebrightness = brightness;
  for (int i = brightness; i < 510; i+=5) {
    // turn the pin on:
    analogWrite(11, fadebrightness);
    fadebrightness = fadebrightness + fadeAmount;  
    delay(20);                  
    // reverse the direction of the fading at the ends of the fade: 
    if (fadebrightness == 0 || fadebrightness == 255) {
      fadeAmount = -fadeAmount;
    }
  }
  brightness = brightness + 5;
}

As I said before, the code compiles and uploads perfectly. But running in on the arduino isn’t working out. The LCD shield that is attached to the arduino will display “PLEASE INSERT ONE QUARTER” like it’ supposed to, but when I do insert a coin, nothing happens. I’ve also tried attaching the ‘counter’ wire from the coin acceptor to pin 3 on the arduino, but that causes the LCD shield to display a number that is continuously counting up very fast. The video that gave me the idea for this project (http://thetechjournal.com/how-to/how-to-make-an-electronic-piggy-bank-that-keeps-track-of-your-savings.xhtml0 never mentions the ‘counter’ wire, so I’m not even sure if I need it.

Like I said before, I have very little programming experience at all, so I would greatly appreciate any suggestions for edits to the code. I was really excited to do this project, and it’s becoming very difficult, but I’ve invested too much money to have it not work out; so I really need your help in making this device come to life. Thank you!!

-Rex

Have you the Arduino connected to your PC so you can see the values produced by Serial.print ?

It looks like it should show an increasing number while the coin is being pushed through - does that happen? What values do you see?

...R

The arduino is temporarily being powered by my computer via USB cable, but I'm planning on powering it via a wall adapter. Would Serial.print only print back to the computer? I was trying to have the total displayed on the LCD screen.

As far as the increasing number problem, the number is always being displayed on the LCD screen, regardless of whether or not a coin is being pushed through.

  // while the coin pin is low (no coin detected), do nothing
  while (! digitalRead(COIN)) {
    delay(1);
  } //////////IT DOES NOTHING, AS YOU SAY, SO TAKE IT OUT.

  // while the pin is high, we'll track the length with a counter
  uint8_t counter = 0;
  while (digitalRead(COIN)) {  ///////////////THIS ALSO DOES NOTHING!
     //////////////////////TRY: while (digitalRead(COIN == HIGH))
    delay(1);
    counter++;
  }

It looks like you're trying to measure the size of the coin by seeing how long it takes to pass through the counter. Have you thought about the effect that friction will have on that time? Not all coins of the same size/value will have the same amount of friction.

Well I'm actually trying to have the arduino differentiate between coins based on the pulses that the multicoin acceptor puts out. This code was written for a single coin acceptor, so I suppose it's possible that that's what's happening. I have extremely little experience in programming, so I'm really not sure how to adapt this code for my project.

Rex202:
The arduino is temporarily being powered by my computer via USB cable, but I’m planning on powering it via a wall adapter. Would Serial.print only print back to the computer?

If it was my project I would put the LCD in a drawer until I had the rest of the code working.

the number is always being displayed on the LCD screen

I’m not sure what number you mean, but I think you are referring to the coin count (or the total value).

I was referring to a number that increments while the coin is in contact with the detector in this code

while (digitalRead(COIN)) {
    delay(1);
    counter++;
  }
  Serial.print(counter);
  Serial.println(" ms long pulse");

That number should appear in the Serial monitor and it is the source for the subsequent tests. If that number is not correct nothing else will work.

…R