#include <LCDI2C_Multilingual.h> // Inclusion de la librairie pour afficheur LCD
#include <Keypad.h>
#include <neotimer.h>
const byte ROWS = 4; //4 lignes
const byte COLS = 3; //3 colonnes
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {28, 30, 32, 34}; //broches connectées à L0 -> L4
byte colPins[COLS] = {22, 24, 26}; //broches connectées à C0 -> C3
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
const int BUZZER = 3;
const int relayPin = A0;
const int redLED = 36;
const int greenLED = 37;
const int batteryPin = A1;
char key;
boolean bSOUND = true;
float fmap(float, float, float, float, float);
void SOUND(double, double);
void MULTISOUND(double, double, int, int);
void checkCode();
void deleteCode();
void updateDisplay();
void setLEDStatus(bool, bool);
void lock();
void openLock();
char res[1000];
String master = "6296835891";
String code = "";
enum Status {
WAITING,
INCORRECT,
CORRECT,
};
Status status = WAITING;
enum BatteryLevel {
FULL,
GOOD,
HALF,
VLOW,
};
BatteryLevel battery;
bool displayMode = 0;
int lock_counter = 0;
int time = 300;
LCDI2C_RussianLatin lcd(0x27, 16, 2);
Neotimer openTimer = Neotimer(5000);
Neotimer lockTimer = Neotimer(3000);
Neotimer batteryTimer = Neotimer(5000);
void setup()
{
//initialisation liaison série
Serial.begin(9600);
//initialisation des broches en sortie
pinMode(BUZZER, OUTPUT);
pinMode(relayPin, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
//transmission message debut programme
Serial.println("Debut du programme ...");
digitalWrite(relayPin, LOW);
setLEDStatus(HIGH, LOW);
lcd.init();
lcd.backlight();
updateDisplay();
batteryTimer.start();
}
void loop()
{
char key = keypad.getKey();
if (key) {
Serial.println(key);
if (key == '#') {
Serial.println("test");
displayMode = 0;
checkCode();
}
else if (key == '*') {
deleteCode();
}
else {
if (code.length() <= master.length()) {
code.concat(key);
}
}
SOUND(1000, 100);
updateDisplay();
}
if (batteryTimer.done()) {
Serial.println("battery timer is done");
checkBattery();
displayMode = !displayMode;
updateDisplay();
batteryTimer.reset();
batteryTimer.start();
}
}
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
return round(((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min) * 10.0) / 10.0;
}
void SOUND(double note, double duree)
{
tone(BUZZER, note, duree);
}
void MULTISOUND(double note, double duree, int iterations, int idelay)
{
for (int i = 0; i < iterations; i++) {
SOUND(note, duree);
delay(idelay);
}
}
void updateDisplay()
{
lcd.setCursor(0, 0);
lcd.print("Code: ");
lcd.setCursor(6, 0);
if (code.length() != 0) {
for (int i = 0; i < code.length(); i++) {
lcd.print("*");
}
}
lcd.setCursor(0, 1);
switch(displayMode) {
case 0:
switch(status) {
case WAITING:
lcd.print("En attente... ");
break;
case INCORRECT:
lcd.print("Accès refusé! ");
lock();
break;
case CORRECT:
lcd.print("OK, Ouverture...");
openLock();
break;
}
break;
case 1:
switch(battery) {
case FULL:
lcd.print("Batterie pleine ");
break;
case GOOD:
lcd.print("Batterie à 75% ");
break;
case HALF:
lcd.print("Batterie à 50% ");
break;
case VLOW:
lcd.print("Batterie faible!");
MULTISOUND(2000, 200, 4, 300);
break;
}
break;
}
}
void checkCode()
{
Serial.println("Checking code...");
if (code.equals(master)) {
status = CORRECT;
}
else {
status = INCORRECT;
}
deleteCode();
}
void deleteCode()
{
Serial.println("deleteCode() has been ran!");
code.remove(0);
lcd.clear();
updateDisplay();
}
void setLEDStatus(bool redLEDstatus, bool greenLEDstatus)
{
digitalWrite(redLED, redLEDstatus);
digitalWrite(greenLED, greenLEDstatus);
}
void lock()
{
lock_counter++;
if (lock_counter >= 3) {
SOUND(500, 1000);
lcd.clear();
time = 300;
while (time >= 0) {
lcd.setCursor(0, 0);
lcd.print("Porte bloquée!");
lcd.setCursor(0, 1);
lcd.print(time);
lcd.print("s restantes ");
time--;
delay(1000);
}
status = WAITING;
lock_counter = 0;
lcd.clear();
updateDisplay();
}
else {
SOUND(800, 300);
lockTimer.reset();
lockTimer.start();
lcd.setCursor(0, 0);
for (int i = 0; i < 16; i++) {
lcd.write(0x16);
}
while (!lockTimer.done()) {
continue;
}
status = WAITING;
batteryTimer.reset();
batteryTimer.start();
lcd.clear();
}
}
void openLock()
{
setLEDStatus(LOW, HIGH);
SOUND(1500, 500);
openTimer.reset();
openTimer.start();
digitalWrite(relayPin, HIGH);
lock_counter = 0;
lcd.setCursor(0, 0);
for (int i = 0; i < 16; i++) {
lcd.write(0x16);
}
while (!openTimer.done()) {
continue;
}
digitalWrite(relayPin, LOW);
setLEDStatus(HIGH, LOW);
status = WAITING;
batteryTimer.reset();
batteryTimer.start();
lcd.clear();
}
void checkBattery()
{
float batteryVoltage = fmap(analogRead(batteryPin), 0, 1023, 8, 16);
Serial.println(batteryVoltage);
if (batteryVoltage >= 14.8) {
battery = FULL;
}
else if (batteryVoltage < 14.8 and batteryVoltage >= 12.5) {
battery = GOOD;
}
else if (batteryVoltage < 12.5 and batteryVoltage >= 10.8) {
battery = HALF;
}
else {
battery = VLOW;
}
}