Problem with attachInterrupt

I have a very simple setup with a coin acceptor machine that gives out pulses depending on the type of coin inputted. The first of the coin acceptors outputs triggers for every coin. The other outputs trigger for specific coins (like a 1 euro coin for example).

The problem I'm having is that the attachInterrupt only works for the first output that triggers for every coin. I can't figure out why it won't trigger for the other outputs.

Here is the code that I'm using:

const int coinAcceptorPin = 2; // White
const int kiddieCoinPin = 4; // Red
const int euroCoinPin = 8; // Yellow

// Count value of the coins
int valueCount = 0;

void setup() {
  Serial.begin(9600);

  // Turn off LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  // Set pin modes and attach interrupts
  pinMode(coinAcceptorPin, INPUT_PULLUP);
  pinMode(kiddieCoinPin, INPUT_PULLUP);
  pinMode(euroCoinPin, INPUT_PULLUP);
  
  attachInterrupt(digitalPinToInterrupt(coinAcceptorPin), incomingPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(kiddieCoinPin), kiddieCoin, FALLING);
  attachInterrupt(digitalPinToInterrupt(euroCoinPin), euroCoin, FALLING);
}

void loop() {
  Serial.println(valueCount);
}

void incomingPulse() {
  valueCount += 1;
}

void kiddieCoin() {
  valueCount += 1000;
}

void euroCoin() {
  valueCount += 100;
}

At first I was logging information with the Serial.println function, but I read this shouldn't be done in the functions called by attachedInterrupt because it might give problems with locking of the Arduino. When I did this, logging the digitalRead(euroCoin) status showed me the Arduino did change the value from 1 to 0 when the right coin was inserted into the coin acceptor.
To prevent Serial prints giving issues I'm now working with a counter that should give a very clear indication of which function is being triggered.

Also, I've used my multimeter to check all the outputs. I can see a clear drop from ~5v to ~2.5v when inserting a coin.

Hopefully someone can shed some light on it, thanks for helping!

which board are you using?

BOARD DIGITAL PINS USABLE FOR INTERRUPTS
Uno, Nano, Mini, other 328-based 2, 3
Uno WiFi Rev.2, Nano Every all digital pins
Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21 (pins 20 & 21 are not available to use for interrupts while they are used for I2C communication)
Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7
Zero all digital pins, except 4
MKR Family boards 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Nano 33 IoT 2, 3, 9, 10, 11, 13, A1, A5, A7
Nano 33 BLE, Nano 33 BLE Sense all pins
Due all digital pins
101 all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE)
1 Like

valueCount must be declared volatile since its changed by the interrupt.

If you are using an 8 bit Arduino then you'll need to read valueCount safely in loop() too, since its two bytes you don't want an interrupt to happen between reading the bytes:

void loop() {
  noInterrupts() ;  // critical section
  int my_count = valueCount ;
  interrupts () ;   // end critical section
  Serial.println(my_value);
}
1 Like

Hi @l1quor1ce
its variable is set to "int". " int valueCount = 0; "
"If you are using"Arduino Uno (and other ATmega based boards) an int stores a 16-bit (2-byte) value.
this makes it have a range of -32,767 to 32,767.
This means if you have more than 32 interrupts that call the routine "void kiddieCoin() {" your sketch will have negative values.
Solutions:
"unsigned int valueCount = 0; "
range from 0 to + 65,535

"long valueCount = 0; "
range from - 2,147,483,647 to + 2,147,483,647

"unsigned long valueCount = 0; "
range from 0 to + 4,294,967,295

RV mineirin

we still don’t know what board OP is using, on 32 bit microprocessor int is 32 bit int - Arduino Reference

OK, tks
I corrected my post with the following sentence:
"Arduino Uno (and other ATmega based boards) an int stores a 16-bit (2-byte) value."
RV mineirin

-32768 to 32767

Okay, this makes a lot of sense. I'm using two different Arduino's, the Uno and Uno Wifi Rev.2.

The Wifi Rev.2. is having some issues so therefore I switched to the other Arduino, not knowing the pin situation was so different and I couldn't use them all for interrupts.

Now then, I've got it working on pin 2 and 3 so that's good. The only problem is that sometimes it's completely accurate, but sometimes it counts a coin more than once (calls the interrupt function twice or more). I guess this is because the lowering of the voltage isn't immediate?

Any way I can regulate this so it becomes a bit more reliable?

Thanks for the helpful comments, really makes it a lot easier for me to figure out what is going on :+1:

If these pulses are the result of a mechanical action then I'm not surprised if there is some bounce. I don't see why you even need to use interrupts. You could read the inputs as if they were switches, i.e. look for a HIGH to LOW transition then debounce. That might take care of your issue.

See StateChangeDetection

1 Like

Thanks for that idea, it works way better than the interrupts for what I'm trying to do!