#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <Adafruit_Thermal.h>
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h> // Include SoftwareSerial library
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
#define coinSlot 6
#define coinSlotRGBFrame 2
#define buzzer 13
// Define the SoftwareSerial object for the thermal printer on pins 10 and 11
SoftwareSerial printerSerial(10, 11);
Adafruit_Thermal printer(&printerSerial);
int coinSlotStatus;
int pulse;
int buttonState;
boolean userBalance = false;
boolean noCoin = false;
char lcdBuffer[16];
int resetButtonPin = 7;
int lastResetButtonState = HIGH; // variable to store the previous state of the reset button
long lastDebounceTime = 0; // the last time the reset button was pressed
long debounceDelay = 50; // the debounce time in milliseconds
int button = 4;
int val5;
int count5 = 0;
long voucher5[520]; // Array to store voucher 5 PHP
int val10;
int count10 = 0;
long voucher10[520]; // Array to store voucher 10 PHP
int val20;
int count20 = 0;
long voucher20[520]; // Array to store voucher 20 PHP
long lastCoinInsertTime = 0; // Time of last coin insert for debouncing
long coinDebounceDelay = 100; // Coin slot debounce time
// Function to read the voucher count from EEPROM
int readVoucherCount(int address) {
int value;
EEPROM.get(address, value);
return value;
}
// Function to write the voucher count to EEPROM
void writeVoucherCount(int address, int value) {
EEPROM.put(address, value);
}
// Function to reset the EEPROM values for the voucher counts
void resetEEPROM() {
writeVoucherCount(2, 0); // Reset the count for 5 vouchers to 0
writeVoucherCount(4, 0); // Reset the count for 10 vouchers to 0
writeVoucherCount(6, 0); // Reset the count for 20 vouchers to 0
}
// Function to load vouchers from SD card
void loadVouchersFromSD() {
lcd.clear();
lcd.print("Initializing SD...");
if (!SD.begin(10)) { // Initialize SD card with CS pin 10 (adjust if needed)
lcd.clear();
lcd.print("SD init failed");
Serial.println("SD init failed");
return;
}
lcd.clear();
lcd.print("SD init success");
File file = SD.open("vouchers.txt");
if (file) {
lcd.clear();
lcd.print("File opened");
int index5 = 0, index10 = 0, index20 = 0;
while (file.available()) {
String line = file.readStringUntil('\n');
line.trim(); // Remove any extra whitespace
if (line.startsWith("//")) {
continue;
}
long voucherCode = line.toInt();
if (voucherCode > 0) {
if (index5 < 520) {
voucher5[index5++] = voucherCode;
} else if (index10 < 520) {
voucher10[index10++] = voucherCode;
} else if (index20 < 520) {
voucher20[index20++] = voucherCode;
}
}
}
file.close();
lcd.clear();
lcd.print("File closed");
} else {
lcd.clear();
lcd.print("Error opening file");
Serial.println("Error opening file");
}
}
// Function to generate and display voucher
void generateAndDisplayVoucher(int voucherValue, int &voucherCount, long *voucherCodes, int address) {
if (voucherCount < 520) { // Ensure there are vouchers left
lcd.clear();
lcd.print("GENERATING..");
delay(1000);
lcd.clear();
lcd.print("GENERATING....");
delay(1000);
lcd.clear();
lcd.print("GENERATING......");
delay(1000);
lcd.clear();
tone(buzzer, 3000);
delay(200);
noTone(buzzer);
delay(50);
tone(buzzer, 3000);
delay(50);
noTone(buzzer);
// Print "VOUCHER CODE" centered on the first line
int textLength = 14; // Length of " VOUCHER CODE"
int startPosition = (LCD_COLUMNS - textLength) / 2;
lcd.setCursor(startPosition, 0);
lcd.print(" VOUCHER CODE");
// Print the voucher code centered on the second line
sprintf(lcdBuffer, "%ld", voucherCodes[voucherCount]);
int voucherLength = strlen(lcdBuffer);
int voucherStartPosition = (LCD_COLUMNS - voucherLength) / 2;
lcd.setCursor(voucherStartPosition, 1);
lcd.print(voucherCodes[voucherCount]);
delay(10000);
// Print voucher to thermal printer
printer.println("GUSTAVO'S WIFI");
printer.println("Voucher Code:");
printer.println(voucherCodes[voucherCount]);
printer.feed(4);
noCoin = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Thank You! ENJOY");
delay(2700);
tone(buzzer, 3000);
delay(200);
noTone(buzzer);
delay(50);
tone(buzzer, 3000);
delay(50);
noTone(buzzer);
lcd.clear();
pulse = 0; // Reset pulse to 0 after displaying the voucher code
// Increment the voucher count and save to EEPROM
voucherCount++;
writeVoucherCount(address, voucherCount);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("No more vouchers");
delay(3000);
}
}
void setup() {
lcd.begin(LCD_COLUMNS, LCD_LINES);
lcd.backlight();
lcd.clear();
pinMode(buzzer, OUTPUT);
pinMode(coinSlot, INPUT);
pinMode(coinSlotRGBFrame, OUTPUT);
pinMode(resetButtonPin, INPUT);
pinMode(button, INPUT);
printerSerial.begin(9600); // Initialize SoftwareSerial for thermal printer
printer.begin();
tone(buzzer, 262);
delay(100);
tone(buzzer, 294);
delay(100);
tone(buzzer, 330);
delay(100);
tone(buzzer, 349);
delay(100);
tone(buzzer, 392);
delay(100);
tone(buzzer, 440);
delay(100);
tone(buzzer, 494);
delay(100);
tone(buzzer, 563);
delay(500);
noTone(buzzer);
delay(1000);
// Initialize EEPROM values for voucher counts if they are uninitialized (equals -1)
int tempCount;
tempCount = readVoucherCount(2);
if (tempCount != -1) {
count5 = tempCount;
}
tempCount = readVoucherCount(4);
if (tempCount != -1) {
count10 = tempCount;
}
tempCount = readVoucherCount(6);
if (tempCount != -1) {
count20 = tempCount;
}
loadVouchersFromSD(); // Load vouchers from SD card
}
void loop() {
// Read the reset button state with button debouncing
int reading = digitalRead(resetButtonPin);
if (reading != lastResetButtonState) {
// Reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading == LOW && lastResetButtonState == HIGH) {
resetEEPROM(); // Call the resetEEPROM function when the button is pressed
}
}
lastResetButtonState = reading;
if (!noCoin) {
noCoin = true;
lcd.setCursor(0, 0);
lcd.print(" GUSTAVO`S WIFI");
lcd.setCursor(0, 1);
lcd.print(" INSERT COINS");
digitalWrite(coinSlotRGBFrame, HIGH);
}
buttonState = digitalRead(button);
if (buttonState == 1 && pulse == 5 && userBalance) {
generateAndDisplayVoucher(5, count5, voucher5, 2);
}
if (buttonState == 1 && pulse == 10 && userBalance) {
generateAndDisplayVoucher(10, count10, voucher10, 4);
}
if (buttonState == 1 && pulse == 20 && userBalance) {
generateAndDisplayVoucher(20, count20, voucher20, 6);
}
coinSlotStatus = digitalRead(coinSlot);
delay(30);
// Debounce the coin slot to avoid counting multiple pulses from one insert
if (coinSlotStatus == LOW && (millis() - lastCoinInsertTime) > coinDebounceDelay) {
pulse += 5;
userBalance = true;
lastCoinInsertTime = millis();
}
}