Skip to content

Instantly share code, notes, and snippets.

@fajarlabs
Last active December 2, 2024 02:37
Show Gist options
  • Save fajarlabs/5a6c8859493c2450a275d7b252de0e61 to your computer and use it in GitHub Desktop.
Save fajarlabs/5a6c8859493c2450a275d7b252de0e61 to your computer and use it in GitHub Desktop.
#include <LCD_I2C.h>
#include <TimeOut.h>
#define BUZZER 2
#define CONTACT_RELAY 3
#define COIN_PIN 9
#define PULSE1 120 // 2 menit / 600 detik
#define PULSE5 120 // 10 menit / 600 detik
#define PULSE10 120 // 10 menit / 600 detik
// interfaces function
void clearLine(int line);
void coinInterrupt();
bool delayNonBlocking(unsigned long interval);
bool countdownHandler(int* time);
void callback0();
// Set var timeout
TimeOut timeout0;
// initial display 16x2
LCD_I2C lcd(0x27, 16, 2); // Default address of most PCF8574 modules, change according
// coin time variable
unsigned long lastCoinTime = 0; // Last time a coin was detected
const unsigned long coinDebounceTime = 500; // Debounce time in milliseconds
volatile int coinCount = 0; // Counter for coin pulses
// pulse count
int pulseCount = 0;
// time counter
unsigned long CTR_previousMillis = 0; // Waktu sebelumnya
const long CTR_interval = 1000; // Interval 1 detik dalam milidetik
int CTR_countdown = 0; // Waktu awal countdown (dalam detik)
// Karakter khusus untuk simbol asap
byte smokeSymbol[8] = {
0b00100, // Baris 1: Titik asap atas
0b01010, // Baris 2: Pola asap melengkung
0b10101, // Baris 3: Pola asap melengkung
0b00100, // Baris 4: Pola menurun
0b01010, // Baris 5: Pola melengkung
0b00000, // Baris 6: Kosong
0b00100, // Baris 7: Titik asap bawah
0b00000 // Baris 8: Kosong
};
void setup() {
Serial.begin(9600);
Serial.println(F("Startup"));
timeout0.timeOut(1000, callback0); //delay, callback function
lcd.begin(); // If you are using more I2C devices using the Wire library use lcd.begin(false)
// this stop the library(LCD_I2C) from calling Wire.begin()
lcd.backlight();
// clear line 0-1
clearLine(0);
clearLine(1);
// set text to LCD
lcd.setCursor(0, 0);
lcd.print("* Fog Machine *");
lcd.setCursor(0, 1);
lcd.print(" version 1.0.0 ");
pinMode(CONTACT_RELAY, OUTPUT);
pinMode(BUZZER, OUTPUT);
// Coin Acceptor
pinMode(COIN_PIN, INPUT_PULLUP);
// Aktifkan Pin Change Interrupt untuk PORTB
PCICR |= (1 << PCIE0); // Aktifkan PCI untuk PORTB
PCMSK0 |= (1 << PCINT1); // Aktifkan interrupt untuk pin 9 (PCINT1)
// Aktifkan global interrupt
sei();
delay(1000);
// clear line 0-1
clearLine(0);
clearLine(1);
// buat character di index 0
lcd.createChar(0, smokeSymbol);
// set text to LCD
lcd.setCursor(0, 0);
lcd.write(byte(0)); // Menampilkan simbol koin
lcd.setCursor(1, 0);
lcd.print(" Insert Coin ");
lcd.setCursor(14, 0);
lcd.write(byte()); // Menampilkan simbol koin
}
void loop() {
// Panggil fungsi countdown
if (countdownHandler(&CTR_countdown)) {
Serial.print("Waktu tersisa: ");
Serial.println(CTR_countdown);
if (CTR_countdown > 0) {
clearLine(1);
lcd.setCursor(0, 1);
if (CTR_countdown < 11) {
if (CTR_countdown % 2 == 0) {
//digitalWrite(BUZZER, HIGH);
} else {
//digitalWrite(BUZZER, LOW);
}
}
lcd.print(CTR_countdown);
lcd.print(" Seconds");
// if (CTR_countdown > 60) {
// float count_minutes = (float)CTR_countdown/(float)60;
// Serial.println(count_minutes);
// lcd.print(round(count_minutes));
// lcd.print(" Minutes");
// } else {
// if(CTR_countdown < 11){
// if (CTR_countdown % 2 == 0) {
// //digitalWrite(BUZZER, HIGH);
// } else {
// //digitalWrite(BUZZER, LOW);
// }
// }
// lcd.print(CTR_countdown);
// lcd.print(" Seconds");
// }
digitalWrite(CONTACT_RELAY, HIGH);
} else {
digitalWrite(BUZZER, LOW); // stop buzzer
// clear LCD
clearLine(0);
clearLine(1);
// set text to LCD
lcd.setCursor(0, 0);
lcd.write(byte(0)); // Menampilkan simbol koin
lcd.setCursor(1, 0);
lcd.print(" Insert Coin ");
lcd.setCursor(14, 0);
lcd.write(byte()); // Menampilkan simbol koin
digitalWrite(CONTACT_RELAY, LOW);
}
}
TimeOut::handler();
}
void callback0() {
Serial.print(F("Pulse count :"));
Serial.println(pulseCount);
// Pilih jenis koin dan terapkan nominalnya
if (pulseCount == 1) {
clearLine(0);
clearLine(1);
lcd.setCursor(0, 0);
lcd.print("Remaining Time :");
CTR_countdown += PULSE1;
} else if (pulseCount == 5) {
clearLine(0);
clearLine(1);
lcd.setCursor(0, 0);
lcd.print("Remaining Time :");
CTR_countdown += PULSE5;
} else if (pulseCount == 10) {
clearLine(0);
clearLine(1);
lcd.setCursor(0, 0);
lcd.print("Remaining Time :");
CTR_countdown += PULSE10;
} else {
// CTR_countdown = 0;
}
pulseCount = 0; // reset to 0
}
// ISR untuk PORTB Pin Change Interrupt
ISR(PCINT0_vect) {
// Periksa apakah pin 9 yang berubah
if (PINB & (1 << PB1)) {
timeout0.cancel();
pulseCount++;
timeout0.timeOut(1000, callback0);
}
}
// Function to clear a specific line on the LCD
void clearLine(int line) {
lcd.setCursor(0, line); // Move to the start of the specified line
lcd.print(" "); // Print 16 spaces (clears the line)
lcd.setCursor(0, line); // Move the cursor back to the start of the line
}
bool delayNonBlocking(unsigned long interval) {
static unsigned long lastTime = 0; // Variabel static untuk menyimpan waktu terakhir
unsigned long currentTime = millis();
if (currentTime - lastTime >= interval) {
lastTime = currentTime; // Reset waktu terakhir
return true; // Interval tercapai
}
return false; // Interval belum tercapai
}
// Fungsi untuk menangani countdown
bool countdownHandler(int* time) {
unsigned long CTR_currentMillis = millis();
if (CTR_currentMillis - CTR_previousMillis >= CTR_interval) {
CTR_previousMillis = CTR_currentMillis;
if (*time > 0) {
(*time)--; // Kurangi waktu countdown
return true; // Indikasikan bahwa waktu telah berubah
}
}
return false; // Tidak ada perubahan waktu
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment