Appearance
Version 1.2.5
Note
- Amélioration de la lisibilité du code.
- Réecriture de tout les commentaires dans le code.
Code
c++
/**
* @file bras.cpp
* @brief Communication entre l'afficheur STONE HMI, Arduino MEGA et action des casiers du B.R.A.S
* documentation : https://docs.ks-infinite.fr/bras/
* github : https://github.com/kerogs/bras/
* @author Lucas W.
* @author Florian V.
* @author Jessy K.
* @version 1.2.5
* @date 29/05/2024
* @copyright Copyright - B.R.A.S, Kerogs Infinite, Lycée Condorcet - Stiring-Wendel
*/
#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"
#define led 2
#define TX_PIN 46
#define RX_PIN 48
SoftwareSerial printSerial(RX_PIN, TX_PIN);
Adafruit_Thermal printer(&printSerial);
char tampon[30];
int tamponPos = 0;
String tamponStr;
char incomingByte;
// Casier Action
int casierActionNumber;
char casierActionName;
int casierAdminActionNumber;
int casiersPassword[7];
int PasswordTemp;
int M1dirpin = 7;
int M1steppin = 6;
const int BPfdc = 38;
const int BPfdc2 = 36;
const int LedR = 32;
const int LedG = 30;
bool casierUtilisation = false; // true ? casiser utilisé : casier non utilisé
bool modeAdmin = false;
bool printAction = true;
// configuration
const bool serialSpaceReset = true;
const int adminPasswordPreset = 1234;
void setup() {
configset();
}
void loop() {
digitalWrite(led, LOW);
// --------- Début de trame ---------
if (searchArray(tampon, "ST<", 3)) {
Serial.println("[DEBUT DE TRAME]");
// --------- Mode Admin ---------
if (searchArray(tampon, "MA", 2) || modeAdmin) {
modeAdmin = true;
// --------- Admin Password ---------
if (searchArray(tampon, "AP", 2)) {
Serial.println("[MODE ADMIN [???]]");
int tamponLength = sizeof(tampon) / sizeof(tampon[0]);
PasswordTemp = getValueAdmin(tampon, tamponLength);
Serial.println(PasswordTemp);
if (PasswordTemp == adminPasswordPreset) {
Serial.println("[MODE ADMIN [CONFIRMATION]]");
Serial3.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CA\",\"enable\":true}>ET");
Serial.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CA\",\"enable\":true}>ET");
}
}
// [Détection casier admin]
if (searchArray(tampon, "Admin", 5)) {
Serial.println("[CASIER ADMIN]");
for (int i = 0; i <= 6; i++) {
String casierNumber = "Casier" + String(i);
String casierAdminNumber = "Admin" + String(i);
if (searchArray(tampon, casierAdminNumber.c_str(), 6)) {
Serial.println("[NUMERO " + String(i) + "]");
casierActionNumber = i;
casierAdminActionNumber = i;
break;
}
}
// [Vérifie si casier déjà utilisé]
for (int i = 1; i < 7; i++) {
if (casierActionNumber == i) {
if (casiersPassword[i]) {
// [Casier déjà utilisé -> on cache les textes pour utilisé un casier]
Serial.println("[CASIER STATUS : DEJA UTILISER]");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer1\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer2\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer2a\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer3\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"IC\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer4\",\"visible\":true}>ET");
casierUtilisation = true;
} else {
Serial.println("[CASIER STATUS : PAS UTILISER]");
}
}
}
}
// --------- Dévérouiller Admin ---------
if (casierAdminActionNumber != 0 && searchArray(tampon, "DA", 2)) {
Serial.println("[CONFIRMATION ADMIN]");
Serial.println(casierAdminActionNumber);
Serial.println(PasswordTemp);
// Serial.println(casier1Password);
for (int i = 1; i < 7; i++) {
Serial.print(i);
Serial.print(" : ");
Serial.println(casiersPassword[i]);
}
// [si casier utilisé]
if (!casierUtilisation) { // Jai ajouté le ! et ca a marché, faudrait tester sans
Serial.println(casierAdminActionNumber);
Serial.println(casiersPassword[casierAdminActionNumber]);
Serial.println(PasswordTemp);
sendColorHMI(casierActionNumber, "bg_color", "green");
sendColorHMI(casierAdminActionNumber, "bg_color", "green");
Serial.println("[OUVERTURE PORTE]");
casiersPassword[casierAdminActionNumber] = 0;
// [Ouvrir la porte.]
while (digitalRead(BPfdc) != LOW) {
rotation_montre();
digitalWrite(LedG, HIGH);
digitalWrite(LedR, LOW);
}
}
casierActionNumber = NULL;
casierAdminActionNumber = NULL;
casierUtilisation = false;
PasswordTemp = 0;
printAction = true;
}
}
// ----------- Fin mode admin -----------
// [Détection du casier sélectionné]
if (searchArray(tampon, "Casier", 6)) {
Serial.println("[CASIER]");
for (int i = 0; i <= 6; i++) {
String casierNumber = "Casier" + String(i);
String casierAdminNumber = "Admin" + String(i);
if (searchArray(tampon, casierNumber.c_str(), 7)) {
Serial.println("[NUMERO " + String(i) + "]");
casierActionNumber = i;
break;
}
}
// [Vérifie si casier déjà fermé]
for (int i = 1; i < 7; i++) {
if (casierActionNumber == i) {
if (casiersPassword[i]) {
// [Casier déjà utilisé -> on cache les textes pour utilisé un casier]
Serial.println("[CASIER STATUS : DEJA UTILISER]");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer1\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer2\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer2a\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer3\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"IC\",\"visible\":false}>ET");
Serial3.print("ST<{\"cmd_code\":\"set_visible\",\"type\":\"widget\",\"widget\":\"Inserer4\",\"visible\":true}>ET");
casierUtilisation = true;
} else {
Serial.println("[CASIER STATUS : PAS UTILISER]");
casierUtilisation = false;
}
}
}
}
// ----------- Détection MDP -----------
if (casierActionNumber != 0 && searchArray(tampon, "PC", 2)) {
Serial.println("[CASIER PASSWORD [MDP]");
// if valeur casier === 4
int tamponLength = sizeof(tampon) / sizeof(tampon[0]);
PasswordTemp = getValue(tampon, tamponLength);
Serial.println(PasswordTemp);
// [Vérifier si nombre de PC == 4]
if (numDigits(PasswordTemp) == 4) {
Serial3.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CC\",\"enable\":true}>ET");
Serial.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CC\",\"enable\":true}>ET");
} else {
Serial3.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CC\",\"enable\":false}>ET");
Serial.println("ST<{\"cmd_code\":\"set_enable\",\"type\":\"widget\",\"widget\":\"CC\",\"enable\":false}>ET");
}
Serial.println(numDigits(PasswordTemp));
}
// ----------- Activé/Désactivé Impression -----------
if (searchArray(tampon, "IC", 2)) {
printAction ? printAction = false : printAction = true;
Serial.print("Imprimante : ");
Serial.println(printAction);
}
// ----------- Confirmer client -----------
if (casierActionNumber != 0 && searchArray(tampon, "CC", 2)) {
Serial.println("[CONFIRMATION CLIENT]");
Serial.println(casierActionNumber);
Serial.println(PasswordTemp);
for (int i = 1; i < 7; i++) {
Serial.print(i);
Serial.print(" : ");
Serial.println(casiersPassword[i]);
}
// [Vérifier si casier utilisé]
if (casierUtilisation) {
Serial.println(casierActionNumber);
Serial.println(casiersPassword[casierActionNumber]);
Serial.println(PasswordTemp);
// [Vérifier bon mot de passe]
if (casiersPassword[casierActionNumber] == PasswordTemp) {
sendColorHMI(casierActionNumber, "bg_color", "green");
sendColorHMI(casierAdminActionNumber, "bg_color", "green");
Serial.println("[OUVERTURE PORTE]");
casiersPassword[casierActionNumber] = 0;
// [Ouvrir la porte.]
while (digitalRead(BPfdc) != LOW) {
rotation_montre();
digitalWrite(LedG, HIGH);
digitalWrite(LedR, LOW);
}
} else {
Serial.println("[ERREUR : FAUX MDP]");
}
} else {
// [enregistrement mdp]
if (!casierUtilisation) {
for (int i = 1; i < 7; i++) {
if (casierActionNumber == i) {
casiersPassword[i] = PasswordTemp;
Serial.println("[MDP ENREGISTRE]");
}
}
}
sendColorHMI(casierActionNumber, "bg_color", "red");
sendColorHMI(casierAdminActionNumber, "bg_color", "red");
Serial.println("[FERMETURE PORTE]");
// [Fermer la porte]
while (digitalRead(BPfdc2) != LOW) {
rotation_inverse();
digitalWrite(LedG, LOW);
digitalWrite(LedR, HIGH);
}
if (printAction) {
Serial.println("[IMPRIMANTE]");
imprimante(casierActionNumber, PasswordTemp);
}
}
casierActionNumber = NULL;
casierAdminActionNumber = NULL;
casierUtilisation = false;
PasswordTemp = 0;
printAction = true;
}
// Password popup up close
if (casierActionNumber != 0 && searchArray(tampon, "FermerPopup", 11)) {
Serial.println("[PASSWORD POPUP FERME]");
casierActionNumber = NULL;
casierUtilisation = false;
}
}
tamponReset();
}
void serialEvent3() {
monitorSerialSpace();
while (Serial3.available() > 0) {
digitalWrite(led, HIGH);
incomingByte = Serial3.read();
tampon[tamponPos] = incomingByte;
tamponPos++;
}
Serial.println("+=======================+");
Serial.print("|> ASCII : ");
for (int i = 0; i < tamponPos; i++) {
Serial.print(tampon[i]);
}
Serial.println("");
Serial.print("|> HEX : ");
for (int i = 0; i < tamponPos; i++) {
Serial.print(tampon[i], HEX);
Serial.print(" ");
}
Serial.println("");
Serial.println("+=======================+");
Serial.println("En attente...");
}
void configset() {
// PC
while (!Serial) Serial.print(".");
Serial.begin(9600);
Serial.print(".");
// HMI
while (!Serial3) Serial.print(".");
Serial3.begin(9600);
Serial.print(".");
// Imprimante
while (!printSerial) Serial.print(".");
printSerial.begin(19200);
Serial.print(".");
printer.begin();
Serial.print(".");
// LED
pinMode(led, OUTPUT);
Serial.print(".");
// ALLUME
digitalWrite(LedG, HIGH);
Serial.print(".");
pinMode(M1dirpin, OUTPUT);
Serial.print(".");
pinMode(M1steppin, OUTPUT);
Serial.print(".");
pinMode(BPfdc, INPUT);
Serial.print(".");
pinMode(BPfdc2, INPUT);
Serial.print(".");
pinMode(LedR, OUTPUT);
Serial.print(".");
pinMode(LedG, OUTPUT);
Serial.print(".");
delay(500);
Serial.println("Fin");
}
// Fonction pour rechercher une chaîne de caractères dans un tableau
bool searchArray(char array[], char arraySearch[], int numberCSearch) {
bool sequenceFound = false;
for (int i = 0; i < 30 - numberCSearch + 1; i++) {
bool match = true;
for (int j = 0; j < numberCSearch; j++) {
if (tampon[i + j] != arraySearch[j]) {
match = false;
break;
}
}
if (match) {
sequenceFound = true;
break;
}
}
return sequenceFound;
}
void tamponReset() {
// fin de trame
if (searchArray(tampon, ">ET", 3)) {
Serial.println("[FIN DE TRAME]");
for (int i = 0; i < sizeof(tampon); i++) {
tampon[i] = 0;
}
tamponPos = 0;
}
}
void sendColorHMI(char widget[], char color_object[], char color[]) {
// Vert : rgba(14, 217, 38, 1) = 4279163174
// Rouge : rgba(235, 45, 71, 1) = 4293602631
// Blanc : rgba(255, 255, 255, 1) = 4294967295
color == "white" ? color = "4294967295" : color = color;
color == "black" ? color = "4278190080" : color = color;
color == "green" ? color = "4279163174" : color = color;
color == "red" ? color = "4293602631" : color = color;
widget == 1 ? widget = "Casier1" : widget = widget;
widget == 2 ? widget = "Casier2" : widget = widget;
widget == 3 ? widget = "Casier3" : widget = widget;
widget == 4 ? widget = "Casier4" : widget = widget;
widget == 5 ? widget = "Casier5" : widget = widget;
widget == 6 ? widget = "Casier6" : widget = widget;
widget == 11 ? widget = "Admin1" : widget = widget;
widget == 12 ? widget = "Admin2" : widget = widget;
widget == 13 ? widget = "Admin3" : widget = widget;
widget == 14 ? widget = "Admin4" : widget = widget;
widget == 15 ? widget = "Admin5" : widget = widget;
widget == 16 ? widget = "Admin6" : widget = widget;
String widgetStr = widget;
String color_objectStr = color_object;
String colorStr = color;
Serial3.println("ST<{\"cmd_code\":\"set_color\",\"type\":\"widget\",\"widget\":\"" + widgetStr + "\",\"color_object\":\"" + color_objectStr + "\", \"color\":" + colorStr + "}>ET");
Serial.println("[ENVOIE HMI] ST<{\"cmd_code\":\"set_color\",\"type\":\"widget\",\"widget\":\"" + widgetStr + "\",\"color_object\":\"" + color_objectStr + "\", \"color\":" + colorStr + "}>ET");
}
// Récupérer password
int getValue(char array[], int length) {
char arraySearchStart[] = "\"PC\":";
char arraySearchEnd[] = ">ET";
int numberCSearchStart = sizeof(arraySearchStart) - 1; // -1 pour ne pas compter le caractère de fin de chaîne '\0'
int numberCSearchEnd = sizeof(arraySearchEnd) - 1;
bool sequenceFound = false;
int startIndex = -1;
for (int i = 0; i < length - numberCSearchStart + 1; i++) {
bool match = true;
for (int j = 0; j < numberCSearchStart; j++) {
if (array[i + j] != arraySearchStart[j]) {
match = false;
break;
}
}
if (match) {
sequenceFound = true;
startIndex = i + numberCSearchStart;
break;
}
}
if (!sequenceFound) {
return -1;
}
sequenceFound = false;
int endIndex = -1;
for (int i = startIndex; i < length - numberCSearchEnd + 1; i++) {
bool match = true;
for (int j = 0; j < numberCSearchEnd; j++) {
if (array[i + j] != arraySearchEnd[j]) {
match = false;
break;
}
}
if (match) {
sequenceFound = true;
endIndex = i;
break;
}
}
if (!sequenceFound) {
return -1;
}
String pcValue = "";
for (int i = startIndex; i < endIndex; i++) {
pcValue += array[i];
}
return pcValue.toInt();
}
// Récupérer password
int getValueAdmin(char array[], int length) {
char arraySearchStart[] = "\"AP\":";
char arraySearchEnd[] = ">ET";
int numberCSearchStart = sizeof(arraySearchStart) - 1; // -1 pour ne pas compter le caractère de fin de chaîne '\0'
int numberCSearchEnd = sizeof(arraySearchEnd) - 1;
bool sequenceFound = false;
int startIndex = -1;
for (int i = 0; i < length - numberCSearchStart + 1; i++) {
bool match = true;
for (int j = 0; j < numberCSearchStart; j++) {
if (array[i + j] != arraySearchStart[j]) {
match = false;
break;
}
}
if (match) {
sequenceFound = true;
startIndex = i + numberCSearchStart;
break;
}
}
if (!sequenceFound) {
return -1;
}
sequenceFound = false;
int endIndex = -1;
for (int i = startIndex; i < length - numberCSearchEnd + 1; i++) {
bool match = true;
for (int j = 0; j < numberCSearchEnd; j++) {
if (array[i + j] != arraySearchEnd[j]) {
match = false;
break;
}
}
if (match) {
sequenceFound = true;
endIndex = i;
break;
}
}
if (!sequenceFound) {
return -1;
}
String pcValue = "";
for (int i = startIndex; i < endIndex; i++) {
pcValue += array[i];
}
return pcValue.toInt();
}
// Nombre de chiffre int
int numDigits(int number) {
if (number == 0) {
return 1;
}
int digits = 0;
if (number < 0) digits = 1; // compte le signe moins pour les nombres négatifs
while (number) {
number /= 10;
digits++;
}
return digits;
}
void rotation_montre() {
digitalWrite(M1dirpin, LOW);
digitalWrite(M1steppin, LOW);
delayMicroseconds(2);
digitalWrite(M1steppin, HIGH);
delayMicroseconds(750);
}
void rotation_inverse() {
digitalWrite(M1dirpin, HIGH);
digitalWrite(M1steppin, LOW);
delayMicroseconds(2);
digitalWrite(M1steppin, HIGH);
delayMicroseconds(750);
}
void imprimante(int codeCasierNumber, int codeCasier) {
printer.underlineOn();
printer.justify('C');
printer.setSize('M');
printer.println("-------------------------");
printer.println(F("KEROGS INFINITE - BRAS"));
printer.println("-------------------------");
printer.print(F("Casier Numero "));
printer.print(codeCasierNumber);
printer.print(F("\n"));
printer.setSize('L');
printer.boldOn();
printer.println(F("CODE"));
printer.println(codeCasier);
printer.setSize('M');
printer.justify('C');
printer.println("-------------------");
printer.boldOff();
printer.print(F("\n"));
printer.print(F("\n"));
printer.setSize('S');
printer.feed(2);
printer.setDefault(); // Restore printer to defaults
}
void monitorSerialSpace() {
if (serialSpaceReset) {
for (int i = 0; i <= 100; i++) {
Serial.println("");
}
}
}