Last active
December 2, 2024 02:37
-
-
Save fajarlabs/5a6c8859493c2450a275d7b252de0e61 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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