Skip to content

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("");
    }
  }
}

Documentation/code du Projet B.R.A.S présent sur ce site sous license CC BY 4.0. (pour en savoir plus rdv dans la section LICENSE)