Arduino Smart Alarm Clock Design (8×8 Matrix Keypad + LCD Display + Buzzer Songs)
Author: STCode
1. Effect Description:
This design is based on the Arduino Nano controller, with the main functions being a timer alarm and environmental temperature and humidity display. Users can set the alarm hour and minute using the 8×8 matrix keypad, and can turn the alarm on and off. The alarm sound is emitted by the buzzer, with the set tune being the “Ode to Joy”. While the song is playing, the RGB light will flash according to the rhythm. The device can check the current environmental temperature and humidity through the matrix keypad buttons, and all information is displayed on an LCD1602 screen, making it a very worthwhile small project to try.
2. Components Used
1) Arduino Nano Controller
2) 8×8 Matrix Keypad
3) DHT11 Temperature and Humidity Sensor
4) IIC LCD1602 Display
5) Buzzer
6) DS1302 Clock Module
7) Common Cathode RGB Light
8) One Controller Expansion Board
9) Several Dupont Wires
3. Circuit Connection
4. Source Code
#include <DHT.h> // Define <DHT.h> header file
#include <Keypad.h> // Matrix keypad header file
#include <DS1302.h> // DS1302 header file
#include <Wire.h> // Wire header file
#include <LiquidCrystal_I2C.h> // Import I2C communication LCD1602 library
#define DHTPIN A0 // Humidity sensor OUT connected to A0
#define DHTTYPE DHT11 // Define DHT11 sensor
DHT dht(DHTPIN,DHTTYPE); // Define humidity sensor OUT connected to A0 and read temperature and humidity sensor values
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
// Define key identifiers on the keypad
char hexaKeys[ROWS][COLS] = { // Key values
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; // Connected to row scanning input/output ports
byte colPins[COLS] = {9, 10, 11, 12}; // Connected to column scanning input/output ports
// Define an instance of the Keypad class
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
DS1302 rtc(2,3,4); // Corresponding to DS1302's RST, DAT, CLK
LiquidCrystal_I2C lcd(0x27,16,2);// Set LCD1602 device address, usually 0x3F, 0x20, 0x27, can refer to hardware manual
char buf1[50]; // Define character 1
char buf2[50]; // Define character 2
int alarm_hour = 0; // Alarm hour variable
int alarm_min = 0; // Alarm minute variable
bool adjust_alarm_flag = 0; // Adjust alarm flag
bool alarm_flag = 0; // Enable alarm flag
bool led_flag = 0; // LED state flag
int r_led = A1; // RGB light pin
int g_led = A2;
int b_led = A3;
int length; // Define music array length
int tonepin=0; // Buzzer connected to pin 0 (needs to be connected after the program is downloaded)
bool play_song_flag = 0; // Enable song playback flag
#define NTC0 -1 // C key frequencies
#define NTC1 262
#define NTC2 294
#define NTC3 330
#define NTC4 350
#define NTC5 393
#define NTC6 441
#define NTC7 495
#define NTCL5 196
#define HALF 0.5 // Beat
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
int tune[]= // Audio array
{
NTC3,NTC3,NTC4,NTC5,
NTC5,NTC4,NTC3,NTC2,
NTC1,NTC1,NTC2,NTC3,
NTC3,NTC2,NTC2,
NTC3,NTC3,NTC4,NTC5,
NTC5,NTC4,NTC3,NTC2,
NTC1,NTC1,NTC2,NTC3,
NTC2,NTC1,NTC1,
NTC2,NTC2,NTC3,NTC1,
NTC2,NTC3,NTC4,NTC3,NTC1,
NTC2,NTC3,NTC4,NTC3,NTC2,
NTC1,NTC2,NTCL5,NTC3,
NTC3,NTC3,NTC4,NTC5,
NTC5,NTC4,NTC3,NTC2,
NTC1,NTC1,NTC2,NTC3,
NTC2,NTC1,NTC1
};
float durt[]= // Beat array
{
1,1,1,1,
1,1,1,1,
1,1,1,1,
1+0.5,0.5,1+1,
1,1,1,1,
1,1,1,1,
1,1,1,1,
1+0.5,0.5,1+1,
1,1,1,1,
1,0.5,0.5,1,1,
1,0.5,0.5,1,1,
1,1,1,1,
1,1,1,1,
1,1,1,1,
1,1,1,1,
1+0.5,0.5,1+1,
};
void initRTCTime(void)// Initialize RTC clock
{
rtc.writeProtect(false); // Disable write protection
rtc.halt(false); // Clear clock stop flag
Time tt(2021, 5, 25, 2, 5, 30, 3); // Create time object, parameter 3 is week data, Sunday is 1, Monday is 2, and so on
rtc.time(tt);// Set time data to DS1302
}
void printTime()// Print time data
{
Time tim = rtc.time(); // Get time data from DS1302
//snprintf(buf1, sizeof(buf1), "%04d-%02d-%02d",tim.yr, tim.mon, tim.date); // Character 1 for year, month, day data
snprintf(buf2, sizeof(buf2), "%02d:%02d:%02d",tim.hr, tim.min, tim.sec); // Character 2 for hour, minute, second data
//Serial.println(buf1); // Serial print data
//Serial.println(buf2);
if ((tim.hr == alarm_hour) && (tim.min == alarm_min) && (tim.sec == 0) && alarm_flag == 1) // Check if song should play
{
tim.sec = 1;
play_song(); // Play song
}
}
void setup()
{
//Serial.begin(9600);
dht.begin(); // Initialize humidity sensor
lcd.init(); // Initialize LCD
lcd.backlight(); // Set LCD background to light
initRTCTime();
// New module needs to set the current time once,
// This function needs to be disabled after downloading, otherwise it will initialize time data every time powered on
pinMode(r_led,OUTPUT);
pinMode(g_led,OUTPUT);
pinMode(b_led,OUTPUT);
pinMode(tonepin,OUTPUT);
digitalWrite(r_led,1);
digitalWrite(g_led,1);
digitalWrite(b_led,1);
length=sizeof(tune)/sizeof(tune[0]); // Calculate audio array length
}
void loop()
{
printTime(); // Print time sub-function
lcd_display(); // LCD display sub-function
}
void play_song() // Play song function
{
for(int x=0;x<length;x++)
{
if(play_song_flag == 1)
{
play_song_flag = 0;
noTone(tonepin);
digitalWrite(r_led,1); // RGB light flashes
digitalWrite(g_led,1);
digitalWrite(b_led,1);
lcd.setCursor(0,0);
lcd.print(" ");
break;
}
tone(tonepin,tune[x]);
digitalWrite(r_led,random(0,2));
digitalWrite(g_led,random(0,2));
digitalWrite(b_led,random(0,2));
for(int i = 0;i < 30*durt[x];i++)
{
contral_song();
delay(1);
}
noTone(tonepin);
}
digitalWrite(r_led,1);
digitalWrite(g_led,1);
digitalWrite(b_led,1);
lcd.setCursor(0,0);
lcd.print(" ");
}
void print_temp_humi() // Output temperature and humidity function
{
float HH = dht.readHumidity();
float TT = dht.readTemperature();
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("T:");
lcd.setCursor(2,1);
lcd.print(TT);
lcd.setCursor(7,1);
lcd.print("C");
lcd.setCursor(9,1);
lcd.print("H:");
lcd.setCursor(11,1);
lcd.print(HH);
}
void lcd_display() // LCD display function
{
//lcd.setCursor(0,0); // Set display position
//lcd.print(buf1); // Output character
lcd.setCursor(0,0);
lcd.print(buf2);
char customKey = customKeypad.getKey();
if (customKey)
{
//Serial.println(customKey);
if(customKey == '1')
{
adjust_alarm_flag = 1;
}
if(customKey == '4')
{
adjust_alarm_flag = 0;
}
if(adjust_alarm_flag == 1)
{
switch(customKey)
{
case '2':alarm_hour++;break;
case '5':alarm_hour--;break;
case '3':alarm_min++;break;
case '6':alarm_min--;break;
defalt:break;
}
alarm_hour = constrain(alarm_hour,0,24);
alarm_min = constrain(alarm_min,0,60);
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(alarm_hour / 10);
lcd.setCursor(1,1);
lcd.print(alarm_hour % 10);
lcd.setCursor(2,1);
lcd.print(":");
lcd.setCursor(3,1);
lcd.print(alarm_min / 10);
lcd.setCursor(4,1);
lcd.print(alarm_min % 10);
}
if(customKey == 'A')
{
alarm_flag = 1;
lcd.setCursor(5,1);
lcd.print(" ");
lcd.setCursor(7,1);
lcd.print("Clock On ");
}
else if(customKey == 'B')
{
alarm_flag = 0;
lcd.setCursor(5,1);
lcd.print(" ");
lcd.setCursor(7,1);
lcd.print("Clock Off");
}
else if(customKey == 'D')
{
print_temp_humi();
}
}
}
void contral_song() // Control song sub-function
{
lcd.setCursor(0,0);
lcd.print("Clock rang");
char customKey = customKeypad.getKey();
if(customKey != NULL)
{
play_song_flag = 1;
}
}