I have this project called Onionskin Vending machine. The function should be: when a coin is inserted, the pulses from the coin acceptor (which is not accurate sometimes so i didn't use attachInterrupt) is recorded by the Arduino and is shown to the user as Credits. then while still waiting for coin input, it will ask the user to select a product.
EX. Scenario 1: The user drops a 1cent coin, then the machine will show the user its credit as 1cents and will ask to press a button. the user will press a button then the machine will turn on a motor for (X) seconds to dispense product and say thank you then resets again.
EX. Scenario 2: The user drops a 5cent coin, then the machine will show the user its credit as 5cents and will ask to press a button. then the user will drop again a 1cent coin so the machine will show its credit as 6cents and will again ask to press a button. the user will press a button then the machine will turn on a motor for (6X) seconds to dispense product and say thank you then resets again.
Here is the code I wrote so far, but the problem is when activated, it only records the first cent/pulse then goes on waiting for user input to press a button, even if I drop more coins, it will not count the new coins inserted, only always the 1cent / 1 Credit is displayed.
EDIT: There is no target credit, 1cents would do. but if user drop 2cents, then 2 Sets of product should be dispensed upon user selection of product. So target is the arduino should wait for coin slot input while waiting for user input at same time.
#include <Wire.h> // Comes with Arduino IDE, Required for I2C
#include <LiquidCrystal_I2C.h> //Call LCD I2C Library
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address Set up data transmission from microcontroller to LCD
int coinPin = 2; //Defined as the receiving pin from the coin machine.
int coinState = 0; //Determine the status of coinPin
int credits = 0; //Define a variable to display the credit.
int delayTime = 0; //Define delay variable for number of onionskin sheet feed duration
int resetPin = 12; //Define reset pin for resetting after complete function
int sensorPin = A0; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor
const int laserPin = 6;
const int shortSizeFeedTime = 5000; //Duration for 2pc onionskin to pass feeder
const int longSizeFeedTime = 7500; //Duration for 3pc onionskin to pass feeder
const int ledpin = 13; //define LED Pin at pin13
const int ButtonS = 8; //Define button for short onionskin
const int ButtonL = 7; //Define button for long onionskin
const int shortSize = 9; //Define pin for motor pin shortSize
const int longSize = 10; //Define pin for motor pin longSize
void setup()
{
digitalWrite(resetPin, HIGH);
delay(200);
pinMode(coinPin, INPUT); //Determine the function of the buttton pin to the input pin.
pinMode(resetPin, OUTPUT); //Set Reset PIN as OUTPUT
pinMode(shortSize, OUTPUT);
pinMode(longSize, OUTPUT);
pinMode(laserPin, OUTPUT); //Laser PIN
/*
lcd.begin(16, 2); //Schedule your columns and rows. LCD
lcd.setCursor(4,0); //Set the cursor's starting position at position(4,0)
lcd.print("WELCOME"); //Display screen text LCD
lcd.setCursor(0,1); //Set the cursor's starting position at position(0,1)
lcd.print("PLZ INSERT COIN"); //Display screen text LCD
*/
Serial.begin(9600); // Begin Serial Connection to PC
lcd.begin(16, 2); // initialize the lcd for 16 chars 2 lines, turn on backlight
pinMode(ButtonS, INPUT_PULLUP);
pinMode(ButtonL, INPUT_PULLUP);
digitalWrite(laserPin, HIGH);// used as a laser trip wire sensor
start(); //GOTO Start FUNCTION
//delay(8000);
// Wait and then tell user they can start the Serial Monitor and type in characters to
// Display. (Set Serial Monitor option to "No Line Ending")
//lcd.clear();
//lcd.setCursor(0,0); //Start at character 0 on line 0
}
void start()
{
//-------- Write characters on the display ------------------
// NOTE: Cursor Position: (CHAR, LINE) start at 0
lcd.clear();
lcd.setCursor(4, 0); //Start at character 4 on line 0
lcd.print("WELCOME!");
delay(1000);
lcd.setCursor(0, 1);
lcd.print(" ->Insert Coin<-");
loop();
}
void loop()
{
sensorValue = analogRead(sensorPin);//read the status of the LDR attached to the analog pin for laser trip wire
coinState = digitalRead(coinPin); //coinPin value In the coinState
lcd.setCursor(0, 0); //Set the cursor's starting position at position(0,0)
while (analogRead(sensorPin) < 1000)
{
lcd.clear();
lcd.print("PLS. REMOVE ANY");
lcd.setCursor(0, 1);
lcd.print("OBJECT FRM TRAY!");
delay(2000);
start();
}
if (coinState == LOW) //Condition
{
credits += 1; //Calculate the value of the variable. It will increase each time. 5
delay(500); //Delay schedule 500ms.
lcd.clear(); //Clear command all LCD screen
lcd.print("CREDIT:"); //Display LCD Display Message
lcd.setCursor(8, 0); //Set the cursor's starting position at position(8,0)
lcd.print(credits); //Displays the value of variable "credit" on the LCD screen.
lcd.setCursor(12, 0); //Set the cursor's starting position at position(8,0)
lcd.print("PHP"); //Display screen text LCD
lcd.setCursor(0, 1);
lcd.print("PRESS TO PROCEED");
//Wait for button input from user
while (digitalRead(ButtonS) == HIGH || digitalRead(ButtonL) == HIGH) {
//---------Servo A----------------
if (digitalRead(ButtonS) == LOW && sensorValue > 1000) {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("VENDING:");
lcd.setCursor(0, 1);
lcd.print("LONG ONIONSKIN");
delayTime = credits * longSizeFeedTime;
digitalWrite(longSize, HIGH);//Turn on the feeder motor
delay(delayTime); //calculation time for 2pc of onionskin
digitalWrite(longSize, LOW);//Turn off the feeder motor
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("THANK YOU!");
lcd.setCursor(0, 1);
lcd.print("PLS. COME AGAIN!");
credits = 0;//set the credits back to zero
delay(3000);
digitalWrite(resetPin, LOW);//optional for activation harware reset pin
start();//GO to start function, kind of reset
break;//this never actually happens :)
} // when item is dispensed exit loop and return to wait for coin
//---------Servo B-------------
else if (digitalRead(ButtonL) == LOW && sensorValue > 1000) {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("VENDING:");
lcd.setCursor(0, 1);
lcd.print("SHORT ONIONSKIN");
delayTime = credits * shortSizeFeedTime;//calculation time for 2pc of onionskin
digitalWrite(shortSize, HIGH);//Turn on the feeder motor
delay(delayTime);
digitalWrite(shortSize, LOW);//Turn off the feeder motor
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("THANK YOU!");
lcd.setCursor(0, 1);
lcd.print("PLS. COME AGAIN!");
credits = 0;
delay(3000);
digitalWrite(resetPin, LOW);//optional for activation harware reset pin
start();//GO to start function, kind of reset
break;//Again, this never happens :)
}
}//End While Loop
}//End If coin detect loop
}//End void loop()
PS: I have read somewhere that using millis could help solve the dual running problem or by using the correct while or switch-case loop. I'm not familiar much about how while, do-while, for, switch loops work.
