Currently, the sketch for a coin acceptor works like this:
You insert a quarter. The coin acceptor sends five pulses to the arduino (or whatever you set it to). Then using attach interupt, for every pulse, the arduino adds 5 cents to the money value. Dimes send two pulses, and nickles send 1 pulse. Simple enough.
But here is ultimately what I need: I want a certain number of pulses to mean one thing, while another number of pulses means something different. For example, make a nickle send 4 pulses to the arduino, and make the arduino know that 4 pulses specifically means 5 cents. Not 4 times 5 cents.
Is there a way to do this?
const int coinInt = 0;
//Attach coinInt to Interrupt Pin 0 (Digital Pin 2). Pin 3 = Interrpt Pin 1.
volatile float coinsValue = 0.00;
//Set the coinsValue to a Volatile float
//Volatile as this variable changes any time the Interrupt is triggered
int coinsChange = 0;
//A Coin has been inserted flag
void setup()
{
Serial.begin(9600);
//Start Serial Communication
attachInterrupt(coinInt, coinInserted, RISING);
//If coinInt goes HIGH (a Pulse), call the coinInserted function
//An attachInterrupt will always trigger, even if your using delays
}
void coinInserted()
//The function that is called every time it recieves a pulse
{
coinsValue = coinsValue + 0.05;
//As we set the Pulse to represent 5p or 5c we add this to the coinsValue
coinsChange = 1;
//Flag that there has been a coin inserted
}
void loop()
{
if(coinsChange == 1)
//Check if a coin has been Inserted
{
coinsChange = 0;
//unflag that a coin has been inserted
Serial.print("Credit: £");
Serial.println(coinsValue);
//Print the Value of coins inserted
}
}
Delta_G:
IT already does that. If it gets two pulses you know it is a dime. If it gets 5 pulses you know it is a quarter. You should use millis to keep track of how close together the pulses come. That will tell you if they are from the same coin or not. See how long the 5 pulses for a quarter takes. So you'd mark the time with millis or micros when the interrupt fires and the pulse count is at zero. Then you let loop poll millis or micros against that time and when the length of time has passed you know the full count came from one coin so you can reset the count to zero and then process whatever you want about the coin.
I think I somewhat understand what you're saying. I have never used the millis function. I am a complete noob. Would you be able to show me what you mean with code?
Okay, played around with the millis function. Tried this sketch:
const int coinInt = 0;
//Attach coinInt to Interrupt Pin 0 (Digital Pin 2). Pin 3 = Interrpt Pin 1.
int oldMillis = 0;
volatile float coinsValue = 0.00;
//Set the coinsValue to a Volatile float
//Volatile as this variable changes any time the Interrupt is triggered
int coinsChange = 0;
//A Coin has been inserted flag
int currentMillis = 0;
void setup()
{
Serial.begin(9600);
//Start Serial Communication
attachInterrupt(coinInt, coinInserted, RISING);
//If coinInt goes HIGH (a Pulse), call the coinInserted function
//An attachInterrupt will always trigger, even if your using delays
}
void coinInserted()
//The function that is called every time it recieves a pulse
{
//As we set the Pulse to represent 5p or 5c we add this to the coinsValue
coinsChange = 1;
unsigned long currentMillis = millis();
int difference = currentMillis-oldMillis;
Serial.print("Millis: ");
Serial.println(difference);
oldMillis = currentMillis;
//Flag that there has been a coin inserted
}
void loop()
{
//Print the Value of coins inserted
}
On average, the serial showed there was a 150 millis gap between each pulse from the coin acceptor. The very first "difference" ends up being from the last time I input a coin. Everything following is almost exactly 150 apart.
Millis: 2270
Millis: 150
Millis: 151
Millis: 149
Millis: 151
Millis: 16233
Millis: 151
Millis: 149
Millis: 151
Millis: 150
Now how can I take this and apply it to the code?
All pulses from the same coin arrive < 200ms apart. You can count pulses from 1st until >= 200ms goes by with no pulse. A nickel returns 1 pulse, dime 2, quarter 5. Coins identified, only those three.
You can change the 1, 2, 5 to whatever you can code them to be.
Thank you both for the ideas! Here's what I ended up doing:
const int coinInt = 0;
//Attach coinInt to Interrupt Pin 0 (Digital Pin 2). Pin 3 = Interrpt Pin 1.
int oldMillis = 0;
volatile float coinsValue = 0.00;
//Set the coinsValue to a Volatile float
//Volatile as this variable changes any time the Interrupt is triggered
int coinsChange = 0;
//A Coin has been inserted flag
int currentMillis = 0;
void setup()
{
Serial.begin(9600);
//Start Serial Communication
attachInterrupt(coinInt, coinInserted, RISING);
//If coinInt goes HIGH (a Pulse), call the coinInserted function
//An attachInterrupt will always trigger, even if your using delays
}
void coinInserted()
//The function that is called every time it recieves a pulse
{
//As we set the Pulse to represent 5p or 5c we add this to the coinsValue
coinsChange = 1;
unsigned long currentMillis = millis();
int difference = currentMillis-oldMillis;
Serial.print("Millis: ");
Serial.println(difference);
oldMillis = currentMillis;
if(difference < 152 && difference >148){
coinsValue = coinsValue +0.05;
coinsChange = 1;
}
//Flag that there has been a coin inserted
}
void loop()
{
if (coinsChange == 1){
Serial.print("Money: $");
Serial.println(coinsValue);
coinsChange = 0;
}
//Print the Value of coins inserted
}
It scraps the first pulse. Checks to see if the next pulse is within around 150 millis of the last pulse. If it is, it adds 20 cents. For instance, a quarter now only inputs as 20 cents at this point. However, I moved the amount of pulses for each coin up on the coin acceptor by one.
The reason for this entire bit of code is to eliminate any form of static electricity for a pulse. Unless you manage to shock the front of the machine, TWICE or more, within 150 millis of each other, it will never count static as any amount of money.
Thank you all so much!
A nickel should pulse once. The coin mech should not be affected by static when grounded.
How wide is the pulse itself? Use micros() to measure close, not millis().