// C++ code
//
#include <Wire.h>
#include <Adafruit_PCF8575.h>
#include <Adafruit_GFX.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_LiquidCrystal.h>
//0x26 Create PCF8574 object with I2C address 0x20
Adafruit_PCF8575 pcf(0x26);
// PCF8574 pin connections
#define ROW1 P0
#define ROW2 P1
#define ROW3 P2
#define ROW4 P3
#define COL1 P4
#define COL2 P5
#define COL3 P6
#define COL4 P7
//0x27 Initialize the I2C LCD with its I2C address (e.g., 0x27)
Adafruit_LiquidCrystal lcd(0x27);
//0x70 Create an instance of the LED backpack
Adafruit_7segment matrix = Adafruit_7segment();
// Inintialise Variables
//CONST
const int resetButtonPin = 2; // Pin for the reset button
const int buzzerPin = 9;
const int maxDisplayValue = 10000; // Max Display Value
const int T_1000 = 1000; // 1000ms
const unsigned long debouncePeriod_200 = 200;
const unsigned long debouncePeriod_500 = 500;
// Keypad layout
const char keys[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
//STATIC
static unsigned long lastDisplayUpdate = 0;
static unsigned long lastDebounceTime = 0;
//OTHER
unsigned long elapsedMillis = 0;
//Timer
unsigned long TimerReset = 0; // = Timer Set actual Millis()
unsigned int TimerElapsed = 0; // = Timer Calculate time since last Reset
unsigned int TimerMin = 0; // = Timer Minutes
unsigned int TimerSec = 0; // = Timer Seconds
//Conter
unsigned long CounterReset = 0; // = Counter Set actual Millis()
unsigned int CounterElapsed = 0; // = Counter Calculate time since last Reset
unsigned int CounterMin = 0; // = Counter Minutes
unsigned int CounterSec = 0; // = Counter Seconds
void setup() {
// Initialize Serial communication for debugging
Serial.begin(9600);
Serial.println("Scanning for I2C devices...");
// Initialize I2C
Wire.begin();
// Initialize PCF8574 with I2C
pcf.begin();
for (int i = 0; i < 4; i++) {
pcf.pinMode(i, OUTPUT); // Row pins (P0 to P3) as outputs
pcf.digitalWrite(i, HIGH); // Set rows HIGH initially
}
for (int i = 4; i < 8; i++) {
pcf.pinMode(i, INPUT_PULLUP); // Column pins (P4 to P7) as inputs +Enable pull-up resistors on columns
}
// Initialize the LCD display with I2C
lcd.begin(16, 2);
lcd.setBacklight(1);
// Initialize the LED 7 Segment display
matrix.begin(0x70); // Use the default I2C address
//Buton Setup
pinMode(resetButtonPin, INPUT_PULLUP); // Configure button pin with pull-up resistor
pinMode(buzzerPin, OUTPUT);
// Scan for I2C devices
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
if (Wire.endTransmission() == 0) {
Serial.print("I2C device found at address 0x");
Serial.println(address, HEX);
delay(debouncePeriod_500);
}
}
//Start Menu
lcd.setCursor(0, 0);
lcd.print("Menu:...[Select]"); // Print a message
// Short delay before starting the main loop
delay(debouncePeriod_200);
}
void loop() {
// Check Overflow
if ( TimerReset > millis() || CounterReset > millis() ){
TimerReset = 0;
CounterReset = 0;
}
// Check if the reset button is pressed (with non-blocking debounce)
if (digitalRead(resetButtonPin) == LOW) {
if (millis() - lastDebounceTime > debouncePeriod_200) { // 200ms debounce period
TimerReset = millis();
CounterReset = millis();
lastDebounceTime = millis();
}
}
// Calculate elapsed time
TimerElapsed = (millis() - TimerReset ) /T_1000; // Elapsed time in seconds
CounterElapsed = (millis() - CounterReset) /T_1000; // Elapsed time in seconds
//Display Time every 1000ms
if (millis() - lastDisplayUpdate >= T_1000) {
lastDisplayUpdate = millis();
// Display a number on the 7-segment display
matrix.print(maxDisplayValue-TimerElapsed); // Display elapsed time in seconds
matrix.writeDisplay(); // Update the display
// Move the cursor to the second row, first column
lcd.setCursor(0,1);
lcd.print(TimerElapsed); // Display elapsed time in seconds
elapsedMillis = TimerElapsed;
CounterMin = elapsedMillis / 60; // Extract minutes
CounterSec = elapsedMillis % 60; // Extract seconds
lcd.setCursor(11,1);
if (CounterMin < 10) { lcd.print("0"); }
lcd.print(CounterMin);
lcd.print(":");
if (CounterSec < 10) { lcd.print("0"); }
lcd.print(CounterSec);
}
/*
tone(buzzerPin, 1000); // Generate a 1kHz sound
delay(1000); // Sound for 1 second
noTone(buzzerPin); // Stop the sound
delay(1000); // Wait 1 second
*/
}
/*
Display 7s
Clear the display
matrix.clear();
matrix.writeDisplay();
*/
/*
LCD display:
1. Direct Connection (Without I2C Module)
LCD Pin Label Connection to Arduino
1 GND GND
2 VCC 5V
3 V0 (Contrast) Connect to a 10kΩ potentiometer (middle pin)
4 RS (Register Select) Digital Pin (e.g., D7)
5 RW (Read/Write) GND (set to Write mode)
6 E (Enable) Digital Pin (e.g., D8)
7–10 D0–D3 Leave unconnected (used in 4-bit mode)
11 D4 Digital Pin (e.g., D9)
12 D5 Digital Pin (e.g., D10)
13 D6 Digital Pin (e.g., D11)
14 D7 Digital Pin (e.g., D12)
15 LED+ (Backlight) 220Ω resistor to 5V
16 LED- (Backlight) GND
>> LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // RS, E, D4, D5, D6, D7
lcd.begin(16, 2); (Setup) Set up the LCD's number of columns and rows
lcd.setCursor(column, row); Moves the cursor to the specified column (0–15) and row (0–1).
lcd.clear(); Clears the entire display and resets the cursor to (0, 0).
lcd.home(); Moves the cursor back to (0, 0) without clearing the screen.
lcd.print(); Display data or "text"
2. Using an I2C Module (Recommended)
I2C Module Pin Connection to Arduino
GND GND
VCC 5V
SDA A4 (Uno) or SDA pin
SCL A5 (Uno) or SCL pin
>> LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the I2C LCD with its I2C address (e.g., 0x27)
lcd.init(); (Setup) Initialize the LCD
lcd.Backlight(); (Setup) Turn on the backlight
lcd.noBacklight(); to toggle the backlight.
lcd.setCursor(column, row); Moves the cursor to the specified column (0–15) and row (0–1).
lcd.print(); Display data or "text"
*/
/*
I2C Address Table
A2 A1 A0 I2C Address
0 0 0 0x70
0 0 1 0x71
0 1 0 0x72
0 1 1 0x73
1 0 0 0x74
1 0 1 0x75
1 1 0 0x76
1 1 1 0x77
*/
/*
void setup()
{
pinMode(A0, INPUT);
pinMode(8, OUTPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
}
void loop()
{
// if button press on A0 is detected
if (digitalRead(A0) == HIGH) {
tone(8, 440, 100); // play tone 57 (A4 = 440 Hz)
}
// if button press on A1 is detected
if (digitalRead(A1) == HIGH) {
tone(8, 494, 100); // play tone 59 (B4 = 494 Hz)
}
// if button press on A0 is detected
if (digitalRead(A2) == HIGH) {
tone(8, 523, 100); // play tone 60 (C5 = 523 Hz)
}
delay(10); // Delay a little bit to improve simulation performance
}*/