#include <Arduino.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_Thermal.h>
enum DeviceState {
READY,
PRINTING
};
DeviceState state = READY; // Declare the 'state' variable here
LiquidCrystal_I2C lcd(0x27, 20, 4);
Adafruit_Thermal printer(&Serial);
const int coinPin = 2; // Coin acceptor input
const int vendButtonPin = 3; // Vending button input
const int voucherButtons[] = {4, 5, 6, 7}; // Pins for the 4 voucher buttons
const int voucherRates[] = {5, 10, 15, 20}; // Rates for 30m, 1h, 1.5h, 2h vouchers
const int voucherInventoryAddresses[] = {0, 1, 2, 3}; // EEPROM addresses for inventory
int selectedVoucher = -1; // To track the selected voucher type
int coinsInserted = 0; // To track the coins inserted
int buttonPressed;
String vouchers30min[] = {
"621444", "266543", "655231", /* Add your 30-min voucher codes here */
};
String vouchers1hour[] = {
"561223", "551363", "312253", /* Add your 1-hour voucher codes here */
};
String vouchers1h30min[] = {
"546534", "622656", "344535", /* Add your 1h30min voucher codes here */
};
String vouchers2hours[] = {
"446156", "611426", "541362", /* Add your 2-hour voucher codes here */
};
String usedVouchers30min[100];
String usedVouchers1hour[100];
String usedVouchers1h30min[100];
String usedVouchers2hours[100];
int usedVoucherCount30min = 0;
int usedVoucherCount1hour = 0;
int usedVoucherCount1h30min = 0;
int usedVoucherCount2hours = 0;
void setup() {
Serial.begin(19200);
printer.begin();
lcd.init();
lcd.backlight();
lcd.clear(); // Clear the LCD display
for (int i = 0; i < 4; i++) {
pinMode(voucherButtons[i], INPUT_PULLUP);
}
pinMode(vendButtonPin, INPUT_PULLUP);
pinMode(coinPin, INPUT_PULLUP);
state = READY; // Set the state to READY after initialization
lcd.setCursor(0, 0);
lcd.print(" WIFI VOUCHER VENDO");
// Initialize the inventory values in EEPROM
int initialInventory[] = {100, 100, 100, 100}; // Initialize the last type to 100
for (int i = 0; i < 4; i++) {
EEPROM.write(voucherInventoryAddresses[i], initialInventory[i]);
}
// Read inventory from EEPROM and display it
int inventory[4];
for (int i = 0; i < 4; i++) {
inventory[i] = EEPROM.read(voucherInventoryAddresses[i]);
}
// Display inventory on LCD
lcd.setCursor(0, 1);
lcd.print("Tm: 30m 1H 1.3H 2H");
lcd.setCursor(0, 2);
lcd.print("Rt: ");
for (int i = 0; i < 4; i++) {
lcd.print("P");
lcd.print(voucherRates[i]);
lcd.print(" ");
}
lcd.setCursor(0, 3);
lcd.print("It: ");
for (int i = 0; i < 4; i++) {
lcd.print(inventory[i]);
lcd.print(" ");
}
}
void loop() {
if (state == READY) {
checkButtons();
checkCoinAcceptor();
} else if (state == PRINTING) {
printVoucher();
}
}
// Rest of the code remains the same
void checkButtons() {
for (int i = 0; i < 4; i++) {
if (digitalRead(voucherButtons[i]) == LOW) {
buttonPressed = 1;
selectedVoucher = i;
lcd.clear();
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" WIFI VOUCHER VENDO");
lcd.setCursor(0, 1);
lcd.print("====================");
lcd.setCursor(0, 2);
lcd.print("You've selected ");
lcd.print(voucherRates[i]);
lcd.print("P");
lcd.setCursor(0, 3);
lcd.print("Please Insert Coins");
delay(1000); // Delay for button debounce
state = READY; // Change the state to READY
}
}
}
void checkCoinAcceptor() {
if (digitalRead(coinPin) == LOW) {
coinsInserted += 1;
lcd.setCursor(0, 3);
lcd.print("Coins Inserted: P");
lcd.print(coinsInserted);
delay(100);
}
if(buttonPressed == 1){
if (digitalRead(vendButtonPin) == LOW) {
if (coinsInserted >= voucherRates[selectedVoucher]) {
printVoucher();
removeUsedVoucherCode(selectedVoucher);
} else {
lcd.setCursor(0, 1);
lcd.print("INSUFFICIENT COINS!");
delay(300);
lcd.setCursor(0, 1);
lcd.print("====================");
delay(300);
lcd.setCursor(0, 1);
lcd.print("INSUFFICIENT COINS!");
delay(300);
lcd.setCursor(0, 1);
lcd.print("====================");
delay(300);
state = READY;
}
}
}
}
void printVoucher() {
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0);
lcd.print("Voucher is Printing");
lcd.setCursor(0, 2);
lcd.print("Please wait.");
delay(250);
lcd.setCursor(0, 2);
lcd.print("Please wait..");
delay(250);
lcd.setCursor(0, 2);
lcd.print("Please wait...");
delay(250);
lcd.clear(); // Clear the LCD before printing
lcd.setCursor(0, 0);
lcd.print("Voucher is Printing");
lcd.setCursor(0, 2);
lcd.print("Please wait.");
delay(250);
lcd.setCursor(0, 2);
lcd.print("Please wait..");
delay(250);
lcd.setCursor(0, 2);
lcd.print("Please wait...");
printer.setDefault(); // Reset printer formatting
printer.setSize('L'); // Set larger font size
printer.boldOn();
printer.println("WIFI VOUCHER VENDO");
printer.boldOff();
printer.println();
// Generate and print the voucher code here
String voucherCode = generateVoucherCode(selectedVoucher);
printer.boldOn();
printer.println(voucherCode);
printer.boldOff();
printer.boldOn();
printer.println("How to use:");
printer.boldOff();
printer.println("Open your WiFi");
printer.println("Tap 'WiFi Voucher' SSID");
printer.println("Input the voucher Code");
printer.println("Connect");
printer.println();
printer.println("Enjoy!");
printer.feed(3); // Advance paper
printer.sleep(); // Put the printer to sleep to cut the paper (if supported)
delay(3000); // Delay for the cutting process
// Update inventory and reset selectedVoucher and coinsInserted
int selectedInventory = EEPROM.read(voucherInventoryAddresses[selectedVoucher]);
selectedInventory--;
EEPROM.write(voucherInventoryAddresses[selectedVoucher], selectedInventory);
selectedVoucher = -1;
coinsInserted = 0;
// Set the LCD back to the main display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WIFI VOUCHER VENDO");
int inventory[4];
for (int i = 0; i < 4; i++) {
inventory[i] = EEPROM.read(voucherInventoryAddresses[i]);
}
lcd.setCursor(0, 1);
lcd.print("Tm: 30m 1H 1.3H 2H");
lcd.setCursor(0, 2);
lcd.print("Rt: ");
for (int i = 0; i < 4; i++) {
lcd.print("P");
lcd.print(voucherRates[i]);
lcd.print(" ");
}
lcd.setCursor(0, 3);
lcd.print("It: ");
for (int i = 0; i < 4; i++) {
lcd.print(inventory[i]);
lcd.print(" ");
}
state = READY; // Change the state back to READY for user interaction
}
String generateVoucherCode(int voucherType) {
// Generate a voucher code based on the selected voucher type
String code;
switch (voucherType) {
case 0: // 30 minutes
code = "Voucher-30m-" + String(random(1000, 10000));
break;
case 1: // 1 hour
code = "Voucher-1H-" + String(random(1000, 10000));
break;
case 2: // 1.5 hours
code = "Voucher-1.5H-" + String(random(1000, 10000));
break;
case 3: // 2 hours
code = "Voucher-2H-" + String(random(1000, 10000));
break;
default:
code = "Invalid Voucher";
break;
}
return code;
}
void removeUsedVoucherCode(int voucherType) {
switch (voucherType) {
case 0: // 30 minutes
if (usedVoucherCount30min < 100) {
usedVouchers30min[usedVoucherCount30min++] = vouchers30min[0];
for (int i = 0; i < usedVoucherCount30min; i++) {
vouchers30min[i] = vouchers30min[i + 1];
}
usedVouchers30min[usedVoucherCount30min] = "";
}
break;
case 1: // 1 hour
if (usedVoucherCount1hour < 100) {
usedVouchers1hour[usedVoucherCount1hour++] = vouchers1hour[0];
for (int i = 0; i < usedVoucherCount1hour; i++) {
vouchers1hour[i] = vouchers1hour[i + 1];
}
usedVouchers1hour[usedVoucherCount1hour] = "";
}
break;
case 2: // 1.5 hours
if (usedVoucherCount1h30min < 100) {
usedVouchers1h30min[usedVoucherCount1h30min++] = vouchers1h30min[0];
for (int i = 0; i < usedVoucherCount1h30min; i++) {
vouchers1h30min[i] = vouchers1h30min[i + 1];
}
usedVouchers1h30min[usedVoucherCount1h30min] = "";
}
break;
case 3: // 2 hours
if (usedVoucherCount2hours < 100) {
usedVouchers2hours[usedVoucherCount2hours++] = vouchers2hours[0];
for (int i = 0; i < usedVoucherCount2hours; i++) {
vouchers2hours[i] = vouchers2hours[i + 1];
}
usedVouchers2hours[usedVoucherCount2hours] = "";
}
break;
}
}