user42418: 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.

user359: Make it a state machine:
Initial state is idle, nothing on the tray, no credit
If a coin is entered then it counts the credits and displays it. (Should always be true)
If a button is pushed then only if credit is sufficient and tray is empty will something be vended (and credit is subtracted), otherwise show error for a few seconds.
Showing an error can be done by setting a global and a start time and duration:
long credit;
enum{noError, insufficientCredit, trayError, thankyou};
int error;
unsigned long messageTimestamp;
unsigned long messageDuration;


void updateLCD(){
    if(millis() - messageTimestamp > messageDuration) 
        error=noError;
    switch(error){
    case noError: break;

    case insufficientCredit: 

        //show insufficient credit error
        break;
    case trayError: 

        //show tray error
        break;
    case thankyou: 

        //show thankyou message
        break;
    }

    if(credit == 0){
        //show attract mode
    }else{
        //show credit
    }
}

You can do something similar for the motor:
bool motorOn;
unsigned long motorTimestamp;
unsigned long motorDuration;

if(motorOn && millis() - motorTimestamp> motorDuration){ 
    motorOn = false;
    digitalWrite(shortSize, LOW);//Turn off the feeder motor
}

this way you can also prevent the vending from starting again while the motor is still running by making an extra check on motorOn.

42418: <p>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. </p>

<p>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.</p>

<p>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.</p>

<p>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.</p>

<p><strong>EDIT:</strong> 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. <strong><em>So target is the arduino should wait for coin slot input while waiting for user input at same time.</em></strong></p>

<pre class="lang-cpp prettyprint-override"><code>#include &lt;Wire.h&gt;  // Comes with Arduino IDE, Required for I2C
#include &lt;LiquidCrystal_I2C.h&gt;  //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(" -&gt;Insert Coin&lt;-");
  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) &lt; 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 &amp;&amp; sensorValue &gt; 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 &amp;&amp; sensorValue &gt; 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()
</code></pre>

<p>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.</p>
 359: <p>Make it a state machine:</p>

<p>Initial state is idle, nothing on the tray, no credit</p>

<p>If a coin is entered then it counts the credits and displays it. (Should always be true)</p>

<p>If a button is pushed then only if credit is sufficient and tray is empty will something be vended (and credit is subtracted), otherwise show error for a few seconds.</p>

<p>Showing an error can be done by setting a global and a start time and duration:</p>

<pre><code>long credit;
enum{noError, insufficientCredit, trayError, thankyou};
int error;
unsigned long messageTimestamp;
unsigned long messageDuration;


void updateLCD(){
    if(millis() - messageTimestamp &gt; messageDuration) 
        error=noError;
    switch(error){
    case noError: break;

    case insufficientCredit: 

        //show insufficient credit error
        break;
    case trayError: 

        //show tray error
        break;
    case thankyou: 

        //show thankyou message
        break;
    }

    if(credit == 0){
        //show attract mode
    }else{
        //show credit
    }
}
</code></pre>

<p>You can do something similar for the motor:</p>

<pre><code>bool motorOn;
unsigned long motorTimestamp;
unsigned long motorDuration;

if(motorOn &amp;&amp; millis() - motorTimestamp&gt; motorDuration){ 
    motorOn = false;
    digitalWrite(shortSize, LOW);//Turn off the feeder motor
}
</code></pre>

<p>this way you can also prevent the vending from starting again while the motor is still running by making an extra check on <code>motorOn</code>.</p>
