// Inclusion des bibliothèques nécessaires pour utiliser l'écran LCD, le clavier et le servomoteur
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
// Création de l'objet LiquidCrystal pour contrôler l'écran LCD
// Les paramètres sont les broches utilisées pour la communication
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Définition des constantes pour le nombre de lignes et de colonnes du clavier
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
// Définition des broches utilisées pour les lignes du clavier
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2};
// Définition des broches utilisées pour les colonnes du clavier
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0};
// Définition des caractères associés à chaque touche du clavier
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
};
// Création de l'objet Keypad pour contrôler le clavier
// Les paramètres sont la matrice des caractères, les broches des lignes et des colonnes, et le nombre de lignes et de colonnes
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
// Déclaration d'une variable pour stocker la valeur saisie par l'utilisateur
uint64_t value = 0;
// Définition d'une fonction pour afficher un écran d'accueil
void showSpalshScreen() {
// Affichage du texte "GoodArduinoCode" sur la première ligne de l'écran LCD
lcd.print("Arduino Code");
// Déplacement du curseur sur la deuxième ligne, à la quatrième colonne
lcd.setCursor(3, 1);
// Déclaration d'une variable de type String pour stocker le message "Calculator"
String message = "Calculatrice";
// Boucle for pour parcourir chaque caractère du message
for (byte i = 0; i < message.length(); i++) {
// Affichage du caractère courant sur l'écran LCD
lcd.print(message[i]);
// Attente de 50 millisecondes
delay(50);
}
// Attente de 500 millisecondes
delay(500);
}
// Définition d'une fonction pour mettre à jour le curseur sur l'écran LCD
void updateCursor() {
// Si le temps écoulé depuis le démarrage de l'Arduino est divisible par 250 et pair
if (millis() / 250 % 2 == 0 ) {
// Activation du curseur sur l'écran LCD
lcd.cursor();
} else {
// Désactivation du curseur sur l'écran LCD
lcd.noCursor();
}
}
// Définition de la fonction setup qui s'exécute une fois au début du programme
void setup() {
// Initialisation de la communication série à 115200 bauds
Serial.begin(115200);
// Initialisation de l'écran LCD avec 16 colonnes et 2 lignes
lcd.begin(16, 2);
// Appel de la fonction showSpalshScreen pour afficher l'écran d'accueil
showSpalshScreen();
// Effacement de l'écran LCD
lcd.clear();
// Activation du curseur sur l'écran LCD
lcd.cursor();
// Déplacement du curseur sur la première ligne, à la deuxième colonne
lcd.setCursor(1, 0);
}
// Déclaration d'une variable pour stocker l'opération choisie par l'utilisateur
char operation = 0;
// Déclaration d'une variable de type String pour stocker la mémoire de la calculatrice
String memory = "";
// Déclaration d'une variable de type String pour stocker le nombre saisi par l'utilisateur
String current = "";
// Déclaration d'une variable pour stocker la partie décimale du nombre saisi par l'utilisateur
uint64_t currentDecimal;
// Déclaration d'une variable booléenne pour indiquer si le nombre saisi par l'utilisateur contient un point décimal
bool decimalPoint = false;
// Définition d'une fonction pour calculer le résultat d'une opération entre deux nombres
// Les paramètres sont l'opération, le nombre de gauche et le nombre de droite
double calculate(char operation, double left, double right) {
// Selon l'opération
switch (operation) {
// Si c'est l'addition
case '+':
// Retourner la somme des deux nombres
return left + right;
// Si c'est la soustraction
case '-':
// Retourner la différence des deux nombres
return left - right;
// Si c'est la multiplication
case '*':
// Retourner le produit des deux nombres
return left * right;
// Si c'est la division
case '/':
// Retourner le quotient des deux nombres
return left / right;
}
}
// Définition d'une fonction pour traiter l'entrée de l'utilisateur
// Le paramètre est la touche pressée par l'utilisateur
void processInput(char key) {
// Si la touche est le signe moins et que le nombre saisi est vide
if ('-' == key && current == "") {
// Ajouter le signe moins au nombre saisi
current = "-";
// Afficher le signe moins sur l'écran LCD
lcd.print("-");
// Retourner de la fonction
return;
}
// Selon la touche
switch (key) {
// Si c'est un opérateur
case '+':
case '-':
case '*':
case '/':
// Si aucune opération n'a été choisie
if (!operation) {
// Stocker le nombre saisi dans la mémoire
memory = current;
// Réinitialiser le nombre saisi
current = "";
}
// Stocker l'opérateur choisi dans la variable operation
operation = key;
// Déplacer le curseur sur la deuxième ligne, à la première colonne
lcd.setCursor(0, 1);
// Afficher l'opérateur sur l'écran LCD
lcd.print(key);
// Déplacer le curseur sur la deuxième ligne, après le nombre saisi
lcd.setCursor(current.length() + 1, 1);
// Retourner de la fonction
return;
// Si c'est le signe égal
case '=':
// Convertir la mémoire en un nombre à virgule flottante
float leftNum = memory.toDouble();
// Convertir le nombre saisi en un nombre à virgule flottante
float rightNum = current.toDouble();
// Calculer le résultat de l'opération entre les deux nombres
memory = String(calculate(operation, leftNum, rightNum));
// Réinitialiser le nombre saisi
current = "";
// Effacer l'écran LCD
lcd.clear();
// Déplacer le curseur sur la première ligne, à la deuxième colonne
lcd.setCursor(1, 0);
// Afficher le résultat sur l'écran LCD
lcd.print(memory);
// Déplacer le curseur sur la deuxième ligne, à la première colonne
lcd.setCursor(0, 1);
// Afficher l'opérateur sur l'écran LCD
lcd.print(operation);
// Retourner de la fonction
return;
}
// Si la touche est un point et que le nombre saisi contient déjà un point
if ('.' == key && current.indexOf('.') >= 0) {
// Retourner de la fonction
return;
}
// Si la touche n'est pas un point et que le nombre saisi est zéro
if ('.' != key && current == "0") {
// Remplacer le nombre saisi par la touche
current = String(key);
} else if (key) { // Sinon, si la touche n'est pas vide
// Ajouter la touche au nombre saisi
current += String(key);
}
// Afficher la touche sur l'écran LCD
lcd.print(key);
}
// Définition de la fonction loop qui s'exécute en boucle après la fonction setup
void loop() {
// Appel de la fonction updateCursor pour mettre à jour le curseur sur l'écran LCD
updateCursor();
// Lecture de la touche pressée sur le clavier
char key = keypad.getKey();
// Si la touche n'est pas vide
if (key) {
// Appel de la fonction processInput pour traiter l'entrée de l'utilisateur
processInput(key);
}
}