/*
Forum: https://forum.arduino.cc/t/pass-the-pulse-from-coin-acceptor-to-coffee-vending-machine-using-arduino-esp32/1178550
Wokwi: https://wokwi.com/projects/378917741462749185
*/
#include "MCAEmulation.h"
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
constexpr byte resetAmountPin = 5;
constexpr byte coinPin = 2;
constexpr byte CoinTypes = 4;
constexpr int coinPulses[CoinTypes] = {1, 2, 5, 10};
constexpr float coinValue[CoinTypes] = {1.0, 2.0, 5.0, 10.0};
volatile int impulseCountISR = 0;
volatile unsigned long lastPulseISR;
constexpr unsigned long WaitAfterLastPulseDetected = HIGHTIME+LOWTIME+10;
int impulseCount = 0;
unsigned long lastPulse;
int coinType = 0;
float totalAmount = 0.0;
void IRAM_ATTR coinInterrupt() {
impulseCountISR++;
lastPulseISR = millis();
}
void setup() {
Serial.begin(115200);
pinMode(resetAmountPin, INPUT_PULLUP);
pinMode(coinPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(coinPin), coinInterrupt, FALLING);
lcd.init();
lcd.backlight();
Serial.println("Start");
printAmount();
}
void loop() {
// Only required for testing START
MCAEmulation();
// Only required for testing END
if (coinInserted()) {
totalAmount += lookup(impulseCount);
printAmount();
}
checkResetAmount();
}
void printAmount() {
Serial.print("Total Amount: ");
Serial.println(totalAmount, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Total Balance: ");
lcd.setCursor(0, 1);
lcd.print(totalAmount, 2);
}
int lookup(int pulses) {
for (int i = 0; i < CoinTypes; i++) {
if (pulses == coinPulses[i]) {
return coinValue[i];
}
}
return 0;
}
void getISRData() {
noInterrupts();
impulseCount = impulseCountISR;
lastPulse = lastPulseISR;
interrupts();
}
void clearISRData() {
noInterrupts();
impulseCountISR = 0;
interrupts();
}
boolean coinInserted() {
boolean result = false;
getISRData();
if (impulseCount > 0 && millis() - lastPulse > WaitAfterLastPulseDetected) {
clearISRData();
result = true;
}
return result;
}
void checkResetAmount() {
static byte state = HIGH;
static byte lastState = HIGH;
static unsigned long lastChange;
byte actState = digitalRead(resetAmountPin);
if (actState != lastState) {
lastChange = millis();
lastState = actState;
}
if (actState != state && millis() - lastChange > 30) {
state = actState;
if (!state) {
totalAmount = 0.0;
printAmount();
}
}
}
1
2
5
10
Reset