Coin Change Machine - Can`t quite find the code problem!

Hi I`m making a change machine to change coins into 10 pence coins. So £1 in, 10x10p (pence) out, 50p in 5x10p out.

There are two devices: 1. A coin acceptor - it detects which coin has been inserted and pulses a set number of pulses on a single line to let the ardunio know what can has entered. e.g £1 in = 1 pulse, 2p in = 2pulses, 5p in = 3 pulses. 2. A coin hopper - power it up and it starts ejecting 10pence coins - each coin it ejects it goes Low so the arduinos job to count the coints ejected and turn it off.

So to clarify: arduino sits and waits for a pulse by a coin inserted --> it then waits and sees how many pulses came and identifies what coin it was --> it turns on a relay which turns on the hopper --> it senses a pulse each coin ejected and turns off the hopper when the correct number of coins has been sent out.

Problem: When a coin is inserted, it senses that the correct coin has gone in but then randomly senses that other coins have been inserted! So you put 10p in and it sends out 1 coin but then immediately says £1 was inserted as well and spits 10 more out.

Troubleshooting so far - Ive commented out lines and it is definitely an issue with the despense() function. Without it, it recognises the coins just fine. Now I cant see a problem with this function since the same function works in similar code I`ve written for the hopper alone.

using a Serial.write I can see that for some reason, during the dispence function coinPulseCount is increasing - as though a coin has been inserted!! I`ve tried code to hold coinPulseCount low when dispensing but still an issue!

Can anyone see a problem with the code? Could this be a hardware issue - I don`t see why coinPulseCount is counting when nothing is coming through on the coin selector line - no coins are inserted but for some reason the "dispence()" function is making it change!!

Any help would be massively appreciated. I`m totally lost as to why this is happening.

void coinacceptor()      //Function called when coin enters coin acceptor
  pulseTime = millis();   //store current time in pulseTime

Don't do serial prints inside an ISR.

I can't see any major problems with your code other than that. Maybe there is noise on the coin acceptor part? Some debugging prints in the main loop might show what is happening.

Hi Nick, I removed the print in the interrupt, same problem!

In the main loop I've put a print of the coinPulseCoin and you can see this rising again while a coin is being dispenced as thought a coin is going into the coin selector when it is not!!

I don't understand how LOW pulses on the hopper line could be generating HIGH pulses on the coin verifier line!

I'm new to arduino and electronics - this is a bigger project to something I'm building my daughter.

Any further advice welcome! No idea now where to go with this!

Better show your circuit. Does the acceptor need pull-up resistors? Or the dispenser? It is possible that the pulsing of the coins is causing noise which is interpreted as new coins.

I found it very hard to read your code, since it is so poorly indented.

Use Tools + Auto Format to fix that.

add some debouncing in the coinacceptor

void coinacceptor()  
  if (millis() - pulseTime > 200)  // coins do not enter faster than 5 per second
    pulseTime = millis();   //store current time in pulseTime

2 remarks (pushing the design to extreme)

  • does it work when different coins are inserted in random order and before the dispenser is ready..
  • hopperPulseCount is a byte, so if I throw in 40 pounds quickly I get an overflow?

void coinacceptor()
if (millis() - pulseTime > 200) // coins do not enter faster than 5 per second
pulseTime = millis(); //store current time in pulseTime

Uhm I always thought using millis() inside an ISR function is not a good idea since millis will not increment …

Uhm I always thought using millis() inside an ISR function is not a good idea since millis will not increment ...

It doesn't, which means that you can't use it in a while loop, terminating when some desired interval has elapsed (a.k.a. delay()), but reading it is fine. You'll always get the same value. In this case, that's fine.

Ok,, thanks for all the help.

PaulS - I've aligned the code, sorry about that.

Robtillaart - you have got some great points But I can't even get this working yet, so those issues are true, but will have to be faced next!!

Nick and all of you, thanks for the continued Interest, ideas and support. I've taken a video as I think I've dug a little deeper as to where this error is coming from but not why!!

I've added two new serial,print lines in the loop. When a coin is inserted, I expect to see on the serial monitor the coinPulseCount in its new variable - newCoinInserted printed and then a line which prints the coin value from the switch statement. Instead, I see: coinPulseCount which is correct, printed coin value line which is correct but then a second coinPulseCount line with a new value on it!!!! If this new values matches a switch statement then it ejects more coins!!

A video will explain better - I hate talking but I couldn't explain without.

I've observed the physical pin wit a logic probe and there are no additional pulses on the coin count line so this phantom number is being generated somewhere!!!

Any help appreciated.


Is this a configuration issue? How many pulses does the acceptor send when you insert this coin?

New code:

Wrong. Post your code attached HERE, not on some rubbish site that gets blocked by many people that care about anti-virus efforts.

Please post your current code (here) in code tags.

Edited my original post - removed pastebin link and inserted code. Sorry!

Nick - no it is not a config error as far as the coin acceptor is concerned. Each coin inserted is generating the correct number of pulses which is registering with the arduino and correctly moving into the switch statement. However, the pulseCount variable then increases again to register more pulses- but no extra ones are coming through!

EDIT - you can see the pulse count is correct when the coin is inserted in the video. But then an additional pulse count is given even though no pulses are coming through on this line - or at least that I can detect with my logic probe! And besides, the random pulse count gives numbers that are not programmed into the coin acceptor!


    newCoinInserted = coinPulseCount;  //new variable to free up coinPulseCount on the interrupt.
    Serial.print("newCoinInserted pulses ");
    Serial.println(newCoinInserted);         // print the pulses of the new coin inserted.
    coinPulseCount = 0;                // clear pulse count ready for a new pulse on the interrupt.

A lot of stuff happens between when coinPulseCount is copied and when it is reset. Interrupts should probably be disabled while the copy/reset happens. The copy/reset should definitely happen closer together.

It sounds rather like an electrical issue. What happens if you replace the dispensing relay with an LED and appropriate resistor?

The LED turns ON OK but you dont get to see what happens since there is no optical output from the hopper to dispence any coins - so the way Im setting it up isn`t a good test.

Do I need to set up some sort of physical noise reduction on the input lines. I know little to nothing about electronics so haven`t a clue where to even attempt to take it if this is the issue.


Did you get any bogus pulses from the coin input device with the LED?

If not, I'd be inclined to restore the dispenser and build a subset of your sketch that has the two interrupt routines and just increment counters in each of them, never bothering to reset. Display the counts in loop and call dispense every 5 seconds or so. With so much less code, it'll be more convincing as to whether the issue is electrical.

If it is wiring, post your schematic so that the electronics gurus can check it. I'd be inclined to look at optoisolators, but there may well be a simpler solution.

Here’s my guess. The dispenser is drawing enough current (it probably uses quite a bit) to introduce spikes or voltage drops on the line, making the processor think more input pulses have occurred.

One simple thing would be to detach that interrupt (for the acceptor) prior to dispensing and then reattach after. eg.

void dispence()
  detachInterrupt (1);
  digitalWrite(relayPin, LOW);   //turn on relay - active LOW.
  hopperPulseCount = 0;
  while (hopperPulseCount < coinValue)     { }
  delay(50);    //wait to ensure the coin has enough momentum to leave hopper but not long enough for another coins to dispense!
  digitalWrite(relayPin, HIGH);   //turn off relay - active LOW.        
  EIFR = _BV (INTF1);  // clear flag for interrupt 1  
  attachInterrupt(1, coinacceptor, RISING); 

I should point out too that this will loop infinitely if you run out of coins to dispense. Maybe that’s OK.

I should point out too that this will loop infinitely if you run out of coins to dispense.

But, you can, of course, add sensors and code to test for that condition.