#include <Arduino.h>
#include <SPI.h> //Import libraries to control the OLED display
#include <Wire.h>
#include <Servo.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
Servo lockServo; //Create a servo object for the lock servo
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define CLK 2
#define DT 3
#define SW 4
#define RED_PIN_1 6
#define RED_PIN_2 8
#define RED_PIN_3 10
#define RED_PIN_4 12
#define GRN_PIN_1 5
#define GRN_PIN_2 7
#define GRN_PIN_3 9
#define GRN_PIN_4 11
#define LOCK_SERVO_PIN 13
String currentDir = "";
unsigned long lastButtonPress = 0;
bool safeLocked = true;
int iSecretPIN = 0;
int PIN_CODE_ADDR = 0;
int MAX_POS_SERVO = 60; // rotations for a complete lock
enum wheel_modes {
LOCK_MODE,
PIN_CHANGE_MODE
};
int lastStateCLK;
wheel_modes mode;
#define HEIGHT 60
#define WIDTH 60
/***********************************************************************************************/
// 'coffre-fort (fermer)', 60x60px
const unsigned char PROGMEM fermer []= {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0,
0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0,
0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf3, 0xe7, 0xff, 0xc0, 0x3f, 0xff, 0xe4, 0xf0, 0xf3, 0xe7, 0xff, 0x00, 0x0f, 0xff, 0xe4, 0xf0,
0xf3, 0xe7, 0xfc, 0x39, 0xc3, 0xff, 0xe4, 0xf0, 0xf3, 0xe7, 0xf8, 0xf9, 0xf1, 0xff, 0xe4, 0xf0,
0xf3, 0xe7, 0xf0, 0xff, 0xf0, 0xff, 0xe4, 0xf0, 0xf0, 0x07, 0xf0, 0x7f, 0xe0, 0xff, 0xe0, 0xf0,
0xf0, 0x0f, 0xe6, 0x7f, 0xe6, 0x7f, 0xe0, 0xf0, 0xf2, 0x7f, 0xe7, 0xf9, 0xfe, 0x7f, 0xe4, 0xf0,
0xf2, 0x7f, 0xcf, 0xe0, 0x7f, 0x3f, 0xe4, 0xf0, 0xf2, 0x7f, 0xcf, 0xc6, 0x3f, 0x3f, 0xe4, 0xf0,
0xf2, 0x7f, 0xcf, 0xcf, 0x3f, 0x3f, 0xe4, 0xf0, 0xf2, 0x7f, 0xc3, 0x9f, 0x9c, 0x3f, 0xe4, 0xf0,
0xf2, 0x7f, 0xc3, 0x9f, 0x9c, 0x3f, 0xe4, 0xf0, 0xf2, 0x7f, 0xcf, 0xcf, 0x3f, 0x3f, 0xe4, 0xf0,
0xf2, 0x7f, 0xcf, 0xc6, 0x3f, 0x3f, 0xe4, 0xf0, 0xf2, 0x7f, 0xcf, 0xe0, 0x7f, 0x3f, 0xe4, 0xf0,
0xf2, 0x7f, 0xe7, 0xf9, 0xfe, 0x7f, 0xe4, 0xf0, 0xf0, 0x0f, 0xe6, 0x7f, 0xe6, 0x7f, 0xe0, 0xf0,
0xf0, 0x07, 0xf0, 0x7f, 0xe0, 0xff, 0xe0, 0xf0, 0xf3, 0xe7, 0xf0, 0xff, 0xf0, 0xff, 0xe4, 0xf0,
0xf3, 0xe7, 0xf8, 0xf9, 0xf1, 0xff, 0xe4, 0xf0, 0xf3, 0xe7, 0xfc, 0x39, 0xc3, 0xff, 0xe4, 0xf0,
0xf3, 0xe7, 0xff, 0x00, 0x0f, 0xff, 0xe4, 0xf0, 0xf3, 0xe7, 0xff, 0xc0, 0x3f, 0xff, 0xe4, 0xf0,
0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0,
0xf2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xf0, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0,
0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0
};
/***********************************************************************************************/
// 'coffre-fort', 60x60px
const unsigned char PROGMEM ouvert[] = {
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x1f, 0xff, 0xff, 0x00, 0x33, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xf0, 0x06, 0x33, 0xff, 0xff, 0xc0,
0x3f, 0xff, 0x80, 0x7e, 0x33, 0xff, 0xff, 0xc0, 0x3f, 0xf8, 0x03, 0xfe, 0x33, 0xff, 0xff, 0xc0,
0x3f, 0xc0, 0x3f, 0xfe, 0x33, 0xff, 0xff, 0xc0, 0x3e, 0x01, 0xff, 0xfe, 0x30, 0x00, 0x07, 0xc0,
0x3e, 0x1f, 0xff, 0xfe, 0x30, 0x00, 0x07, 0xc0, 0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3c, 0x3f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x38, 0x1f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x39, 0x8f, 0xff, 0xee, 0x33, 0xff, 0xe7, 0xc0, 0x39, 0x8f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x39, 0x8f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x38, 0x1f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3c, 0x3f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xe6, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x3f, 0xff, 0xee, 0x33, 0xff, 0xe7, 0xc0, 0x3c, 0x1f, 0xff, 0xc6, 0x33, 0xff, 0xe7, 0xc0,
0x38, 0x1f, 0xff, 0xee, 0x33, 0xff, 0xe7, 0xc0, 0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x39, 0x8f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x38, 0x1f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3c, 0x1f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0, 0x3e, 0x7f, 0xff, 0xfe, 0x33, 0xff, 0xe7, 0xc0,
0x3e, 0x3f, 0xff, 0xfe, 0x30, 0x00, 0x07, 0xc0, 0x3e, 0x03, 0xff, 0xfe, 0x30, 0x00, 0x07, 0xc0,
0x3f, 0x80, 0x7f, 0xfe, 0x33, 0xff, 0xff, 0xc0, 0x3f, 0xf0, 0x07, 0xfe, 0x33, 0xff, 0xff, 0xc0,
0x3f, 0xff, 0x00, 0xfe, 0x33, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x1e, 0x33, 0xff, 0xff, 0xc0,
0x1f, 0xff, 0xfe, 0x00, 0x33, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf9, 0xf8, 0xff, 0xff, 0xff, 0xf1, 0xf9, 0xf0,
0xf9, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xf0, 0xf9, 0xf1, 0xff, 0xff, 0xff, 0xf8, 0xf9, 0xf0,
0xf8, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xf0, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xf0
};
/***********************************************************************************************/
// 'pngegg', 60x60px
const unsigned char PROGMEM logo []= {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xfc, 0x00, 0x9f, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xfc, 0x7e, 0x3f, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xfc, 0xff, 0x3f, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xfd, 0xc3, 0x9f, 0x80, 0x00, 0xf9, 0xc0,
0x39, 0xf9, 0x99, 0x9f, 0x80, 0x00, 0xf9, 0xc0, 0x39, 0xf1, 0xbd, 0x87, 0x9f, 0xfe, 0xf9, 0xc0,
0x39, 0xf1, 0xbd, 0x8f, 0x9f, 0xfe, 0xf9, 0xc0, 0x39, 0xf9, 0x99, 0x9f, 0x80, 0x00, 0xf9, 0xc0,
0x39, 0xfc, 0xc3, 0xbf, 0x80, 0x00, 0xf9, 0xc0, 0x39, 0xfc, 0xff, 0x3f, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xfc, 0x3e, 0x3f, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xf9, 0x00, 0x9f, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0,
0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf9, 0xf3, 0xff, 0xff, 0xff, 0xfc, 0xf9, 0xf0,
0xf9, 0xf3, 0xff, 0xff, 0xff, 0xfc, 0xf9, 0xf0, 0xf9, 0xf3, 0xff, 0xff, 0xff, 0xfc, 0xf9, 0xf0,
0xf8, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0
};
/**********************************/
/*** SETUP ***/
/*********************************/
void setup() {
Serial.begin(115200); //Démarre le moniteur série pour le débogage
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) //Connect to the OLED display
{
Serial.println(F("SSD1306 allocation failed")); //If connection fails
for (;;)
; //Ne pas poursuivre, boucler à l'infini
}
display.clearDisplay(); //Raz Affichage
// Set encoder pins as inputs
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
digitalWrite(LOCK_SERVO_PIN, LOW);
// RED
pinMode(RED_PIN_1, OUTPUT);
pinMode(RED_PIN_2, OUTPUT);
pinMode(RED_PIN_3, OUTPUT);
pinMode(RED_PIN_4, OUTPUT);
// GREEN
pinMode(GRN_PIN_1, OUTPUT);
pinMode(GRN_PIN_2, OUTPUT);
pinMode(GRN_PIN_3, OUTPUT);
pinMode(GRN_PIN_4, OUTPUT);
AllumerLR();
AllumerLG();
EteindreLR();
EteindreLG();
lockServo.attach(LOCK_SERVO_PIN);
display.setTextColor(SSD1306_WHITE); //Set the text colour to white
startupAnimation();
// Read the PIN code memory location to see if we ave a value set
int value = EEPROM.read(PIN_CODE_ADDR);
// Vérifier si le code PIN a été défini
if (value == 255) {
// Le code PIN n'a pas encore été défini. Générer un code PIN et le mémoriser
// Gnerate PIN
iSecretPIN = GetPin("INIT");
// Store PIN in memory
EEPROM.put(PIN_CODE_ADDR, iSecretPIN);
// Affichage d'un message de confirmation à l'écran
display.clearDisplay();
display.setCursor(20,10); //Définir la position du curseur d'affichage
display.println("CODE");
display.setCursor(20,40); //Définir la position du curseur d'affichage
display.println("ENREG.");
display.display();
EteindreLG();
} else {
// PIN already set. Read it from memory
EEPROM.get(PIN_CODE_ADDR, iSecretPIN);
}
lastStateCLK = digitalRead(CLK);
}
/*********************************/
/*** LOOP ***/
/*********************************/
void loop() {
int currentStateCLK = digitalRead(CLK);
// Si le dernier état et l'état actuel de CLK sont différents, une impulsion s'est produite.
// Réagit à un seul changement d'état pour éviter un double comptage
if (currentStateCLK != lastStateCLK && currentStateCLK == LOW) {
// Si l'état DT est différent de l'état CLK, alors
// le codeur tourne dans le sens inverse des aiguilles d'une montre, donc décrémente
if (digitalRead(DT) != currentStateCLK) {
display.clearDisplay();
display.setTextSize(2); //Définir la taille du texte affiché
display.setCursor(20, 10); //Sélectionner la position du curseur d'affichage
display.println(F("CHANGER")); //Sélectionner le texte d'affichage
display.setCursor(20, 40); //Sélectionner la position du curseur d'affichage
display.println(F("LE CODE")); //Sélectionner le texte d'affichage
display.display(); //Sortie du texte d'affichage
mode = PIN_CHANGE_MODE;
} else {
display.clearDisplay();
display.setTextSize(2); //Définir la taille du texte affiché
if (safeLocked == true)
{
display.setCursor(20, 10); //Sélectionner la position du curseur d'affichage
display.println(F("OUVRIR")); //Sélectionner le texte d'affichage
display.setCursor(30, 40); //Sélectionner la position du curseur d'affichage
display.println(F("COFFRE")); //Sélectionner le texte d'affichage
}
else
{
display.setCursor(20, 10); //Sélectionner la position du curseur d'affichage
display.println(F("COFFRE")); //Sélectionner le texte d'affichage
display.setCursor(30, 40); //Sélectionner la position du curseur d'affichage
display.println(F("FERMER")); //Sélectionner le texte d'affichage
}
display.display(); //Sortie du texte d'affichage
mode = LOCK_MODE;
}
}
lastStateCLK = currentStateCLK;
// Lire l'état du bouton
int btnState = digitalRead(SW);
//Si nous détectons un signal BAS, le bouton est enfoncé.
if (btnState == LOW) {
//si 50ms se sont écoulés depuis la dernière impulsion BAS, cela signifie que la
//a été pressé, relâché et pressé à nouveau.
if (millis() - lastButtonPress > 50) {
Serial.println("Bouton actif!");
if (mode == LOCK_MODE) {
if (safeLocked == false)
lock();
else
unlock();
} else if (mode == PIN_CHANGE_MODE) {
int attempt = GetPin("Actuel");
EteindreLG();
if (attempt == iSecretPIN) {
iSecretPIN = GetPin("Nouveau");
display.clearDisplay();
display.setTextSize(2); //Régler la taille du texte affiché
display.setCursor(20, 10); //Définir la position du curseur d'affichage
display.println(F("CODE")); //Définir le texte de l'affichage
display.setCursor(20, 30); //Définir la position du curseur d'affichage
display.println(F("ENREG.")); //Définir le texte de l'affichage
display.display(); //Éditer le texte de l'affichage
EEPROM.update(PIN_CODE_ADDR, iSecretPIN);
EteindreLG();
} else {
DisplayWrongPinMsg();
}
}
}
Serial.print("safeLock: " + (String)safeLocked);
// Mémoriser la dernière pression sur un bouton
lastButtonPress = millis();
}
// Ajoutez un léger retard pour le rebond.
delay(1);
}
/*******************************************/
void startupAnimation() {
display.clearDisplay();
display.drawBitmap(
(display.width() - WIDTH ) / 2,
(display.height() - HEIGHT) / 2,
logo, WIDTH, HEIGHT, 1);
display.display();
delay(5000);
}
/*********************************************/
void lock() {
if (safeLocked == false) {
for (int pos = 0; pos <= MAX_POS_SERVO; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
lockServo.write(pos); // indiquer au servo de se rendre à la position indiquée dans la variable "pos".
delay(15); // attend 15ms pour que le servo atteigne la position
}
safeLocked = true;
display.clearDisplay();
display.drawBitmap(
(display.width() - WIDTH ) / 2,
(display.height() - HEIGHT) / 2,
fermer, WIDTH, HEIGHT, 1);
display.display();
delay(1000);
// turn on all red leds
AllumerLR();
delay(1000);
EteindreLR();
// turn off all green leds
EteindreLG();
}
}
/***************************************/
void unlock() {
// Is the safe locked?
if (safeLocked == true) {
// Le coffre est verrouillé -> demander le code PIN
/*
int textSize = 2;
display.clearDisplay();
display.setCursor(10, 5); //Définir la position du curseur d'affichage
display.println("- CODE -");
display.display();
*/
int finalNumber = GetPin("CODE ?");
if (finalNumber != iSecretPIN) {
DisplayWrongPinMsg();
} else {
for (int pos = MAX_POS_SERVO; pos >= 0; pos -= 1) { //
lockServo.write(pos); // indiquer au servo de se rendre à la position indiquée dans la variable "pos".
delay(15); // attend 15ms pour que le servo atteigne la position
}
safeLocked = false;
display.clearDisplay();
display.drawBitmap(
(display.width() - WIDTH ) / 2,
(display.height() - HEIGHT) / 2,
ouvert, WIDTH, HEIGHT, 1);
display.display();
delay(1000);
// turn off all red leds
EteindreLR();
// turn on all green leds
AllumerLG();
delay(1000);
// turn on all green leds
EteindreLG();
}
}
}
/*************************************************/
int GetPin(String displayedText) {
int digit = 0;
int cnt = 0;
int lastStateCLK;
int currentStateCLK = LOW;
int counter;
int digitToPrint = 0;
int pottentionalvalue[4] = { 0 };
lastButtonPress = millis();
pottentionalvalue[digitToPrint] = abs(counter);
display.clearDisplay();
display.setCursor(5, 10); //Set the display cursor position
display.setTextSize(2);
display.println(displayedText);
display.setTextSize(3);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
display.setCursor(40, 40); //Set the display cursor position
display.println(String(pottentionalvalue[0]) + String(pottentionalvalue[1]) + String(pottentionalvalue[2]) + String(pottentionalvalue[3])); //Set the display text
display.display();
delay(500);
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE); // Draw 'inverse' text
while (cnt < 4) {
counter = 0;
while (1) {
currentStateCLK = digitalRead(CLK);
// Si le dernier état et l'état actuel de CLK sont différents, une impulsion s'est produite.
// Réagit à un seul changement d'état pour éviter un double comptage
if (currentStateCLK != lastStateCLK && currentStateCLK == LOW) {
// Si l'état DT est différent de l'état CLK, alors
// le codeur tourne dans le sens inverse des aiguilles d'une montre, donc décrémente
if (digitalRead(DT) != currentStateCLK) {
counter++;
currentDir = "CCW";
} else {
// Le codeur tourne dans le sens des aiguilles d'une montre, l'incrément est donc de 0,5 %.
counter--;
currentDir = "CW";
}
counter = (counter + 10) % 10;
pottentionalvalue[digitToPrint] = abs(counter);
//displaycode ();
display.clearDisplay();
display.setCursor(5, 10); //Set the display cursor position
display.setTextSize(2);
display.println(displayedText);
display.setTextSize(3);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
display.setCursor(40, 40); //Set the display cursor position
display.println(String(pottentionalvalue[0]) + String(pottentionalvalue[1]) + String(pottentionalvalue[2]) + String(pottentionalvalue[3])); //Set the display text
display.display();
delay(500);
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE); // Draw 'inverse' text
}
// Mémoriser le dernier état du CLK
lastStateCLK = currentStateCLK;
// Lire l'état du bouton
int btnState = digitalRead(SW);
//Si nous détectons un signal BAS, le bouton est enfoncé.
if (btnState == LOW) {
//si 50ms se sont écoulés depuis la dernière impulsion BAS, cela signifie que la
//a été pressé, relâché et pressé à nouveau.
if (millis() - lastButtonPress > 500) {
digitToPrint = (digitToPrint + 1);
delay(500);
if (digitToPrint==1){digitalWrite(GRN_PIN_1, HIGH);}
if (digitToPrint==2){digitalWrite(GRN_PIN_2, HIGH);}
if (digitToPrint==3){digitalWrite(GRN_PIN_3, HIGH);}
if (digitToPrint==4){digitalWrite(GRN_PIN_4, HIGH);}
break;
}
lastButtonPress = millis();
// Ajoutez un léger retard pour aider à débrider la lecture.
}
}
digit = counter;
cnt++;
}
int number = pottentionalvalue[0] * 1000 + pottentionalvalue[1] * 100 + pottentionalvalue[2] * 10 + pottentionalvalue[3] ;
Serial.println("unlock " + String(number));
return number;
}
/*************************************************/
void DisplayWrongPinMsg() {
display.clearDisplay();
display.setTextSize(2); //Définir la taille du texte affiché
display.setCursor(10, 20); //Sélectionner la position du curseur d'affichage
display.println("MAUVAIS CODE"); //Sélectionner le texte d'affichage
display.display();
EteindreLG();
}
/**************************************************/
void EteindreLR() {
digitalWrite(RED_PIN_1, LOW);
digitalWrite(RED_PIN_2, LOW);
digitalWrite(RED_PIN_3, LOW);
digitalWrite(RED_PIN_4, LOW);
}
void EteindreLG() {
digitalWrite(GRN_PIN_1, LOW);
digitalWrite(GRN_PIN_2, LOW);
digitalWrite(GRN_PIN_3, LOW);
digitalWrite(GRN_PIN_4, LOW);
}
void AllumerLR() {
digitalWrite(RED_PIN_1, HIGH);
digitalWrite(RED_PIN_2, HIGH);
digitalWrite(RED_PIN_3, HIGH);
digitalWrite(RED_PIN_4, HIGH);
}
void AllumerLG() {
digitalWrite(GRN_PIN_1, HIGH);
digitalWrite(GRN_PIN_2, HIGH);
digitalWrite(GRN_PIN_3, HIGH);
digitalWrite(GRN_PIN_4, HIGH);
}