Vending using the DG600F(s) 6 coin acceptor

Hi all.

I am building a vending machine and have gotten my hands on the adafruit 6 coin acceptor (DG600F).

As a Noob I know my script can be a lot better (arays etc) but at this stage I am struggling to get it to do what I am asking it to do and for that I am looking for some help.

The plan is my UNO connected to a 16X2 LCD screen, a 4x4 keypad an LED, 4 motors via relays and of course the coin acceptor. The user process will be insert coins, the LCD will output that there is enough coins to make a credit and the user will be prompted to press 1-4 on the keypad and an LED will confirm the keypad is active. This will activate the motor for a set time turning it to dispense the chocolate. The user can then repeat the process or select another option if there is more credits already.

So far I have had a few variations of the code and non of them have been 100% successful. Whilst this current version of the code isn’t great I can not see why it is behaving the way it is.

Issues I am facing:

  • The code is running and on serial monitor I am seeing the coin acceptor report ready and power on, giving me the impression that the first part of my script is working well.
  • As soon as this comes up it then detects a coin that isn’t there and deducts a coin. It is then putting my coins in negative but is not adding or subtracting a credit.
  • This is putting me in a loop and even then when I insert a coin it is not registering and never gets to the point where the LED lights up.
  • The LCD is not changing and is effectively stuck on “insert $$”. Even in my previous incarnations it would stick here even when there was positive credit.

In a previous incarnation of the code this was working well and would get to the point where I inserted coins and even got credits to register but when it got to my product cost it would act like a button had been pressed and the relay would activate. In fairness I copied the code from one to the other and have been back and compared and can not find anything different other than I am using the keypad not the buttons in my new version. (Happy to post the previous version if that will help just let me know).

I have previously built up to this so used examples to code just the keypad, the LCD, the relays etc and have had them independently working. This is my first attempt using the serial incoming from the coin acceptor so I am not 100% confident that this is not where my issue lies.

Any advice or support is greatly appreciated. I am learning as I go so please forgive if I have forgotten anything or need clarification of answers. Thank you all in advance.

The code currently is:

// Include the library codes:

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <Keypad.h> // include keypad library

// Initialise the library by associating any needed LCD interface pin and buttons to arduino pins
LiquidCrystal lcd (A0, A1, A2, A3, A4, A5); // pins of the LCD. (RS, E, D4, D5, D6, D7)

// Identify where coin acceptor Serial is.
SoftwareSerial mySerial(2,3); //Rx, Tx

// set where the contsant devices are that wont change
const int led1 = 13; // light on led button
const int motor1 = 5; //relay in 1
const int motor2 = 4; //relay in 2
const int motor3 = 1; //relay in 3
const int motor4 = 0; //relay in 4
const byte rows = 4;
const byte cols = 3;

// set any intergers you need, set base lines as well.
int incomingByte = 0;
int productCost = 400;
int credit = 0;
int total = 0;
int sell = (led1, HIGH);
int pozisyon = 0;

char keyMap [rows] [cols] = { //define the cymbols on the buttons of the keypad

  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins [rows] = {12, 11, 10, 9}; //pins of the keypad
byte colPins [cols] = {8, 7, 6};

Keypad keypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);

void setup() {
  //initial code to set everything up
  lcd.begin(16,2); //turns on LCD and sets 2 lines of 16 characters
  pinMode (led1, OUTPUT); //sets the led on button to output
  pinMode (motor1, OUTPUT); //sets the relay as output
  pinMode (motor2, OUTPUT);
  pinMode (motor3, OUTPUT);
  pinMode (motor4, OUTPUT);
  Serial.begin(9600); //gets the software serial terminal working for debugging
  Serial.println("Coin Acceptor Ready!");
  Serial.println("Power On!");
  
  mySerial.begin(4800); //sets the incoming coin acceptor baud rate
//Keypad.addEventListener(keypadEvent);
  
}
//Main loop codes
void loop() {
   
  
  int i; //sets i as an interger value for later
  lcd.clear();
  lcd.print("Please insert $");
  delay(300);

    if (mySerial.available());
    {
      i=mySerial.read();
      //if (i !=255)
      
        total = total + i;
        Serial.print("Coin detected was $");
        Serial.println(i, DEC);
        Serial.print("Total is now $");
        Serial.println(total);
        Serial.print("running credits");
        Serial.print(credit);
        
        }
        if (total == productCost) {
          credit = credit + 1;
          total = total - productCost;
          Serial.print("Credits available - ");
        Serial.println(credit);
          delay(1000);
        }
  

  
    if (credit >= 1) {
  digitalWrite(led1, HIGH);
  lcd.clear ();
  lcd.print("Select snack");
  lcd.setCursor(0, 1);
  lcd.print(credit);
  lcd.print(" allowed!");
  //Serial.println("Buttons Active");
  //delay(20);
}

//break;
    

char key = keypad.getKey();

switch (key) {
  case '1': 
  if (credit >= 1) {
  digitalWrite(motor1, HIGH);
      delay(1000);
      digitalWrite(motor1, LOW);
      credit = credit - 1;
      lcd.print("Enjoy!");
      Serial.println("Snack Delivered");
      Serial.println("Credits Available = ");
      Serial.print(credit);
      digitalWrite(led1, LOW); 
}
else {
  lcd.clear();
  lcd.print("please insert $");
}
  break;
  case '2': 
   if (credit >= 1) {
  digitalWrite(motor2, HIGH);
      delay(1000);
      digitalWrite(motor2, LOW);
      credit = credit - 1;
      lcd.print("Enjoy!");
      Serial.println("Snack Delivered");
      Serial.println("Credits Available = ");
      Serial.print(credit);
      digitalWrite(led1, LOW); 
}
else {
  lcd.clear();
  lcd.print("please insert $");
}
  break;
  
  case '3': 
    if (credit >= 1) {
  digitalWrite(motor3, HIGH);
      delay(1000);
      digitalWrite(motor3, LOW);
      credit = credit - 1;
      lcd.print("Enjoy!");
      Serial.println("Snack Delivered");
      Serial.println("Credits Available = ");
      Serial.print(credit);
      digitalWrite(led1, LOW); 
}
else {
  lcd.clear();
  lcd.print("please insert $");
}
  break;
  
  case '4': 
    if (credit >= 1) {
  digitalWrite(motor4, HIGH);
      delay(1000);
      digitalWrite(motor4, LOW);
      credit = credit - 1;
      lcd.print("Enjoy!");
      Serial.println("Snack Delivered");
      Serial.println("Credits Available = ");
      Serial.print(credit);
      digitalWrite(led1, LOW); 
}
else {
  lcd.clear();
  lcd.print("please insert $");
}
  break;

  default:
  break;
}

  }

You are integrating a number of components into a single sketch which has now got quite complex and you are getting logic errors and it is difficult to follow.
It appears that you have got the LCD right because you get a message on it.
But your error description is focused on the logic to handle the coin acceptor. My suggestion is that you create a new sketch which handles only the coin acceptor logic (that is without LCD; Keypad, Relays etc.) and imbed lots of Serial.print statements so you see what it is doing.
Once that works, start adding the LCD and then other components.

I've also noticed this:

//bad pins to use as these are used for Serial
const int motor3 = 1; //relay in 3
const int motor4 = 0; //relay in 4

//unusual
int sell = (led1, HIGH);

It may be too early for you, but eventually you’ll see the sense in a state-machine, to keep track of what has happened, what is happening, and what needs to happen next.

6v6gt’s suggestion is correct.
Break your code apart (keep a copy of what you have so far!)
Then you’ll know that each function() operates reliably and independently, and you can tie them together.

6v6gt:
You are integrating a number of components into a single sketch which has now got quite complex and you are getting logic errors and it is difficult to follow.
It appears that you have got the LCD right because you get a message on it.
But your error description is focused on the logic to handle the coin acceptor. My suggestion is that you create a new sketch which handles only the coin acceptor logic (that is without LCD; Keypad, Relays etc.) and imbed lots of Serial.print statements so you see what it is doing.
Once that works, start adding the LCD and then other components.

Thanks :). I have had the coin acceptor working in a previous incarnation of the sketch. I then used that to build this one. I think you are spot on that it is complex and that is what is causing the issue. I originally built this from smaller sketches (LCD, Relay, Keypad etc) and individually I have been getting them to work, it is when I integrated them I started having issues.

This is the first attempt at using the switch command and also a sketch that does staged things one after the other. I think that is where my issue is but I have yet to be able to identify it.

Ill break it apart again and see if I can try a new draft. If you are happy I will post the new sketch and see what you think on version 100 :slight_smile:

Really appreciate the guidance.

Along with the other suggestions, I did notice this:

    if (mySerial.available());
    {
      i=mySerial.read();
      //if (i !=255)
      ...

which will always be executed because of the semicolon at the end of the if() statement.

Also, choosing better variable names may help. 'led1' doesn't tell you anything about what it is or what is should be doing. Same for 'mySerial' and 'motor1', 'motor2' etc.

I'd use names like 'ledCredit' (since I think you light it up when there are credits)...

Good luck!