Reading the Optical Sensor on a Suzo MKII Coin Hopper

Greetings. I'm having trouble counting the coins exiting a Suzo MKII Coin Hopper. Right now the optical sensor on the hopper pulses multiple times or not at all when coins pass the sensor. For testing, I'm using a Mega 2560 and a button and attempting to press the button and have one coin ejected. Any insight would be appreciated.

Here's my test sketch

int buttonPin = A0;
int hopperRelay = A15;

//Button debouncing Vars
int readButtonPin;             // the current reading from the input pin
int lastButtonPin = HIGH;      // the previous reading from the input pin
long lastDebounceTime = 0;     // the last time the output pin was toggled
byte debounceDelay = 250;      // the debounce time; increase if the output flickers

//interupt 1 aka pin 3
const int hopperInt = 3; 

int startTime = 0;
int coinPay = 0;
int coinPaid = 0;
  
void setup() {
    // put your setup code here, to run once:
    pinMode(hopperRelay, OUTPUT);
    digitalWrite(hopperRelay, HIGH);

    pinMode(buttonPin,INPUT);                     
    digitalWrite(buttonPin,HIGH);

    // If hopperInt goes LOW (a Pulse), call the coinOUT function
    // An attachInterrupt will always trigger, even if your using delays
    pinMode(hopperInt, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(hopperInt), coinOUT, FALLING);
    
    Serial.begin(115200);
    Serial.println("Press the button to Drop a Coin");
    
}

void coinOUT() {
    //Flag that there has been a coin paid
    coinPaid = 1;                           
}

void loop() {
    // put your main code here, to run repeatedly:
    readButtonPin = digitalRead(buttonPin);
    if (readButtonPin != lastButtonPin && ((millis() - lastDebounceTime) > debounceDelay)) {
                lastDebounceTime = millis(); 
                coinPay = 1;           
                Serial.println("Button Pressed.");     
    }
    lastButtonPin= readButtonPin;

    if (coinPay == 1){
        digitalWrite(hopperRelay,LOW); 
        Serial.println("Hopper On");  
        if (coinPaid == 1){                  
            coinPay=0;
            coinPaid=0;
            Serial.println("Coin Paid.");
            Serial.println("Hopper Off");
            digitalWrite(hopperRelay,HIGH);  
        } 
    }
  
}

Is the signal from the hopper really so short you need an interrupt? Polling, like you do with a regular button, is easier.

Start with writing a very simple script that just reads the hopper's signal and prints a "coin inserted" message on the Serial console. Get an idea of what it's really doing. I wouldn't expect it gives multiple pulses for a single coin, but if you find that's what happens, debounce it like you do with your button (50 ms is usually more than enough for that, even 20 ms may do - 250 ms is very long).

Interesting let me give it a try. thanks!

Maybe I have a bad hopper, the optical sensor is HIGH (from my setup) and seems to randomly go LOW even when there are no coins passing.

// pin 2 as optical count input 
int optical_pin = 2;  

//Optical Pin debouncing Vars
int read_optical_pin;
int last_optical_pin;
long last_optical_debounceTime = 0;
byte optical_debounceDelay = 50; 

int haltLoop = 0;

void setup() {
//hopper optical count is an input
pinMode(optical_pin, INPUT_PULLUP);       
//use the internal pullup resistor on the hopper optical input
digitalWrite(optical_pin, HIGH); 
}


// Do this forever...
void loop() {       
    if (haltLoop == 0){
        read_optical_pin = digitalRead(optical_pin);
        Serial.print("Running ");
        Serial.println(read_optical_pin);        
        // stop on change HIGH to LOW        
        if (read_optical_pin != last_optical_pin && ((millis() - last_optical_debounceTime) > optical_debounceDelay)) {
                last_optical_debounceTime = millis();
                Serial.print("Stopped ");
                Serial.println(read_optical_pin); 
                haltLoop = 1;
        }
        last_optical_pin = read_optical_pin;    
    }
}

This is sending a LOW signal even when the hopper is not powered. weird. Need to learn more to see if I can test the hopper signal.

shacomm:

pinMode(optical_pin, INPUT_PULLUP);       

digitalWrite(optical_pin, HIGH);
}

That second line (in setup()) is not necessary; it enables the pullup resistor which you enabled already in the first line.

Your description of the problem indeed points to a faulty hopper - but it could be as simple as a bad connection. In electronics when things fail, they usually fail into a stable mode: such as a short circuit or no signal at all. An unstable signal is often a sign of a poor cable.

Another option may be (shouldn't be, provided you don't have serious interference) is that the built-in pull-up resistor is not strong enough. Replace it with a 10k or even a 1k external pull-up. I don't see any recommendations in the data sheet.

Finally it may help to place a small capacitor between the coin counter output and GND. If these fake signals are really short (according to the data sheet a coin count signal is at least 30 ms) that may help to filter them out.[/code]

Excellent... I found a couple things this code works... for my Suzo MKII Coin Hopper

  1. The hopper uses a physical rocker switch and if the coins are not the correct diameter the switch only partially opens. I tested this by manually moving the switch.

  2. My hopper debounce time was too long.

int pin_hopperRelay = 4;
const int pin_hopperInt = 2;
byte hopperDebounceDelay = 100;
long lastHopperDebounceTime = 0;    
int coinCounter = 0;

void setup() {
   pinMode(hopperRelay, OUTPUT);
   digitalWrite(hopperRelay, HIGH);                        
   pinMode(hopperInt, INPUT_PULLUP);
   Serial.begin(115200);

}

void loop() {
       digitalWrite(pin_hopperRelay, LOW);
       if(digitalRead(pin_hopperInt) == LOW && ((millis() - lastHopperDebounceTime) > hopperDebounceDelay)){
           lastHopperDebounceTime = millis();
           coinCounter++;
           Serial.println(coinCounter);
       }
}

THanks!