#include<Keypad.h>
#include<LiquidCrystal.h>
#include<EEPROM.h>
#include<Servo.h>
Servo myservo;
int x=0;
#define buzzer A3
LiquidCrystal lcd(13,4,3,2,A1,A0);
byte gauge_empty[8] = {B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111}; // empty middle piece
byte gauge_fill_1[8] = {B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111}; // filled gauge - 1 column
byte gauge_fill_2[8] = {B11111, B11000, B11000, B11000, B11000, B11000, B11000, B11111}; // filled gauge - 2 columns
byte gauge_fill_3[8] = {B11111, B11100, B11100, B11100, B11100, B11100, B11100, B11111}; // filled gauge - 3 columns
byte gauge_fill_4[8] = {B11111, B11110, B11110, B11110, B11110, B11110, B11110, B11111}; // filled gauge - 4 columns
byte gauge_fill_5[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}; // filled gauge - 5 columns
byte gauge_left[8] = {B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111}; // left part of gauge - empty
byte gauge_right[8] = {B11111, B00001, B00001, B00001, B00001, B00001, B00001, B11111}; // right part of gauge - empty
byte gauge_mask_left[8] = {B01111, B11111, B11111, B11111, B11111, B11111, B11111, B01111}; // mask for rounded corners for leftmost character
byte gauge_mask_right[8] = {B11110, B11111, B11111, B11111, B11111, B11111, B11111, B11110}; // mask for rounded corners for rightmost character
byte gauge_left_dynamic[8]; // left part of gauge dynamic - will be set in the loop function
byte gauge_right_dynamic[8]; // right part of gauge dynamic - will be set in the loop function
int cpu_gauge = 0; // value for the CPU gauge
char buffer[10]; // helper buffer to store C-style strings (generated with sprintf function)
int move_offset = 0; // used to shift bits for the custom characters
const int gauge_size_chars = 16; // width of the gauge in number of characters
char gauge_string[gauge_size_chars+1]; // string that will include all the gauge character to be printed
byte chia1[] = {
B00000,
B00000,
B01000,
B10100,
B10011,
B10100,
B01000,
B00000
};
byte chia2[] = {
B00000,
B00000,
B00000,
B00101,
B11111,
B00000,
B00000,
B00000
};
byte khoa[] = {
B01110,
B10001,
B10001,
B10001,
B11111,
B11011,
B11011,
B11111
};
byte mo[] = {
B01110,
B10001,
B10000,
B10000,
B11111,
B11011,
B11011,
B11111
};
byte dung[] = {
B00000,
B00000,
B00001,
B00010,
B10100,
B01000,
B00000,
B00000
};
byte sai[] = {
B00000,
B00000,
B00000,
B01010,
B00100,
B01010,
B00000,
B00000
};
char password[4];
char pass[4],pass1[4];
int i=0;
char customKey=0;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8};
byte colPins[COLS] = {9, 10, 11, 12};
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup()
{
myservo.attach(A2);
lcd.begin(16,2);
lcd.createChar(7, gauge_empty); // middle empty gauge
lcd.createChar(1, gauge_fill_1); // filled gauge - 1 column
lcd.createChar(2, gauge_fill_2); // filled gauge - 2 columns
lcd.createChar(3, gauge_fill_3); // filled gauge - 3 columns
lcd.createChar(4, gauge_fill_4); // filled gauge - 4 columns
lcd.createChar(0,khoa);lcd.createChar(6,mo);
pinMode(buzzer, OUTPUT);
// lcd.setCursor(0,0);
// lcd.print("|--------------|");
// lcd.setCursor(3,1);
// lcd.write(byte (0));
// lcd.setCursor(12,1);
// lcd.write(byte (0));
// delay(1000);
// lcd.clear();
// lcd.setCursor(3,0);
// lcd.write(byte (0));
// lcd.setCursor(12,0);
// lcd.write(byte (0));
// lcd.setCursor(0,1);
// lcd.print("|--------------|");
// delay(1000);
}
void unlock(){
lcd.setCursor(0,0);
lcd.print("Nhap pass mo:");
lcd.setCursor(14,0);
lcd.write(byte (0));
// lcd.setCursor(2,1);
// lcd.write(byte (7));
// lcd.setCursor(3,1);
// lcd.write(byte (1));
lcd.setCursor(6,1);
for(int j=0;j<4;j++)
EEPROM.write(j, j+49);
for(int j=0;j<4;j++)
pass[j]=EEPROM.read(j);
myservo.write(0);
customKey = customKeypad.getKey();
if(customKey=='#')
change();
if (customKey)
{
password[i++]=customKey;
lcd.print("*");
beep();
}
if(i==4)
{
delay(200);
for(int j=0;j<4;j++)
pass[j]=EEPROM.read(j);
if(!(strncmp(password, pass,4)))
{
myservo.write(0);
beep();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Mat khau dung");
lcd.setCursor(14,0);
lcd.write(byte (6));
myservo.write(180);
// lcd.setCursor(7,1);
// lcd.write(byte (6));
delay(5000);
lcd.setCursor(0,1);
lcd.print("#->Thay doi pass");
delay(2000);
myservo.write(0);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Nhap pass mo:");
// lcd.setCursor(14,0);
// lcd.write(byte (0));
// lcd.setCursor(2,1);
// lcd.write(byte (7));
// lcd.setCursor(3,1);
// lcd.write(byte (1));
lcd.setCursor(6,1);
i=0;
myservo.write(0);
}
else
{
digitalWrite(buzzer, HIGH);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Mat khau sai");
lcd.setCursor(13,0);
lcd.write(byte (4));
lcd.setCursor(0,1);
lcd.print("#->Thay doi pass");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Nhap pass mo:");
// lcd.setCursor(14,0);
// lcd.write(byte (0));
// lcd.setCursor(2,1);
// lcd.write(byte (7));
// lcd.setCursor(3,1);
// lcd.write(byte (1));
lcd.setCursor(6,1);
i=0;
digitalWrite(buzzer, LOW);
}
}
}
void change()
{
int j=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Nhap pass cu:");
lcd.setCursor(6,1);
while(j<4)
{
char key=customKeypad.getKey();
if(key)
{
pass1[j++]=key;
lcd.print("*");
beep();
}
key=0;
}
delay(500);
if((strncmp(pass1, pass, 4)))
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Sai pass");
lcd.setCursor(9,0);
lcd.write(byte (4));
lcd.setCursor(0,1);
lcd.print("Hay thu lai");
delay(1000);
}
else
{
j=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Nhap pass moi:");
lcd.setCursor(0,1);
while(j<4)
{
char key=customKeypad.getKey();
if(key)
{
pass[j]=key;
lcd.print(key);
EEPROM.write(j,key);
j++;
beep();
}
}
lcd.setCursor(7,1);
lcd.print("Xong");
lcd.setCursor(12,1);
lcd.write(byte (3));
delay(2000);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Nhap pass mo:");
// lcd.setCursor(14,0);
// lcd.write(byte (0));
// lcd.setCursor(2,1);
// lcd.write(byte (7));
// lcd.setCursor(3,1);
// lcd.write(byte (1));
lcd.setCursor(6,1);
customKey=0;
}
void beep()
{
digitalWrite(buzzer, HIGH);
delay(20);
digitalWrite(buzzer, LOW);
}
void loop()
{
while(x==0){
load();
}
while(x==1){
unlock();
}
}
void load()
{
float units_per_pixel = (gauge_size_chars*5.0)/100.0; // every character is 5px wide, we want to count from 0-100
int value_in_pixels = round(cpu_gauge * units_per_pixel); // cpu_gauge value converted to pixel width
int tip_position = 0; // 0= not set, 1=tip in first char, 2=tip in middle, 3=tip in last char
if (value_in_pixels < 5) {tip_position = 1;} // tip is inside the first character
else if (value_in_pixels > gauge_size_chars*5.0-5) {tip_position = 3;} // tip is inside the last character
else {tip_position = 2;} // tip is somewhere in the middle
move_offset = 4 - ((value_in_pixels-1) % 5); // value for offseting the pixels for the smooth filling
for (int i=0; i<8; i++) { // dynamically create left part of the gauge
if (tip_position == 1) {gauge_left_dynamic[i] = (gauge_fill_5[i] << move_offset) | gauge_left[i];} // tip on the first character
else {gauge_left_dynamic[i] = gauge_fill_5[i];} // tip not on the first character
gauge_left_dynamic[i] = gauge_left_dynamic[i] & gauge_mask_left[i]; // apply mask for rounded corners
}
for (int i=0; i<8; i++) { // dynamically create right part of the gauge
if (tip_position == 3) {gauge_right_dynamic[i] = (gauge_fill_5[i] << move_offset) | gauge_right[i];} // tip on the last character
else {gauge_right_dynamic[i] = gauge_right[i];} // tip not on the last character
gauge_right_dynamic[i] = gauge_right_dynamic[i] & gauge_mask_right[i]; // apply mask for rounded corners
}
lcd.createChar(5, gauge_left_dynamic); // create custom character for the left part of the gauge
lcd.createChar(6, gauge_right_dynamic); // create custom character for the right part of the gauge
for (int i=0; i<gauge_size_chars; i++) { // set all the characters for the gauge
if (i==0) {gauge_string[i] = byte(5);} // first character = custom left piece
else if (i==gauge_size_chars-1) {gauge_string[i] = byte(6);} // last character = custom right piece
else { // character in the middle, could be empty, tip or fill
if (value_in_pixels <= i*5) {gauge_string[i] = byte(7);} // empty character
else if (value_in_pixels > i*5 && value_in_pixels < (i+1)*5) {gauge_string[i] = byte(5-move_offset);} // tip
else {gauge_string[i] = byte(255);} // filled character
}
}
// gauge drawing
lcd.setCursor(0,0); // move cursor to top left
sprintf(buffer, "Load:%3d%%", cpu_gauge); // set a string as CPU: XX%, with the number always taking at least 3 character
lcd.print(buffer); // print the string on the display
lcd.setCursor(0,1); // move the cursor to the next line
lcd.print(gauge_string); // display the gauge
// increase the CPU value, set between 0-100
cpu_gauge = cpu_gauge +1;
if (cpu_gauge > 100) {cpu_gauge = 100;delay(500);x=1;lcd.clear();}
delay(100); // wait for a while - 100ms = update the screen 10x in a second
}