
// ███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
// ██                                                   ██                                                                                                          ██
// ██     ██╗          ████████╗           ███████╗     ██   Micro OS pour Arduino R4 Minima et Ethernet Shield version 2 (W5500)              Biechy Jean-Marc     ██
// ██     ██║  ██████  ╚══██╔══╝  ██████   ██╔════╝     ██    - Shell CLI en Serial et Telnet                                                radiobiechy@gmail.com  ██
// ██     ██║ ██    ██╗   ██║    ██    ██╗ ███████╗     ██    - Serveur WEB FTP (index.htm confIP.htm sur carte SD)                                                 ██
// ██     ██║ ██    ██║   ██║    ██    ██║      ██║     ██    - Gestionnaire de Fichier : SDCARD                                                                    ██
// ██     ██║  ██████╔╝   ██║     ██████╔╝ ███████║     ██    - Datalogger                                                                                          ██
// ██     ╚═╝   ╚════╝    ╚═╝      ╚════╝  ╚══════╝     ██   Institution Saint-Jean -- Ecole d'Electronique Informatique et Reseau -- Colmar France 2026            ██
// ██                                                   ██                                                                                                          ██
// ███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████     
/*
*
* ####  Description du SYSTEM TECHNIQUE  ####
*
*      ╔═══════════════════════════════════════════════════════════════════════════════════════════════════╗
*      ║   Prise IP ── Commande LED par page WEB   -- Version Affichage sur Ecran LCD  Grove Black Light   ║
*      ╚═══════════════════════════════════════════════════════════════════════════════════════════════════╝
*
*
* Version Arduino UNO Rev 4 Minima - Ethernet Shield version 2 (W5500) - Grove Base Shield 
*
*
*
*
*  ┌───────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ 
*  │ [ IoToS ] │ Internet of Things OS                                        Arduino UNO Rev 4 Minima - Renesas RA4M1                           │
*  ├───────────┼──────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────┤ 
*  │   [CLI]   │ Shell cmdLine : Serial / Telnet / Bluetooth (ESP32)      │ - TAB : Autocompletion                                               │ 
*  │           │ - Fleches Haut/Bas : Historique                          │ - login / password sur Serial et Telnet                              │ 
*  │           │ (Mini MS-DOS)                                            │ - dir -- rename -- del -- type -- copie                              │ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [SD]    │ Gestion Fichiers Micro SD  ou  LittleFS sur ESP          │ - Arduino UNO SD Card sur Ethernet Shield V2 port SD                 │ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [NET]   │ Config : ip -- subnet -- gateway -- mac -- dhcp          │ - Outils : Ping complet  --  tracert <URL>  --  netstat              │ 
*  │           │          port WEB (80)                                   │ - Horloge NTP (synchronisation temps Internet)                       │ 
*  ├-──────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [WEB]   │ Serveur HTTP AJAX (port 80)                              │ - Authentification Login/Password Base64  ON/OFF                     │ 
*  │           │ Pages htm/css stockees sur Micro SD Card                 │ - Modification Login:Password : base64encode.org                     │ 
*  │           │ Commande LED Arduino par boutons CSS                     │ - Configuration IP Ethernet par page WEB                             │ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [FTP]   │ Serveur FTP (port 21)                                    │ - Acces Micro SD Card  (site WEB + fichiers Datalogger)              │ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [LOG]   │ Datalogger Excel (csv) sur Micro SD                      │ - Horodatage NTP  --  Etat LED  --  Evenements                       │ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [EEP]   │ Sauvegarde des Parametres Systeme sur EEPROM Interne     │ - Fonctions : save -- reload -- defaults reset (reboot + load EEPROM)│ 
*  ├───────────┼──────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤ 
*  │   [LCD]   │ Ecran Grove_LCD_RGB_Backlight_master sur Port I2C        │                                                                      │ 
*  │           │                                                          │                                                                      │ 
*  └-──────────┴──────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┘ 
*
* Mini DOC a la fin du fichier 
*
************************************************************************************************************************************************************
* IDE 2.3.7 (IDE 1.x.x Bug ethernet IP Fixe)
* Carte : Outils --> Type de carte --> Arduino UNO R4 Minima
* Fichier sur carte Micro SD : Micro SD FAT32 System MSDOS : Nom Fichiers Long
* Ethernet - Arduino UNO R4 Minima Librairie : 1.5.3 -- Ethernet@2.0.2
* Copier les autre Libraire dans le sous repertoire \Mes Documents\Arduino\libraries\
* Attention certaine librairies ont ete mis a jours pour l'Arduino R4 Minima
*
* Le croquis utilise 161972 octets (61%) de l'espace de stockage de programmes. Le maximum est de 262144 octets.
* Les variables globales utilisent 16020 octets (48%) de mémoire dynamique, ce qui laisse 16748 octets pour les variables locales. 
* Le maximum est de 32768 octets.
* Un double appui rapide sur RESET active le bootloader : permet de televerser le programme 
************************************************************************************************************************************************************
************************************************************************************************************************************************************
*     ## Cablage des PORT de l'Arduino -- Connexion des Modules Groves 
************************************************************************************************************************************************************
* Arduino avec module Grove BASE
* ## Entree :   
*    D8 : Bouton OK -- D2 D3 Bouton (+) et (-)
* 
* ## Sortie :   
*    Module LED sur PORT Digital D5
*    http://wiki.seeedstudio.com/Grove-Red_LED/
*    http://wiki.seeedstudio.com/Grove-LED_Socket_Kit/
*
* ## Entree / Sortie I/O :
*    Ethernet 2 Shield (W5500)
*    https://store.arduino.cc/products/arduino-ethernet-shield-2
* 
*  PORT SPI
*  Ethernet 2 Shield (W5500)
*  https://store.arduino.cc/products/arduino-ethernet-shield-2
* 
************************************************************************************************************************************************************
*     ## Librairie :
************************************************************************************************************************************************************
* Arduino Serial Commande Line (cmdLine)                   : Attention Librairie Modifiee a cause du Telnet !!!!!!
* Version originale : https://github.com/IndustrialShields/arduino-cmdLine
* Rechercher version : cmdLineTelnet_SD
*
* Lib Gestion carte SDFat version 2.3.1
* GitHub - greiman-SdFat- Arduino FAT16-FAT32 exFAT Library
*
* Arduino SimpleFTPServer-master
* https://github.com/xreef/SimpleFTPServer
* https://mischianti.org/category/my-libraries/simple-ftp-server/#google_vignette
*
* NTPClient2 (temps Internet)
* https://phatiphatt.wordpress.com/esp32-date-and-time-ntp-client/
*
* Ping EthernetICMP
* https://github.com/andrew-susanto/Arduino-Ethernet-Icmp?utm_source=chatgpt.com
*
* MemoryFree  
* https://github.com/mpflaga/Arduino-MemoryFree
*
*-------------------------------------------------------------------------------------------
*  
* Grove_LCD_RGB_Backlight_master sur Port I2C
* http://wiki.seeedstudio.com/Grove-LCD_RGB_Backlight/
*
* Watchdog TickTwo-main
* https://github.com/sstaub/TickTwo
***********************************************************************************************************************************************************
* IoToS - Internet of Things Operating System                                                                                                             *
* Firmware : Telnet CLI | Serveur WEB | FTP | NTP | SD | Ethernet W5500 |                                                                                 *
* Plateforme : Arduino UNO R4 Minima - Renesas RA4M1 / ARM Cortex-M4                                                                                      *
* Licence    : GNU LGPL v2.1  https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html                                                                     *
***********************************************************************************************************************************************************
* DROITS ACCORDES                                OBLIGATIONS (redistribution uniquement)                                                                  *
* - Usage libre y compris commercial             - Distribuer les sources IoToS modifiees                                                                 *
* - Modification des fichiers IoToS              - Conserver les en-tetes de copyright                                                                    *
* - Integration dans un firmware proprietaire    - Mentionner l'usage d'IoToS et sa licence                                                               *
* - Code applicatif (.ino) reste votre propriete - Ne pas ajouter de restrictions suppl.                                                                  *
*                                                                                                                                                         *
***********************************************************************************************************************************************************
* BIBLIOTHEQUES TIERCES - chacune conserve sa licence d'origine                                                                                           *
*----------------------+---------+-------------------+-------+------------------------------------------+-------------------------------------------------*
* Bibliotheque         | Version | Licence           | Mod.  | Depot                                    | Obligation                                      *
*----------------------+---------+-------------------+-------+------------------------------------------+-------------------------------------------------*
* Arduino-MemoryFree   | -       | Beerware          | Non   | github.com/sudar/MemoryFree              | Aucune                                          *
* EthernetICMP         | -       | LGPL v2.1 (*)     | OUI   | Bluebird-Software/Arduino-Ethernet-Icmp  | Distribuer .h/.cpp modifies                     *
* NTPClient2           | -       | MIT               | OUI   | arduino-libraries/NTPClient              | Conserver copyright                             *
* SdFat                | v2.x    | MIT (**)          | Non   | github.com/greiman/SdFat                 | Conserver copyright                             *
* SimpleFTPServer      | -       | MIT               | Non   | github.com/xreef/SimpleFTPServer         | Conserver copyright                             *
* U8g2 (code)          | 2.35.30 | BSD 2-Clause      | Non   | github.com/olikraus/U8g2_Arduino         | Conserver copyright                             *
* U8g2 (polices)       | 2.35.30 | OFL/MIT/BSD/Adobe | Non   | olikraus/u8g2/wiki/fntgrp (par police)   | Verifier par police                             *
*----------------------+---------+-------------------+-------+------------------------------------------+-------------------------------------------------*
*                                                                                                                                                         *
* (*) EthernetICMP : licence duale GPL v2 / LGPL v2.1 - IoToS choisit LGPL v2.1.                                                                          *
*     Modif. RA4M1  : ping W5500, TRACERT TTL 1-30, timeout ARM, socket AVR->EthernetUDP.                                                                 *
*                                                                                                                                                         *
* (**) SdFat v1.x etait GPL v3 - utiliser exclusivement v2.x (MIT).                                                                                       *
*      Modif. RA4M1 : SPI_SD_ON/ETH_ON dans FtpServer.cpp, SPI->SD->Wire, SdFat/SdFile v2.                                                                *
*                                                                                                                                                         *
* NTPClient2      mod. : getFormattedDateTime() JJ/MM/AAAA HH:MM:SS, getDayOfWeek() FR,                                                                   *
*                        backend EthernetUDP W5500, offset UTC+1/+2.                                                                                      *
* SimpleFTPServer mod. : fix DEBUG_PRINT (#ifndef guard), SPI_SD_ON/OFF autour acces SD.                                                                  *
* U8g2            mod. : boot I2C apres SPI (SPI>SD>Wire>LCD>ETH), adr 0x3F*2, PROGMEM logo.                                                              *
*                                                                                                                                                         *
***********************************************************************************************************************************************************
* GARANTIE : FOURNI EN L'ETAT SANS GARANTIE. AUTEUR NON RESPONSABLE DES DOMMAGES RESULTANTS.                                                              *
***********************************************************************************************************************************************************
* Auteur   : Jean-Marc Biechy     ---     Ecole d'Electronique Inforamtique et Reseau : Institution Saint-Jean Colmar France      ---    Date : 1/03/2026 *
***********************************************************************************************************************************************************/

//
// ██╗       ██████╗   █████╗  ██████╗        ███████╗ ██╗ ██████╗  ███    ███╗ ██     ██╗  █████╗  ██████╗  ███████╗
// ██║      ██╔═══██╗ ██   ██╗ ██╔══██╗       ██╔════╝ ██║ ██   ██╗ ████  ████║ ██     ██║ ██   ██╗ ██   ██╗ ██╔════╝
// ██║      ██║   ██║ ███████║ ██║  ██║       █████╗   ██║ ██████╔╝ ██║████╔██║ ██  █  ██║ ███████║ ██████╔╝ █████╗
// ██║      ██║   ██║ ██╔══██║ ██║  ██║       ██╔══╝   ██║ ██╔══██╗ ██║ ██╔╝██║ ██ ███ ██║ ██╔══██║ ██╔══██╗ ██╔══╝
// ███████╗ ╚██████╔╝ ██║  ██║ ██████╔╝       ██║      ██║ ██║  ██║ ██║ ╚═╝ ██║  ███╔███╔╝ ██║  ██║ ██║  ██║ ███████╗
// ╚══════╝  ╚═════╝  ╚═╝  ╚═╝ ╚═════╝        ╚═╝      ╚═╝ ╚═╝  ╚═╝ ╚═╝     ╚═╝  ╚══╝╚══╝  ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚══════╝
//
/***********************************************************************************************************************************************************/
// #####   ----   Declaration Librairie   ----    #####
/***********************************************************************************************************************************************************/
// Declaration Librairie
const char* hostname = "PriseIP_UNO_R4";                                            // Nom de l'Arduino en DHCP ?????

// ---------->  Watchdog UNO R4


// ---------->  EEPROM bus SPI
#include <EEPROM.h>                                                                 // 8ko EEPROM -- Librairie LOCAL de l'IDE d'Arduino : Librairie eeprom 
#include <SPI.h>                                                                    // SPI I2C    -- Librairie LOCAL de l'IDE d'Arduino

// ---------->  Initialisation Carte Reseau : Arduino UNO rev4 minima et shield ethernet2 (A000024 W5500)
#include <Ethernet.h> 
// Define Chip Select for your SD card according to hardware // #define CS_SDCARD 4       // SD card reader of Ehernet shield
// Define Reset pin for W5200 or W5500  // set to -1 for other ethernet chip or if Arduino reset board is used
// #define W5x00_RESET -1

// ---------->  Initialisation Carte SD : SdFat-master SdFat version 2.3.1
// Activer les noms longs (LFN) dans SdFat : Ouvrir SdFatConfig.h et chercher les lignes suivantes #define USE_LONG_FILE_NAMES 1 -- #define SDFAT_FILE_TYPE 1  ou #define SDFAT_FILE_TYPE 3 off    mais bug carte micro sd
//#include <SPI.h>
#include <SdFat.h>
#define SD_CS   4                                                                   // Selection carte SD
#define ETH_CS 10                                                                   // Selection carte Reseau

SdFat sd;                                                                           // SdFs sd;
FsFile root;
boolean microSD = 0;                                                                // 0 OFF / 1 ON Micro SD Card et partion Fichiers

// ---------->  DNS
#include <Dns.h>
IPAddress timeServer;                                                               // https://services.renater.fr/ntp/serveurs_francais
DNSClient dns;                                                                      // initialisation pour dns.begin(Ethernet.dnsServerIP());

// ---------->  Time NTP : Temps Internet
#include <NTPClient.h>                                                              // A besoin du DNS
//#include <EthernetUdp.h>
EthernetUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// Vous pouvez specifier le pool de serveurs de temps et le decalage (en secondes, peut etre change plus tard avec setTimeOffset ()). De plus, vous pouvez specifier le
// intervalle de mise a jour (en millisecondes, peut etre modifiee a l'aide de setUpdateInterval ()). NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);   // IPAddress timeServer;     // NTP server address
char date[10] = {0};

// ---------->  FTP _DOC Version ---   SimpleFTPServer 3.0.2 ok UNO Rev4 ok
// A mettre dans le fichier D:\Documents\Arduino\libraries\SimpleFTPServer-master\FtpServer.h
//#undef DEFAULT_STORAGE_TYPE_ARDUINO
//#define DEFAULT_STORAGE_TYPE_ARDUINO  STORAGE_SDFAT2                                //#define DEFAULT_STORAGE_TYPE_ARDUINO STORAGE_SDFAT1 off
#include <FtpServer.h>
FtpServer ftpSrv;                                                                     //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial
char etatFTP = 2;                                                                     // Met etatFTP a 2 au cas ou il est en off  ::  etatFTP = 2 pas connecte -- 3 4 5 109 en cours connexion -- 5 connecte -- 77 copie en cours

// Fichier CSV
String fileTxt; 
EthernetServer serverFTP(21);
//EthernetClient hasClient;

// ---------->  Initialisation de la Librairie Ethernet WEB Server -------------------
//#include <EthernetClient.h> //#include <EthernetUdp.h>
EthernetServer server(80);

// ---------->  Initialisation de la Librairie Client Telnet 
EthernetServer serverTelnet(23);                                                      // EthernetServer serverTelnet = EthernetServer(23);
EthernetClient clientTelnet;
boolean premiereConnexionTelnet = 1;                                                  // variable de demarrage (pour nexecuter qu'une foi l intro
unsigned long timeoutDeconnexionTelnet = 0;                                           // pour remettre premiereConnexionTelnet = 1 execute intro
const int telnetTimeDuree = 2 * 60 * 1000;                                            // duree 

// ---------->  Librairie Commande Line CmdLine CLI -- serial / Telnet                 // Version Lib modifiee
#include <CmdLineTelnet_UNOR4.h> 
CmdLine cmdLine(Serial);
#define countof(commands) (sizeof(commands)/sizeof(commands[0]))
boolean cliEcho = true;                                                               // Desactive l'echo de la lib cmdLine pour MobaXtern (evite bug de double lettre 
   
// ---------->  Print RAM Free
#include <MemoryFree.h>
#include <pgmStrToRAM.h>

// ---------->  Ping ICMP ----------                                                  // Version LIB modifiee pour tracert
#include <utility/w5100.h>                                                            // Pour Netstat
#include <EthernetICMP.h>
SOCKET pingSocket = 7;
char buffer [256];
EthernetICMPPing ping(pingSocket, (uint16_t)random(0, 255));
//EthernetICMPPing *ping;     // objet créé plus tard dans setup()
					 

/***********************************************************************************************************************************************************/
// #####   ----   Variables et Constantes Globales Programme    ----    #####
/***********************************************************************************************************************************************************/
// Parametre de la carte Reseau                             
IPAddress myDNS(1,1,1,1);                               // Cloudflare
//const byte DNS1[] = { 4, 4, 4, 4 };                   // DNS  //const byte dnsIP0[] = { 8, 8, 8, 8 };   const byte DNS1[] = { 212, 27, 40, 240 }; // DNS Free  //const byte DNS0[] = { 89, 2, 0, 1 };                  // DNS

// Variable Structure EEPROM
#define VALID        111110171                          // Pour valider les Info dans l'EEPROM : si on reprogramme une ancienne version sur une nouvelle il faut un nombre qui permet de voir que ce n'est pas la meme strucure sinon bug et les valeurs de l'ancien se melange avec la nouvelle structure

typedef struct {                                        // https://www.squalenet.net/fr/ti/tutorial_c/14-structures-unions.php5
  uint32_t validity;                                    // ID Cette variable permet de verifier que l'EEPROM a deja ete programme par ce programme Valeur de test pour savoir si des donnes sont valid en EEPROM (de type Adresse IP)
  char nameSystem[40];                                  // Nom du system
  char telnetPassword[40];                              // Mot de passe connexion cmdLine et Telnet  
  boolean login_cmdTelnetSwitch;                        // Validation a l acces du cmdLine et au telnet 1 Active password // 0 Desactive
 
  boolean SrvWEBswitch;                                 // Switch Serveur WEB
  boolean SrvFTPswitch;                                 // Switch Serveur FTP
     
  boolean led;                                          // Etat de la LED 

  uint8_t mac[6];                                       // local MAC address
  boolean dhcp;                                         // Arduino configure en IP STATC = 0 // Arduino configure en IP DHCP = 1 
  uint8_t ip[4];                                        // local IP address
  uint8_t subnet[4];  
  uint8_t gateway[4];
  uint16_t port;                                        // Port serveur WEB

  boolean loginWEB;                                     // ON / OFF : Login et Password du site WEB
  char loginPasswordWEB[40];                            // dXNlcjpwYXNz = 'user:pass' (user:pass) base64  /////  (admin:01_Admin YWRtaW46MDFfQWRtaW4=)   https://www.base64encode.org/ 

  char loginFTP[40];
  char passwordFTP[40];
  
// Datalogger
  boolean dataloggerSwitch;                             // Valide Datalogger
  char fichierEnCours[40];
  unsigned char lcdRetro;                               // retroeclairage
  char timeReboot[25];                                  // temps du dernier reboot "YYYY-MM-DDTHH:MM:SSZ"

 unsigned char LCDrgb;                                  // Niveau d eclairement 0 255  -- Attention sur l'ESP 8266 la consommation est limite (eclairage 255 bug du programme ....

																																
} conf_t;
conf_t conf;                                            // conf est la variable structure avec les information conf.ip[] , conf.subnet[] ....
conf_t conf_TMP;

// Definition des valeurs Reseau par defaut
const conf_t default_conf = {
  VALID,                                                // ID Cette variable permet de verifier que l'EEPROM a deja ete programme par ce programme 
  "PriseIP_UNO_R4",                                     // Nom du system
  "changerLeMotDePasse",                                // Mot de Passe Connexion cmdLine et Telnet
  0,                                                    // login off // 0 acces du cmdLine et au telnet
  1,                                                    // WEB Switch
  1,                                                    // FTP Switch
  
  0,                                                    // Etat LED

  {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xB1},                 // mac  DE:AD:BE:EF:FE:B1   DE:AD:BE:EF:FE:B2
  0,                                                    // dhcp
  { 192, 168, 0,   10  },                               // ip
  { 255, 255, 255, 0   },                               // Masque sous reseau
  { 192, 168, 0,   254 },                               // Passerelle
  80,                                                   // PORT WEB 0-- 65536 Par defaut port serveur WEB : 80

  0,                                                    // Enable =1 // Disable = 0 --> Login et Password
  "dXNlcjpwYXNz",                                       // dXNlcjpwYXNz = 'user:pass' (user:pass) base64  ////   https://www.base64encode.org/ 
  
  "arduino",                                            // Login FTP
  "arduino",                                            // MdP FTP

  0,                                                    // ON / OFF Datalogger  
  "datalogger.csv",                                     // Nom fichier datalogger
  200,                                                  // conf.lcdRetro retro de 0 a 255
  "YYYY-MM-DDTHH:MM:SSZ",                               // taille suffisante pour "YYYY-MM-DDTHH:MM:SSZ" + '\0'

  32,                                                   // Niveau eclairement LCD
																		
};
// Nom du Fichier ino : Attention il faut creer le __FILE__ dans le fichier principal (ino)   // https://forum.arduino.cc/t/filename-ino-as-string-variable/583738/20
  String ino = __FILE__;
//  ino = (ino.substring((ino.indexOf(".")), (ino.lastIndexOf("\\")) + 1));
  String date_ino = __DATE__;
  String time_ino = __TIME__;
  
// Declaration Valeurs programme (Etiquette = Valeur) 
unsigned char adressBase = 5;                               // Adresse de base de depart de l'ecriture des DATA en EEPROM
boolean etatWAN = 0;                                        // Etat connexion Internet (google DNS)
boolean dhcpEtat = 0;                                       // Etat du mode de la carte reseau ( basculement automatique en mode dhcp si l aconfiguration reseau de l'Arduino est fausse)

// Serial
unsigned long startSerial = millis();
boolean premiereConnexionSerial = 1;
boolean connexionTelnet = 0;
boolean etatPrecedentConnexionSerial = 0;
boolean etatActuelConnexionSerial = 0;

// Login Telnet
unsigned long nbrEssaiLoginTelnet = 30;                 // Nombre d'essai login Telnet : base 30 sec
unsigned long previousMillisTelnet = 0;                 // Time entre deux essai Telnet
// Variable commune a plusieur Fonction (Variable de Transfert inter Fonction)
// Datalogger
const char * fichierLittleFS_datalogger = "datalogger.csv";           // Nom du Fichier copier dans la partition LittleFS !!! Voir procedure pour televerser le fichier !!!!
const char * formatCSV = "Date ; Heure ; Etat Alarme ; Alarme ; Alarme detecte ; Telecommande";     // Entete du Fichier Excel

// Declaration PORT Entrer Sortie de l'Arduino 
#define pinled D5  

/***********************************************************************************************************************************************************/
// #####   ----   Declaration Include et Fonctions    ----    #####
/***********************************************************************************************************************************************************/
// Fonction utilisee par plusieurs header .h               // Creation de la Fonction pour que la compilation ne BUG pas -- Les Fonctions sont plus bas 
void InfoVersion();                                        // Fonction Affichage Version
void Datalogger();                                         // SousProg : Appel Datalogger enregistrement dans conf.fichierEnCours
void AffichageLCD_Principale();                            // SousProg : Affichage sur ecran LCD	
void ServeurWEB(EthernetClient &client);                   // SousProg : ServeurWEB             
byte parseNibble(const char *arg);                         // Affichage Adresse MAC
byte parseByte(const char *arg);                           // Affichage Adresse MAC
void PrintMAC(uint8_t mac[6]);                             // Affichage Adresse MAC
boolean TestValidityIPadress();                            // Fonction Test validite adresse IP <--> MSR  <--> Pass

// Fichier include header (en .h) (Sous Programme) 
#include "utils.h"                                         // Fonction commune a plusieurs headers -- Datalogger - ValiIP ... 
#include "Shell_CmdLine_SD.h"                              // Shell CLI : Fonction Commande Line (cmd) Telnet / Serial de configuration    <Commande> <arg>
#include "ServeurWEB.h"                                    // Serveur WEB
#include "Driver_Ethernet_Reseau.h"                        // Initalisation de l'Arduino UNO R4 et de la carte Ethernet2 ---> Ethernet 			   
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void InfoVersion() {
   cmdLine.println( F("\033[1;31;40m"));   // Changement de couleur du serial : Affiche du texte jaune sur fond noir // https://xdevs.com/guide/color_serial/    
   //                          \033[couleur vive;couleur police;fond ecran;  
   cmdLine.println();  cmdLine.println();  cmdLine.println();  cmdLine.println();
   cmdLine.println( F(" *********************************************************"));   
   cmdLine.println( F(" *                                                       *"));
   cmdLine.println( F(" *           ###          #######         ###            *"));
   cmdLine.println( F(" *            #              #           #               *"));     
   cmdLine.println( F(" *            #      ##      #     ##     #              *"));
   cmdLine.println( F(" *            #     #  #     #    #  #     #             *"));
   cmdLine.println( F(" *            #     #  #     #    #  #      #            *"));
   cmdLine.println( F(" *           ###     ##      #     ##    ###             *"));
   cmdLine.println( F(" *                                                       *")); 
   cmdLine.println( F(" *********************************************************"));
   cmdLine.println( F(" *         -----  Arduino UNO Rev 4 Mini  -----          *"));
   cmdLine.println( F(" *                                                       *"));   
   cmdLine.println( F(" * Programme : Prise IP -- WEB Control Datalogger        *"));
   cmdLine.println( F(" *                                                       *"));
   cmdLine.println( F(" * ### Configuation en Ligne de commande cmd Line        *"));
   cmdLine.println( F(" * - CLI en Serial (cmdLine)  -- login                   *"));
   cmdLine.println( F(" * - CLI en Telnet (cmdLine)  -- login                   *")); 
   cmdLine.println( F(" *   TAB Autocompletion - Historique fleche Haut/Bas     *"));
   cmdLine.println( F(" * Ping (complet), tracert, Netstat                      *")); 
   cmdLine.println( F(" *                                                       *"));
   cmdLine.println( F(" * ### Services :                                        *"));
   cmdLine.println( F(" * - Serveur WEB AJAX (fichier htm sur Micro SD Card)    *"));
   cmdLine.println( F(" *   - Login Authentification page WEB                   *"));
   cmdLine.println( F(" * - Configuration Ethernet IP par page WEB              *")); 
   cmdLine.println( F(" * - Serveur FTP (fichier sur carte Micro SD)            *"));  
   cmdLine.println( F(" * - Datalogger avec time NTP (fichier en Micro SD Card) *"));   
   cmdLine.println( F(" *                                                       *"));   
   cmdLine.println( F(" * ### Ecran :                                           *"));  
   cmdLine.println( F(" * - Ecran d'affichage LCD I2C Grove Blacklight          *"));  
   cmdLine.println( F(" *                                                       *"));  
   cmdLine.println( F(" * Micro OS -= IoToS =-                       Biechy v72 *"));
   cmdLine.println( F(" *********************************************************"));
   cmdLine.println( F("\033[0;39;49m")); // Serial color defaut 
   cmdLine.println(); 
}
void InfoSerial() {
  Serial.println(); Serial.println(); Serial.println(); Serial.println();
  Serial.println(F(" -- La vitesse de transmission SERIAL est de 115200 Bauds -- "));
  Serial.println(F(" --       Configurer votre PC (IDE Arduino ou PUTTY)      -- ")); 
  Serial.println(); Serial.println(); Serial.println(); Serial.println();
}
//
//  ██████╗    ██████╗    ██████╗  ████████╗       ██╗       ██████╗   █████╗  ██████╗  ███████╗ ██████╗ 
//  ██╔══██╗  ██╔═══██╗  ██╔═══██╗ ╚══██╔══╝       ██║      ██╔═══██╗ ██   ██╗ ██╔══██╗ ██╔════╝ ██╔══██╗
//  ██████╔╝  ██║   ██║  ██║   ██║    ██║          ██║      ██║   ██║ ███████║ ██║  ██║ █████╗   ██████╔╝
//	██╔══██╗  ██║   ██║  ██║   ██║    ██║          ██║      ██║   ██║ ██╔══██║ ██║  ██║ ██╔══╝   ██╔══██╗
//  ██████╔╝  ╚██████╔╝  ╚██████╔╝    ██║          ███████╗ ╚██████╔╝ ██║  ██║ ██████╔╝ ███████╗ ██║  ██║
//  ╚═════╝    ╚═════╝    ╚═════╝     ╚═╝          ╚══════╝  ╚═════╝  ╚═╝  ╚═╝ ╚═════╝  ╚══════╝ ╚═╝  ╚═╝
// 
/***********************************************************************************************************************************************************/
//#####   ----   Initialisation (Setup)       
/***********************************************************************************************************************************************************/
void setup() {
	// IO LED_BUILTIN
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);  // ON
// Initialisation Liaison série Arduino --> USB --> PC : Pour DEBUG 

//   Serial.begin(9600);   while (!Serial) { ; /* wait for serial port to connect. Needed for native USB */ }          delay(100);  InfoSerial();  delay(250);    Serial.flush();
//   Serial.begin(57600);  while (!Serial) { ; /* wait for serial port to connect. Needed for native USB */ }          delay(100);  InfoSerial();  delay(100);    Serial.flush();
//   Serial.begin(19200);  while (!Serial) { ; /* wait for serial port to connect. Needed for native USB */ }          delay(100);  InfoSerial();  delay(100);    Serial.flush();

  Serial.begin(115200);   // while (!Serial) { ; /* wait for serial port to connect. Needed for native USB */ } 
  while (!Serial && millis() - startSerial < 2000)   { ;    /* attend max x seconde */  }
  delay(100);
  Serial.println(F("######################################################################################################################"));
  InfoVersion();
  OK();   Serial.println(F("## Boot IoToS pour Arduino UNO Rev 4  (setup run) ............... "));
// Affichage du Nom du Fichier ino :                                                                // https://forum.arduino.cc/t/filename-ino-as-string-variable/583738/20
  String ino = __FILE__;
  ino = (ino.substring((ino.indexOf(".")), (ino.lastIndexOf("\\")) + 1));
  VIDE(); Serial.print  (F("   Nom du Programme source ino : "));  Serial.println(ino);                      // Print le nom du Fichier ino
  OK();   Serial.println(F("## Serial ok !"));                        

// Load EEPROM configuration
  OK();   Serial.print   (F("## EEPROM Loading"));
  boolean login_cmdTelnetSwitchTemp = conf.login_cmdTelnetSwitch;                                   // Cree une variable temporaire qui enregistre la valeur de //login_cmdTelnetSwitch
  conf.login_cmdTelnetSwitch = 0;										                            // Deractive le login telnet																					
  LoadConfEEPROM(nullptr);
  conf.login_cmdTelnetSwitch = login_cmdTelnetSwitchTemp;                                           // Remet l'etat du login telnet	
 
// Configuration PORT IO Arduino   
  OK();   Serial.print  (F("## PORT I/O Initialisation"));
  pinMode(pinled, OUTPUT);                                                                          // LED prise IP
  //digitalWrite(pinled, LOW);
  pinMode(LED_BUILTIN, OUTPUT);                                                                     // LED de l'Arduino D13
  digitalWrite(LED_BUILTIN, LOW);                                                                   // LED de l'Arduino -->  0 : ON  // 1 : OFF
  digitalWrite(pinled, conf.led);                                                                   // Charge letat de la LED
  Serial.println();

// Initialisation LCD Blacklight
  OK();   Serial.println(F("## LCD Blacklight Initialisation"));
  lcd.begin(16, 2);                                                                                 // Initialisation 16 Caractères et 2 lignes
//  lcd.clear();                                                                                    // Efface le LCD
  // AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2
  AfficheLCD   (  64,   0,  64, 1, "--   Prise IP   --" );
  AfficheLCD   (  64,   0,  64, 2, "Boot...." );  
  delay(1000);

  
  // Initialisation de la partition SD  ---- BUS SPI
  // Ethernet W5500	pin SS (D10) --  SD card	D4
  OK();   Serial.println (F("## SPI Initialisation"));
  pinMode(SS, OUTPUT);           digitalWrite(SS,     HIGH);       // D10
  pinMode(SD_CS, OUTPUT);        digitalWrite(SD_CS,  HIGH);       // D4
  pinMode(ETH_CS, OUTPUT);       digitalWrite(ETH_CS, HIGH);       // D10
  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  SdSpiConfig spiConfig(SD_CS, SHARED_SPI, SD_SCK_MHZ(1));                                          // SdSpiConfig spiConfig(SD_CS, DEDICATED_SPI, SD_SCK_MHZ(25));   // Erreur DEDICATED_SPI 

  VIDE();Serial.println(F("## Test partition Fichiers SD : .......  "));
  if (!sd.begin(spiConfig)) {
	  FAILED();    Serial.println(F("   - ERROR Erreur de Lecture de la partition Micro SD Card !"));
      VIDE();    Serial.println(F("\033[;37;41m###     ATTENTION  !!! ###     : La carte Micro SD est absente ou mal formate !!! (FAT) \033[0;39;49m")); 
      VIDE();    Serial.print  (F("    o Erreur SD. Code : 0x"));        Serial.println(sd.card()->errorCode(), HEX);
      VIDE();    Serial.print  (F("    o Data            : 0x"));        Serial.println(sd.card()->errorData(), HEX);
      microSD = 0;
      //while (true); // on ne va pas plus loin
   // AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2
  AfficheLCD   (  64,   0,  64, 1, "--   Prise IP   --" );
  AfficheLCD   (  64,   0,  64, 2, "Micro SD .. Down" );  
  delay(1000);
  }
  else
  { 
     OK();    Serial.println(F("## Partition et fichiers sur Micro SD : OK !"));
     VIDE();  Serial.println(F("   FAT32 Les noms fichiers sont de type DOS etendu"));
     microSD = 1;
     //Ddir(nullptr);                                                                                // Liste des Fichiers Info Partition SD
  AfficheLCD   (  64,   0,  64, 1, "--   Prise IP   --" );
  AfficheLCD   (  64,   0,  64, 2, "Micro SD .... ok" );  
  delay(1000);
  }



// Initialisation de la Liaison Ethernet avec le Shield Ethernet 2 --> Includ Ethjernet_Reseau       // 
  Initialisation_Ethernet();                                                                         // ---> Execute Fichier Ethernet_Reseau.h
  if (etatWAN == 1) 
  {
	  OK();      Serial.println(F("## Internet ok "));
  }
  else
  {
	  FAILED();  Serial.println(F("## Internet Down "));
  }	  
  
// Initialisation Fonction Librairie --->  Telnet                                                    // Demarrage Telnet Connexion // serverTelnet = EthernetServer(23);
  serverTelnet.begin();                                                                              //serverTelnet.setNoDelay(true);                                                                                                   
  OK();        Serial.println(F("## Telnet Serveur : OK !"));                                        // Serial.println(F("Dans Putty ou Kytty : Telnet port 23"));
  Serial.println();                                                                                  // Serial.println(F("Si besoin : Dans le menu Telnet decocher : Return key sends Telnet New Line instead of ^M  "));
                                                                                                     // Si on ne parammetre pas Putty : le caractere seront duplique : pprriinntt

// Serveur FTP START 
  if (microSD  == 1) {
      OK();        Serial.println(F("## FTP START : OK !"));                                         //      ftpSrv.setCallback(_callback);   //      ftpSrv.setTransferCallback(_transferCallback);      
      ftpSrv.begin(conf.loginFTP,conf.passwordFTP);                                                  // username, password for ftp.  set ports in ESP8266FtpServer.h  (default 21, 50009 for PASV)                                                                            // Liste des Fichiers Info Partition SD
      VIDE();      Serial.println(F("   - Sur FileZilla : ")); 
      VIDE();      Serial.println(F("     Cliquer sur Fichier --> Gestion de sites --> Parametre de Transfert --> Limiter le nombre de connexion a 1")); 
      AfficheLCD   (  64,   0,  64, 1, "--   Prise IP   --" );
      AfficheLCD   (  64,   0,  64, 2, "FTP ....... Down" );  
      delay(1000);
  }
  else
  { 
      FAILED();  Serial.println(F("## Partition FS ERROR : FTP Down !!")); 
      AfficheLCD   (  64,   0,  64, 1, "--   Prise IP   --" );
      AfficheLCD   (  64,   0,  64, 2, "FTP ....... Down" );  
      delay(1000);
  }

// Time NTP
  if ( etatWAN == 1 )                         // Si mode STA (WiFi Normal)
     {
          OK();        Serial.println(F("## Serveur NTP (Real Time) : START !"));
          timeClient.update();

          OK();        Serial.print("Date  : ");         Serial.println(timeClient.getFormattedDate() );          // Get Date : 2020-03-21T02:28:47Z
          OK();        Serial.print("Heure : ");         Serial.println(timeClient.getFormattedTime() ); 
          OK();        Serial.print("UNIX  : ");         Serial.println(timeClient.getEpochTime() );
          // AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2
          AfficheLCD   (  64,   0,  64, 2, "NTP ......... OK" );
          delay(1000);
     } 
  else 
     {
          FAILED();  Serial.println(F("## Serveur NTP (Real Time) : OFF !"));
          // AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2
          AfficheLCD   (  64,   0,  64, 2, "NTP ....... Down" );
          delay(1000);
     }
  
// Demmarage du serveur WEB
  server = EthernetServer(conf.port);                                                                 // Change le port du serveur
  server.begin();
  OK();            Serial.print(F("## Serveur WEB START port : "));    Serial.print(conf.port);    Serial.println(F("  ...... OK !"));
  Serial.println(); Serial.println(); Serial.println();


// Start Serial Commande Line (CmdLine)
  Serial.println(F("## Telnet Commande Line : OK !"));
  Serial.println(F("     Avec MobaXtern taper cli off pour eviter les doubles caracteres"));
  Serial.println(F("     Putty ou Kitty configurer en Telnet port 23")); 
  Serial.println(F("     Si besoin : Dans PUTTY le menu Telnet decocher"));
  Serial.println(F("     Return key sends Telnet New Line instead of ^M"));    
  Serial.println(F("## Serial Commande Line (CmdLine) START : OK !"));
  Serial.println(F("     Putty ou Kitty configurer en serial : Flow control selectionner None"));   
  Serial.println();
  Serial.println(F("     Taper help pour voir les commandes disponibles"));
  Serial.println(F("     Taper print pour voir la configuration reseau"));
  Serial.println(F("\033[1;32;40m## -= IoToS =- System OK : Prise IP --> Start Loop()  \033[0;39;49m")); 
  Serial.println();  Serial.println();  Serial.println();  Serial.println();
  if ( conf.login_cmdTelnetSwitch == 1 ) 
     { Serial.print  (F("## Activer ou desactiver Login CmdLine ou Telnet - Etat : "));                Serial.println(conf.login_cmdTelnetSwitch == 0 ? "OFF" : "ON");   
       Serial.println(F("     Entrer le code de connexion entrer la commande : login <motDePasse>"));
       Serial.println(F("     pour acceder a la ligne de commande"));
       Serial.print  (F("     Le mot de passe actuel de l'acces au Telnet est : "));                  Serial.println(conf.telnetPassword);  
       previousMillisTelnet = millis();
       nbrEssaiLoginTelnet = 5; 
       Serial.println();    
     }
  cmdLine.begin(commands, countof(commands));

  digitalWrite(LED_BUILTIN, HIGH);                                                                       // LED de l'Arduino UNO R4 -->  0 : ON  // 1 : OFF

  // AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2 
  //AfficheLCD   (  64,   0,  64, 2, "IP:" );
  //AfficheLCD(   R,   V,   B, L, "|0           15|" )  // L : Ligne 1 ou 2
  AfficheLCD  (  64,   0,  64, 2, "                " );
  IPAddress ip = Ethernet.localIP();
  lcd.setCursor(0, 1);  
  lcd.print( IPAddress(ip) );
  delay(3000);
}
//
//    ██╗  ██╗ ███████╗ ██████   ███    ██╗ ███████╗ ██╗               ██╗          ████████╗           ███████╗
//    ██║ ██╔╝ ██═════╝ ██   ██╗ ████   ██║ ██╔════╝ ██║               ██║  ██████  ╚══██╔══╝  ██████   ██╔════╝
//    █████╔╝  █████╗   ██████╔╝ ██║██  ██║ █████╗   ██║               ██║ ██    ██╗   ██║    ██    ██╗ ███████╗
//    ██╔═██   ██═══╝   ██╔══██╗ ██║ ██ ██║ ██╔══╝   ██║               ██║ ██    ██║   ██║    ██    ██║ ╚════██║
//    ██║  ██╗ ███████╗ ██║  ██║ ██║  ████║ ███████╗ ███████╗          ██║  ██████╔╝   ██║     ██████╔╝ ███████║
//    ╚═╝  ╚═╝ ╚══════╝ ╚═╝  ╚═╝ ╚═╝  ╚═══╝ ╚══════╝ ╚══════╝          ╚═╝   ╚════╝    ╚═╝      ╚════╝  ╚══════╝
//

/***********************************************************************************************************************************************************/
//#####   ----   Programme Principal (loop)        
/***********************************************************************************************************************************************************/
void loop(){
//#####  ----->  Update cmdLine library                                                                   // ---> Execute Librairie CmdLineTelnet_UNOR4.h
  cmdLine.update();
  clientTelnet = serverTelnet.available();                                                                // mise à jour du client global
  cmdLine.updateTelnet(clientTelnet);                                                                     //cmdLineTelnet.update();  // version cmdLine menu autocompletion
  cmdLine.setEcho(cliEcho);                                                                               // cmdLine.setEcho(false);   // MobaXterm — évite le doublement des caractères // cmdLine.setEcho(true);    // PuTTY Telnet — remet l'écho normal


//#####  ----->  Serveur WEB                                                                              // ---> Execute Fichier ServeurWEB.h
if ( conf.SrvWEBswitch == 1 ) {
      EthernetClient client = server.available();                                                         // écouter les clients entrants (Create a client connection)
      ServeurWEB(client);
  } // Fin Ethernet ON


//#####  ----->  Serveur FTP                                                                              // ---> Execute Librairie FtpServer.h
if ( microSD == 1 && conf.SrvFTPswitch == 1 ) {
     etatFTP = ftpSrv.handleFTP();                                                                        // appeler handleFTP() en boucle est obligatoire !!
     // etatFTP = 2 pas connecte -- 3 4 5 109 en cours connexion -- 5 connecte -- 77 copie en cours
     // Serial.print("etatFTP : ");  Serial.println(etatFTP);
     //server.handleClient();
} // Fin FTP ON

//#####  ----->  Banner 1ere Connexion : Telnet                                                           // Fonction dans utils.h
PremiereConnexionTelnet();

//#####  ----->  Banner 1ere Connexion : Serial                                                           // Fonction dans utils.h
PremiereConnexionSerial();
//#####  ----->  Partie Gestion Alarme

//###############################################################################################################################


//###############################################################################################################################
//#####  ----->  Programme SYSTEM PRISE IP
// La gestion de la LED 
//  --> Dans le serveur WEB
//  --> Dans le Shell led on / led off
//  Appel au Datalogger
//###############################################################################################################################
                     // AfficheLCD(   R,   V,   B,  L, "|0           15|" )  // L : Ligne 1 ou 2 
if (conf.led == 1)   AfficheLCD   (   0,   64,  0,  2, " LED ON " );
else                 AfficheLCD   (  64,    0,  0,  2, " LED OFF" );


//------------------------------------------------------------------------------------------------------------------------------------------------------------------
//#####  ----->  Watchdog


} //Fin loop

/*
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  Mini Documentation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Arduino UNO R4 Minima
════════════════════════════════════════════════════════════════════════════════════════════════════════
 ARDUINO UNO R4 MINIMA — TABLEAU COMPLET DES BROCHES
 MCU : Renesas RA4M1 — Cortex-M4 48 MHz — 5V — 256kB Flash / 32kB SRAM / 8kB EEPROM
════════════════════════════════════════════════════════════════════════════════════════════════════════

 ALIMENTATION
 ┌──────────┬───────────┬───────────────┬─────────────────────────────────────────────────┐
 │ Broche   │ Tension   │ Courant max   │ Remarque                                        │
 ├──────────┼───────────┼───────────────┼─────────────────────────────────────────────────┤
 │ VIN      │ 6–24 V    │ —             │ Entrée alim. externe → régulateur buck → 5V     │
 │ 5V       │ 5 V       │ 1.2 A         │ Sortie régulée (depuis VIN ou USB)              │
 │ 3.3V     │ 3.3 V     │ 50–100 mA     │ Généré par le RA4M1 — NE PAS surcharger         │
 │ GND      │ 0 V       │ —             │ Masse                                           │
 │ RESET    │ —         │ —             │ Remise à zéro MCU (actif LOW)                   │
 └──────────┴───────────┴───────────────┴─────────────────────────────────────────────────┘

 BROCHES NUMÉRIQUES D0–D13
 Tension : 5V  |  Courant max par broche : 8 mA  |  Courant total : 60 mA
 ┌─────────┬───────┬───────┬───────────────────────────────┬──────────────────────────────────────┐
 │ Broche  │ IRQ   │ PWM   │ Fonction(s) alternative(s)    │ Remarque                             │
 ├─────────┼───────┼───────┼───────────────────────────────┼──────────────────────────────────────┤
 │ D0      │ OUI   │ NON   │ UART RX (Serial1)             │ Partagé avec Serial1                 │
 │ D1      │ OUI   │ NON   │ UART TX (Serial1)             │ Partagé avec Serial1                 │
 │ D2      │ OUI   │ NON   │ Interruption externe 0        │ Recommandé SoftwareSerial RX         │
 │ D3      │ OUI   │ OUI   │ Interruption externe 1 / PWM  │ Recommandé SoftwareSerial RX         │
 │ D4      │ NON   │ NON   │ CAN TX                        │ PAS d'IRQ externe                    │
 │ D5      │ NON   │ OUI   │ CAN RX / PWM                  │ PAS d'IRQ externe                    │
 │ D6      │ NON   │ OUI   │ PWM                           │ PAS d'IRQ externe                    │
 │ D7      │ NON   │ NON   │ GPIO uniquement               │ PAS d'IRQ externe                    │
 │ D8      │ OUI   │ NON   │ GPIO / IRQ                    │ Bon choix SoftwareSerial RX          │
 │ D9      │ NON   │ OUI   │ PWM                           │ PAS d'IRQ externe                    │
 │ D10     │ NON   │ OUI   │ SPI SS / PWM                  │ PAS d'IRQ externe                    │
 │ D11     │ NON   │ OUI   │ SPI MOSI / PWM                │ PAS d'IRQ externe                    │
 │ D12     │ OUI   │ NON   │ SPI MISO / IRQ                │ Attention si shield SPI actif        │
 │ D13     │ OUI   │ NON   │ SPI SCK / LED_BUILTIN / IRQ   │ LED intégrée allumée si HIGH         │
 └─────────┴───────┴───────┴───────────────────────────────┴──────────────────────────────────────┘

 BROCHES ANALOGIQUES A0–A5
 Résolution ADC : jusqu'à 14 bits  |  Tension référence par défaut : 5V
 ┌─────────┬──────┬───────┬───────┬───────┬──────────────────────────┬──────────────────────────────┐
 │ Broche  │ N°   │ IRQ   │ ADC   │ DAC   │ Fonction(s) alternative  │ Remarque                     │
 ├─────────┼──────┼───────┼───────┼───────┼──────────────────────────┼──────────────────────────────┤
 │ A0      │ D14  │ NON   │ OUI   │ OUI   │ DAC 12 bits              │ Seul pin avec DAC            │
 │ A1      │ D15  │ OUI   │ OUI   │ NON   │ ADC / IRQ                │ — SoftwareSerial RX          │
 │ A2      │ D16  │ OUI   │ OUI   │ NON   │ ADC / IRQ                │ — SoftwareSerial RX          │
 │ A3      │ D17  │ OUI   │ OUI   │ NON   │ ADC / IRQ / OPAMP+       │ Entrée + OPAMP interne       │
 │ A4      │ D18  │ OUI   │ OUI   │ NON   │ I2C SDA / ADC / IRQ      │ Partagé Wire — exclu SerSoft │
 │ A5      │ D19  │ OUI   │ OUI   │ NON   │ I2C SCL / ADC / IRQ      │ Partagé Wire — exclu SerSoft │
 └─────────┴──────┴───────┴───────┴───────┴──────────────────────────┴──────────────────────────────┘

 CONNECTEUR ICSP — SPI hardware (header 6 broches)
 ┌──────────┬──────────┬─────────────────────────────────────────────────────────────────┐
 │ Broche   │ Signal   │ Remarque                                                        │
 ├──────────┼──────────┼─────────────────────────────────────────────────────────────────┤
 │ ICSP-1   │ MISO     │ = D12 (partagé)                                                 │
 │ ICSP-2   │ +5V      │ Alimentation                                                    │
 │ ICSP-3   │ SCK      │ = D13 (partagé)                                                 │
 │ ICSP-4   │ MOSI     │ = D11 (partagé)                                                 │
 │ ICSP-5   │ RESET    │ Remise à zéro                                                   │
 │ ICSP-6   │ GND      │ Masse                                                           │
 └──────────┴──────────┴─────────────────────────────────────────────────────────────────┘

 CONNECTEUR SWD/JTAG — debug (header 5 broches)
 ┌──────────┬──────────┬─────────────────────────────────────────────────────────────────┐
 │ Broche   │ Signal   │ Remarque                                                        │
 ├──────────┼──────────┼─────────────────────────────────────────────────────────────────┤
 │ SWD-1    │ SWDIO    │ Données debug SWD                                               │
 │ SWD-2    │ GND      │ Masse                                                           │
 │ SWD-3    │ SWDCLK   │ Horloge debug SWD                                               │
 │ SWD-4    │ SWO      │ Trace (optionnel)                                               │
 │ SWD-5    │ +5V      │ Alimentation                                                    │
 └──────────┴──────────┴─────────────────────────────────────────────────────────────────┘

 BUS DE COMMUNICATION
 ┌──────────┬──────────────────────────────────────┬───────────────┬────────────────┬───────────────────────────────┐
 │ Bus      │ Broches                              │ Vitesse max   │ Bibliothèque   │ Remarque                      │
 ├──────────┼──────────────────────────────────────┼───────────────┼────────────────┼───────────────────────────────┤
 │ UART USB │ USB-C                                │ —             │ Serial         │ Moniteur série IDE            │
 │ UART1    │ D0 (RX)  D1 (TX)                     │ —             │ Serial1        │ Seul UART hardware externe    │
 │ I2C      │ A4 (SDA)  A5 (SCL)                   │ 400 kHz       │ Wire           │ Exclut SoftwareSerial A4/A5   │
 │ SPI      │ D10 (SS)  D11 (MOSI)  D12 (MISO)     │ —             │ SPI            │ Partagé avec ICSP             │
 │          │ D13 (SCK)                            │               │                │                               │
 │ CAN      │ D4 (TX)  D5 (RX)                     │ 1 Mbit/s      │ Arduino_CAN    │ Transceiver externe requis    │
 └──────────┴──────────────────────────────────────┴───────────────┴────────────────┴───────────────────────────────┘

 FONCTIONS SPÉCIALES RA4M1
 ┌─────────────┬────────────────┬──────────────────────────────────────────────────────────┐
 │ Fonction    │ Broche(s)      │ Remarque                                                 │
 ├─────────────┼────────────────┼──────────────────────────────────────────────────────────┤
 │ DAC         │ A0             │ 12 bits — analogWrite() ou DAC natif                     │
 │ OPAMP+      │ A3             │ Entrée non-inverseuse OPAMP interne                      │
 │ OPAMP−      │ —              │ Entrée inverseuse (broche interne non exposée)           │
 │ OPAMP out   │ —              │ Sortie OPAMP (broche interne non exposée)                │
 │ RTC         │ —              │ Temps réel interne, pas de broche externe dédiée         │
 │ BOOT        │ pad BOOT       │ Force le mode ROM bootloader (récupération carte)        │
 └─────────────┴────────────────┴──────────────────────────────────────────────────────────┘

 RÉCAPITULATIF attachInterrupt()
 ┌──────────────────────────────────────────────────────────────────────────────────────────┐
 │ OUI : D0  D1  D2  D3  D8  D12  D13  A1(D15)  A2(D16)  A3(D17)  A4(D18)  A5(D19)          │
 │ NON : D4  D5  D6  D7  D9  D10  D11  A0(D14)                                              │
 └──────────────────────────────────────────────────────────────────────────────────────────┘

════════════════════════════════════════════════════════════════════════════════════════════════════════

Broche   attachInterrupt()   Disponible   Remarque
──────────────────────────────────────────────────────────────────────
D0           OUI               ATTENTION   Partagé avec Serial1 RX
D1           OUI               ATTENTION   Partagé avec Serial1 TX
D2           OUI               OUI         Recommandé — config Seeed officielle
D3           OUI               OUI         Recommandé
D4           NON               NON         CAN TX — pas d'IRQ externe
D5           NON               NON         CAN RX — pas d'IRQ externe
D6           NON               NON         Pas dans la table pinsmux
D7           NON               NON         Pas dans la table pinsmux
D8           OUI               OUI         Recommandé
D9           NON               NON         Pas d'IRQ externe
D10          NON               NON         Pas d'IRQ externe (SS SPI)
D11          NON               NON         Pas d'IRQ externe (MOSI SPI)
D12          OUI               ATTENTION   MISO SPI
D13          OUI               ATTENTION   LED_BUILTIN
A0 (D14)     NON               NON         Pas d'IRQ externe
A1 (D15)     OUI               OUI
A2 (D16)     OUI               OUI
A3 (D17)     OUI               OUI
A4 (D18)     OUI               ATTENTION   SDA (I2C / Wire)
A5 (D19)     OUI               ATTENTION   SCL (I2C / Wire)
──────────────────────────────────────────────────────────────────────
RAPPEL : seule la broche RX (1er paramètre) doit être interruptible.
La broche TX (2ème paramètre) est une sortie GPIO, pas de contrainte IRQ.



*********************************************************************************************************************
*     Acces a la ligne de commande cmd     -->    Configuration CmdLine en Serial, Telnet
*********************************************************************************************************************
** Connexion : Serial Moniteur 
*    Detection du PORT COM : Programme : Serial Port Notifier --> https://sourceforge.net/projects/serial-port-monitor/
*
*    Serial avec IDE Arduino : Serial Moniteur 
*      Outils --> PORT (voir dans gestionnaire d'ordinateur pour connaitre le PORT COM utilise par l'Arduino ou l'Arduino UNO R4)
*      Serial dans l'IDE d'Arduino : Outils --> Moniteur serie
*        En bas menu de serial     : Selectionner Les deux NL et CR
*        Selectionner la vitesse   : 115200 
*    Au demarrage de l'Arduino UNO R4 tapez stop pour arreter les tentatives de connexions au Ethernet et obtenir la ligne de commande
*
*    Serial dans Putty ou Kitty    : selectionner le bon PORT COM et Speed : 115200 
*        Dans le menu : connexion --> Serial : Flow control selectionner --> None
*
** Connexion : Telnet avec Putty / Kitty (il faut d'abord que l'IP soit deja configure en Serial ou en portail WEB captif en Ethernet (selon la version du MicroOS SOCLE )
*        Dans Host Name : entrer l'IP 
*        Cocher Telnet (Post 23) puis OPEN        
*        Dans le menu : connexion --> Telnet : decocher : Return key sends Telnet New Line instead of ^M                          (sinon le enter est decale)
*        Attention dans certain terminal il peut apparaitre deux caracteres "pprriinntt" il faut empecher l'echo
*
*********************************************************************************************************************
* Acces FTP
********************************************************************************************************************* 
* FTP -->  Configuration FileZilla pour le Serveur FTP
*  Dans General : entrer l'IP 
*    Type d'authentification : Compte
*       Identifiant (c'est le nom de la connexion
*       Mot de passe
*       Compte : c'est le Login   
*  Cliquer sur Fichier --> Gestion de sites --> Parametre de Transfert --> Limiter le nombre de connexion a 1
*  App Android : AndFTP
*  App iPhone  : 
*********************************************************************************************************************
* Fonctions Disponibles en ligne de commande CLI CMD Line -- Serial - Telnet - Bluetooth (option ESP32)
*********************************************************************************************************************


> help
###########################################################################
###  ---   Prise IP   ---                      Serial Telnet Connexion  ###
###  Info Status Arduino UNO R4 - Ethernet2               System IoToS  ###
###########################################################################
- General System commands :
    print                      print configuration courante (info)
    name                       Changer le nom du systeme

    LED           on/off       LED ON ou OFF
    WEB           on/off       Serveur WEB ON/OFF
    FTP           on/off       Serveur FTP ON/OFF
    ram                        RAM Disponible
    ping          xx.xx.xx.xx  Exemple : ping 192.168.0.1

- Datalogger commands :
    datalogger    on/off       Activation de l'enregistrement des actions ON/OFF sur la prise IP
    create        <name>       Creation Fichier : create NomFichier.extention avec entete du fichier Excel
    select        <Nom.ext>    NomFichier.Extention pour le datalogger

- SD Fichier commands (Mini MSDOS) :
    dir                        Info Fichier sur le SD
    rename        <OLD name>   <New name>
    del           <name>       Efface Fichier
    type          <name>       Affiche contenu Fichier selectionne.extention
    edit                       Exemple edit texte a enregistrer (limiter a 100 caracteres)
    copie         <name1>      <name2>  Le mame2 est cree avec la copie de name1

- Configuration WEB server commands :
    loginWEB      on/off       enable/disable Login et Password du site WEB
    login-passWEB              changer de Login:Password codé en base 64 (voir : https://www.base64encode.org/)

- Configuration FTP server commands :
    loginFTP                   changer de Login
    passwordFTP                changer de Password

- Configuration IP commands :
    mac           <MAC>        set local MAC address (default: DE:AD:BE:EF:FE:ED)
    dhcp          on/off       enable/disable DHCP
    ip            <IP>         set local IP address (Exemple : ip 192.168.0.66)
    subnet        <IP>         set Masque de sous reseau
    gateway       <IP>         set Passerelle
    port          <0 65535>    set Port WEB (Defaut 80)

- EEPROM access commands:
    reload                     load EEPROM avec la configuration sauvegarde
    defaults                   set default configuration HARD Reset (192.168.0.10)
    save                       save configuration en EEPROM
    reset                      Restart Arduino et load la configuration enregistre en EEPROM
    version                    Version et debug du programme

 Exemple : Pour changer l'IP de l'Arduino : taper commande :
 > ip 192.168.0.2
 puis la commande save et enfin reset pour redemarrer l'arduino dans la nouvelle configuration
>
------------------------------------------------------------------------------------------------------------------------------------
*********************************************************************************************************************
*  Fonctions implementees
********************************************************************************************************************* 
* Hardware : Carte Arduino
* Arduino UNO + Schield Ethernet v1                              : X
* Arduino UNO + Ethernet ESP01 'ESP8266) Port D2 (commande AT)   : X
* Arduino UNO R4 + Ethernet 2                                    : ok
* ESP8266 WeMos D1 R1 (ESP8266) (Ethernet)                       : X
* ESP8266 Shelly 1 v2 (ESP8266) (Ethernet) Prise IP              : X
* ESP8266 Shelly 2    (ESP8266) (Ethernet) RGBW                  : X
* ESP8266 Huacanxing H801 (ESP8266) (Ethernet)                   : X
* ESP32 Wemos D1 R32 (Ethernet bluetooth)                        : X 
*
* System de Fichier
* SD.h   SDCard FAT16 Nom 8.3 caracteres  xxxxxxxxx.yyy          : X
* SDFat  SDcard FAT32 Nom long                                   : ok
* SPIFFS     (ESP 8266 - ESP 32 )                                : X
* LittleFS   (ESP 8266 - ESP 32 )                                : X                                       
*
* Ecran LCD Sparking + menu conf 3 boutons (+) (-) et ok         : X
* Ecran LCD RGB Blacklight (I2C)                                 : X
* Ecran LCD TFT I2C 128x64 GroveSparking                         : X
* Ecran LCD TFT GM12864 59n VER2.0 -----  ST7567S                : ok
* Oled                                                           : 
*
* Menu Rotatif 3 Boutons (+) (-) OK par interruption             : ok
*
* Version Programme : Fonction : Commande de Relais (LED) par page WEB
* Serveur WEB
*  - HTML en programme client.print                              : X
*  - HTML en PROGMEM                                             : X
*  - HTML sur carte Micro SD                                     : ok
*  - HTML sur partition SPIFFS/LittleFS (Wemos D1 R1 ESP8266)    : X
*
*  - Commande une LED avec des boutons WEB dessine en CSS        : ok
*  - Authentification Login Mot de passe (Avec activation)        : ok
*  - Changement de Login Password en Base 64                     : ok             https://www.base64encode.org/ 
*  - Configuration IP par Page WEB                               : ok
*  - Mise a jour des DATA en AJAX                                : ok
*
* Configuration IP par Serial Commande (Commande Line)           : ok             Nouvelle version avec cmdLine.print(xxxx);
* Configuration IP par Telnet Commande (Commande Line)           : ok
* Login CmdLine et Telnet                                        : off
* 
* Serveur NTP  (Horloge Internet)                                : ok
* Serveur FTP  (Fichier sur partition SD                         : ok  
* Datalogger   (Memorisation des DATA sur partition SD)          : ok            En fichier csv Excel 
* DEBUG : Fichier LOG.txt + ping + Info variable                 : off
* Fonction ping (SNMP) Ethernet                                  : ok + netstat + tracert            (ping complet)
* Envoie Mail (SMTP)                                             : off
* Info et scan Ethernet                                          : off
* Watchdog                                                       : off erreur pas de watchdog materiel // version logiciel TickTwo marche pas dans une fonction
* HARD RESET configuration defaut (Bouton PORT D3)              : off    
* OTA Programmation Ethernet (Over The Air)                     : off 
* 
***********************************************************************************************************************************
***********************************************************************************************************************************

> print
###########################################################################
###  ---   Prise IP   ---                      Serial Telnet Connexion  ###
###  Info Status Arduino UNO R4 - Ethernet2               System IoToS  ###
###########################################################################


 Status Service
  - Nom du systeme. . . . . . . . . . . : Arduino_UNO_R4
  - Etat LED                            : OFF
  - Carte Micro SD Partition Fichier. . : ready
  - Datalogger. . . . . . . . . . . . . : OFF
    * Nom Fichier en cours              : datalog.csv
  - Ethernet. . . . . . . . . . . . . . :
    * Test DNS                          : Connexion a Internet OK
  - Serveur FTP . . . . . . . . . . . . : ON
    * Serveur FTP Login                 : arduino
    * Serveur FTP Password              : arduino
  - Serveur WEB . . . . . . . . . . . . : ON
    * Authentification                   : OFF  (Login et Password) du site WEB
    * Login:Password                    : dXNlcjpwYXNz  en Base 64

 Configuration en cours de la connexion Ethernet de l'Arduino UNO R4
  - DHCP. . . . . . . . . . . . . . . . : OFF
  - L'adresse IP. . . . . . . . . . . . : 192.168.0.10
  - Le Masque de sous reseau (subnet) . : 255.255.255.0
  - La Passerelle (gateway) . . . . . . : 192.168.0.253
  - DNS . . . . . . . . . . . . . . . . : 1.1.1.1

 Configuration Reseau en RAM  ( Pour sauver la configuration en EEPROM : taper save )
  - DHCP                                : OFF
  - L'adresse IP. . . . . . . . . . . . : 192.168.0.10
  - Le Masque de sous reseau (subnet) . : 255.255.255.0
  - La Passerelle (gateway) . . . . . . : 192.168.0.253
  - MAC Address . . . . . . . . . . . . : DE:AD:BE:EF:FE:B2
  - Serveur WEB : PORT. . . . . . . . . : 80

 Configuration Reseau enregistré en EEPROM  ( Cette configuration n'est valide qu'après un RESET : taper reset )
  - DHCP                                : OFF
  - L'adresse IP. . . . . . . . . . . . : 192.168.0.10
  - Le Masque de sous reseau (subnet) . : 255.255.255.0
  - La Passerelle (gateway) . . . . . . : 192.168.0.253
  - MAC address . . . . . . . . . . . . : DE:AD:BE:EF:FE:B2
  - Serveur WEB : PORT. . . . . . . . . : 80

 Environnement
  - Time : 07:20:42
  - Date : 17/02/2026
  - Mémoire RAM disponible de l'arduino : 22031 byte
> 



Rapport de compilation
Detecting libraries used...
Alternative pour TickTwo.h: [TickTwo@4.4.0]
ResolveLibrary(TickTwo.h)
  -> candidates: [TickTwo@4.4.0]
Alternative pour EEPROM.h: [EEPROM@1.0]
ResolveLibrary(EEPROM.h)
  -> candidates: [EEPROM@1.0]
Alternative pour virtualEEPROM.h: [BlockDevices]
ResolveLibrary(virtualEEPROM.h)
  -> candidates: [BlockDevices]
Alternative pour SPI.h: [SPI]
ResolveLibrary(SPI.h)
  -> candidates: [SPI]
Alternative pour Ethernet.h: [Ethernet@2.0.2]
ResolveLibrary(Ethernet.h)
  -> candidates: [Ethernet@2.0.2]
Alternative pour SdFat.h: [SdFat@2.3.1]
ResolveLibrary(SdFat.h)
  -> candidates: [SdFat@2.3.1]
lternative pour NTPClient.h: [NTPClient@3.1.0]
ResolveLibrary(NTPClient.h)
  -> candidates: [NTPClient@3.1.0]
Alternative pour FtpServer.h: [SimpleFTPServer@3.0.2]
ResolveLibrary(FtpServer.h)
  -> candidates: [SimpleFTPServer@3.0.2]
Alternative pour CmdLineTelnet_UNOR4.h: [CmdLine@1.0.0]
ResolveLibrary(CmdLineTelnet_UNOR4.h)
  -> candidates: [CmdLine@1.0.0]
Alternative pour MemoryFree.h: [Arduino-MemoryFree]
ResolveLibrary(MemoryFree.h)
  -> candidates: [Arduino-MemoryFree]
Alternative pour U8g2lib.h: [U8g2@2.35.30]
ResolveLibrary(U8g2lib.h)
  -> candidates: [U8g2@2.35.30]
Alternative pour Wire.h: [Wire]
ResolveLibrary(Wire.h)
  -> candidates: [Wire]

*/
