Coin Acceptor false pulse

Hi, im building a cigar vendo however when im about to insert a coin and it makes contact on the surface of coin acceptor cover, it's giving a false pulse. It does it when Im not touching the actual vending cointainer, but when im touching the container itself it works fine. It fixes the issue if i attach a grounding wire, I dont want to keep the grounding wire just to make it work. What can I do?

Im using a ground bus for common ground,

-(disregard servo wire connection from image. Currently using 5v separate power supply for it)

What's wrong with the grounding wire?
Where is that wire in the picture?
Give the servo an extternal power supply. Controllers are designed to supply power.

Seems like we already went through this with your other topic for this coin acceptor.

Unfortunately it comes and go. Maybe when i thought it was working already. I was holding the container while inserting the coins

What do you mean by "bus"
I thought you soldered everything together but you still show a solderless breadboard.

Post your code

#include <Servo.h>
#include <Arduino.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>

Servo brand0Servo;

const int brand0ButtonPin = 4;
const int coinPin = 2;
const int ledPin = 6;  // Red LED
const int insufficientLedPin = 7;  // Green LED
const int irSensorPin = 8;
const int buzzerPin = 10;  // Pin for the buzzer

volatile int impulsCount = 0;
float totalAmount = 0.0;
float coinValue;

const char *brand0Name = "Cigar";
const int brand0Price = 8;

const int coinPulses[] = {1, 2, 5, 10};
const float coinValues[] = {1.0, 2.0, 5.0, 10.0};

LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long previousMillis = 0;
const unsigned long interval = 3000;
int messageState = 0;
bool transactionActive = false;
bool outOfStockDisplayed = false;
bool messageUpdated = false;  // Flag to track message updates
unsigned long ledBlinkMillis = 0;
bool ledState = false;  // For blinking LED

float lookup(int pulses) {
    for (int i = 0; i < sizeof(coinPulses) / sizeof(coinPulses[0]); i++) {
        if (pulses == coinPulses[i]) {
            return coinValues[i];
        }
    }
    return -1;
}

void setup() {
    pinMode(brand0ButtonPin, INPUT_PULLUP);
    pinMode(coinPin, INPUT);
    pinMode(ledPin, OUTPUT);
    pinMode(insufficientLedPin, OUTPUT);
    pinMode(irSensorPin, INPUT);
    pinMode(buzzerPin, OUTPUT);  // Set buzzer pin as output

    attachInterrupt(digitalPinToInterrupt(coinPin), coinInterrupt, FALLING);

    brand0Servo.attach(9);
    brand0Servo.write(60);

    lcd.init();
    lcd.clear();
    lcd.backlight();
    
    Serial.begin(9600);

    checkStockOnBoot();  // Check stock on boot and handle initial state
}

void coinInterrupt() {
    impulsCount++;
}

void checkStockOnBoot() {
    if (digitalRead(irSensorPin) == LOW) {  // Stock available
        resetDisplay();
        outOfStockDisplayed = false;
        messageUpdated = false;  // Allow message toggling
    } else {  // Stock out
        handleOutOfStock();  // Handle out-of-stock state
    }
}

void handleOutOfStock() {
    lcd.clear();
    lcd.setCursor(4, 0);
    lcd.print("OUT OF");
    lcd.setCursor(5, 1);
    lcd.print("STOCK");
    totalAmount = 0.0;
    outOfStockDisplayed = true;
    beepOutOfStock();  // Beep for out of stock
}

void monitorStock() {
    if (digitalRead(irSensorPin) == LOW) {  // Stock available
        if (outOfStockDisplayed) {
            resetDisplay();  // Reset display if stock is replenished
            outOfStockDisplayed = false;
        }
    } else {  // Stock out
        if (!outOfStockDisplayed) {
            handleOutOfStock();  // Handle out-of-stock state
        }
    }
}

bool checkStockBeforeDispense() {
    if (digitalRead(irSensorPin) == LOW) {  // Stock available
        outOfStockDisplayed = false;
        return true;
    } else {  // Stock out
        if (!outOfStockDisplayed) {
            handleOutOfStock();
        }
        return false;
    }
}

void loop() {
    unsigned long currentMillis = millis();

    // Continuously monitor stock availability
    monitorStock();

    // Handle LED blinking when stock is out
    if (outOfStockDisplayed) {
        if (currentMillis - ledBlinkMillis >= 200) {  // Toggle LED every 500ms
            ledBlinkMillis = currentMillis;
            ledState = !ledState;
            if (ledState) {
                digitalWrite(ledPin, HIGH);  // Turn on red LED
                digitalWrite(insufficientLedPin, LOW);  // Turn off green LED
            } else {
                digitalWrite(ledPin, LOW);  // Turn off red LED
                digitalWrite(insufficientLedPin, HIGH);  // Turn on green LED
            }
        }
    } else {
        // Reset the LED to the balance state after transaction
        if (totalAmount <= 7) {
            digitalWrite(ledPin, HIGH);  // Red LED on
            digitalWrite(insufficientLedPin, LOW);  // Green LED off
        } else {
            digitalWrite(ledPin, LOW);  // Red LED off
            digitalWrite(insufficientLedPin, HIGH);  // Green LED on
        }
    }

    // Only update the message after the interval has passed and the message has not been updated
    if (!transactionActive && currentMillis - previousMillis >= interval && !messageUpdated) {
        previousMillis = currentMillis;
        messageState = (messageState + 1) % 2;
        messageUpdated = true;  // Set flag to indicate the message has been updated
        resetDisplay();
    }

    if (impulsCount > 0) {
        coinValue = lookup(impulsCount);
        if (coinValue > 0) {
            totalAmount += coinValue;
            transactionActive = true;
            beepCoinInserted();  // Beep when a coin is inserted
        }

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("  YOUR BALANCE");
        lcd.setCursor(0, 1);
        lcd.print("   Php ");
        lcd.print(totalAmount, 2);

        impulsCount = 0;
    }

    // LED Behavior: Turn on red if insufficient funds, green if sufficient funds
    if (totalAmount >= brand0Price) {
        digitalWrite(ledPin, LOW);  // Turn off red LED
        digitalWrite(insufficientLedPin, HIGH);  // Turn on green LED
    } else {
        digitalWrite(ledPin, HIGH);  // Turn on red LED
        digitalWrite(insufficientLedPin, LOW);  // Turn off green LED
    }

    if (digitalRead(brand0ButtonPin) == LOW) {
        if (totalAmount == 0) {
            displayMessage("Insert Coin", 2000);
            beepInsufficientFunds();  // Beep if insufficient funds
        } else if (totalAmount < brand0Price) {
            displayMessage("Add More Coins", 2000);
            beepInsufficientFunds();  // Beep if insufficient funds
        } else if (outOfStockDisplayed) {
            // If stock is out and button is pressed, show "COME BACK LATER"
            displayMessage("  COME BACK", 1000);
            displayMessage("    LATER", 1000);
        }
    }

    if (digitalRead(brand0ButtonPin) == LOW && totalAmount >= brand0Price && !outOfStockDisplayed) {
        dispenseCigar(brand0Servo, brand0Name, brand0Price);
        beepSufficientFunds();  // Beep when the item is dispensed
    }

    // Reset messageUpdated flag after user interaction to allow toggling
    if (digitalRead(brand0ButtonPin) == LOW || impulsCount > 0) {
        messageUpdated = false;  // Allow message to toggle again after user action
    }
}

void displayMessage(const char *message, int duration) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(message);
    delay(duration);
    resetDisplay();
}

void beepCoinInserted() {
    tone(buzzerPin, 4000, 200);  // Short beep when a coin is inserted
}

void beepSufficientFunds() {
    tone(buzzerPin, 3000, 2000);  // Long beep if funds are sufficient
}

void beepInsufficientFunds() {
    for (int i = 0; i < 3; i++) {
        tone(buzzerPin, 3000, 200);  // Beep 3 times if insufficient funds
        delay(200);
    }
}

void beepOutOfStock() {
    for (int i = 0; i < 50; i++) {
        tone(buzzerPin, 5000, 150);  // Beep 10 times if out of stock
        delay(150);
    }
}

void resetDisplay() {
    if (messageState == 0) {
        lcd.clear();  // Clear display only if necessary
        lcd.setCursor(0, 0);
        lcd.print("  EXACT AMOUNT");
        lcd.setCursor(0, 1);
        lcd.print("      ONLY!");
    } else {
        lcd.clear();  // Clear display only if necessary
        lcd.setCursor(0, 0);
        lcd.print("  CIGAR VENDO");
        lcd.setCursor(0, 1);
        lcd.print("   NO MINORS!");
    }
}

void dispenseCigar(Servo &servo, const char *brandName, int price) {
    int cigars = totalAmount / price;

    for (int i = cigars; i > 0; i--) {
        if (!checkStockBeforeDispense()) {  // Check stock before dispensing
            return;
        }

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Dispensing ");
        lcd.setCursor(0, 1);
        lcd.print(String(brandName) + " " + String(i));

        servo.write(0);
        delay(300);
        servo.write(30);
        delay(300);
        servo.write(0);
        delay(300);
        servo.write(30);
        delay(300);
        servo.write(0);
        delay(300);
        servo.write(30);
        delay(300);
        servo.write(60);
        delay(300);
    }

    totalAmount = 0.0;
    transactionActive = false;
    digitalWrite(ledPin, LOW);
    digitalWrite(insufficientLedPin, LOW);

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("   THANK YOU!");
    delay(2000);
    resetDisplay();
}



not really into electronics, please bear with my diagram

Sounds like it may be a static electricity problem. I suggest you keep the ground wire connected. The ground wire provides a path for the static electricity so that it does not create a pulse. You may also try decreasing the 10K pullup to maybe 3.3K

IINM, it seems like the cover is floating, which can of course create mishaps like that. did you check that the cover is grounded from the accepter ground?

all modules are in the common ground, If I add extra wire from ground to earth, it works fine, without it, it gives false pulse.

ooh it's 220V then

the cover is plastic, I dont see any reason why it should be grounded

it is plastic? hmmm

those three dc's are connected in a one 3 gang outlet to 220v

could you specify what dcs or 3 gang means? excuse my bad english (i'm turkish)

yes it is

I dont know the global term too, but locally we call it that way,
dc adapters, and 3 gang outlet,where you can technically plug 3 different devices

See post #10

If it looks like this, then it is metalized plastic.

10k is what most people with the same projects recommend, but I'll try to lower the resistance and see if it works

It will help increase the noise immunity and make it harder for static to generate a pulse.