diff --git a/platformio.ini b/platformio.ini index d9a1bd1..90ce2e9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,3 +16,4 @@ lib_deps = madhephaestus/ESP32Servo@^0.9.0 br3ttb/PID@^1.2.1 adafruit/RTClib@^1.12.4 + ottowinter/ESPAsyncWebServer-esphome@^1.2.7 diff --git a/src/main.cpp b/src/main.cpp index 4ee621f..5b825c2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,63 +4,81 @@ #include "SD.h" #include "SPI.h" #include "RTClib.h" -#include #include -// #include "pcnt.h" // https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/driver/driver/pcnt.h #include "driver/pcnt.h" #include -#include -#include +#include -//définition du compteur -#define PULSE_COMPTEUR +///////////////////////////// +/* DÉFINITIONS DU COMPTEUR */ +///////////////////////////// +//#define PULSE_COMPTEUR #define PCNT_TEST_UNIT PCNT_UNIT_0 // Il existe 8 compteurs de 0 à 7 -//#define PCNT_H_LIM_VAL 10000 //valeur max du compteur_minuteur -#define PCNT_L_LIM_VAL 0 //valeur mini du compteur -//#define PCNT_THRESH1_VAL 5 -//#define PCNT_THRESH0_VAL -5 -#define PCNT_INPUT_SIG_IO 15 // Pulse Input GPIO -#define PCNT_INPUT_CTRL_IO 2 // Control GPIO HIGH=count up, LOW=count down +#define PCNT_TEST_CHANNEL PCNT_CHANNEL_0 +#define PCNT_INPUT_SIG_IO GPIO_NUM_15 // Pulse Input GPIO +#define PCNT_INPUT_CTRL_IO GPIO_NUM_2 // Control GPIO HIGH=count up, LOW=count down bool sem_compteur; // sémaphore pour le compteur -int16_t pulsations = 0; // variable de compteur -int vitesse = 2400; //vitesse de rotation en tr/min -// int16_t Pulses = 0; // variable de lecture de compteur -byte pulsePin = 13; //broche de l'encodeur +int16_t count = 0; // variable de compteur +float vRotReel; // vitesse réelle mesurée du moteur -//définition du PID -#define PIN_INPUT 26 //entrée physique perso? -#define PIN_OUTPUT 3// sortie physique perso? -double Setpoint, Input, Output; //PID Define Variables we'll be connecting to -double Kp=2, Ki=5, Kd=1; //PID Specify the links and initial tuning parameters -PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); - -//définition du numéro de série de l'appareil +///////////////////////////////// +/*NUMÉRO DE SÉRIE DE L'APPAREIL*/ +///////////////////////////////// int numero_capteur = 0001; -//définition du bouton Wifi -int bouton_wifi = 7; // pin du bouton wifi +/////////////////////////// +/* DÉFINITIONS DE LA RTC */ +/////////////////////////// +RTC_DS3231 rtc; //déclaration de la rtc + +//////////////////////////////// +/* DÉFINITIONS DE LA CARTE SD */ +//////////////////////////////// +unsigned long freq_ecriture = 60000; // durée entre deux écritures sur la carte SD en micro secondes +int fichier = 0; +char horodatage[25]; //création du tableau pour contenir l'horodatage + +////////////////////////////////// +/* DÉFINITIONS DU DRIVER MOTEUR */ +////////////////////////////////// +int vRotVis = 2400; //vitesse de rotation recherchée en tr/min +Servo moteur; //création de l'objet moteur +int minUs = 1000; // intervalle pwm mini +int maxUs = 2000; // intervalle pwm maxi +int pos = 135; // vitesse de départ, 135 donne environ 40Hz +int moteurPin = 4; //pin de contrôle du BEC de l'ESC du moteur +ESP32PWM pwm; // Activation du pwm + +//////////////////////////////// +/* DÉFINITIONS DU BOUTON WIFI */ +//////////////////////////////// +int bouton_wifi = 2; // pin du bouton wifi bool sem_wifi; //sémaphore du minuteur du bouton wifi unsigned long wifi_minuteur = 0; // minuteur pour l'appui long sur le bouton wifi unsigned long compteur_minuteur = 0; // minuteur pour l'appui long sur le bouton wifi -char horodatage[25]; //création du tableau pour contenir l'horodatage bool etat_bouton_wifi; -//définition de la RTC -RTC_DS3231 rtc; //déclaration de la rtc +/////////////////////////////////////// +/* DÉFINITIONS DU POINT D'ACCES WIFI */ +/////////////////////////////////////// +const char *ssid = "IFV-Sporix"; // SSID +const char *password = "12345678"; // PASSWORD, 8 caractères minimum +WiFiServer server(80); // port du serveur -//définition de la carteSD -const int broche_CS = 5; // broche de la carte SD -unsigned long freq_ecriture = 60000; // durée entre deux écritures sur la carte SD en micro secondes - -//définition du driver moteur ESC -const byte pinMoteur = 4; // broche de contrôle du moteur -Servo moteur; //création de l'objet moteur - -// définition du point d'accès Wifi -const char *ssid = "yourAP"; -const char *password = "yourPassword"; -WiFiServer server(80); +/////////////// +/* PAGE HTML */ +/////////////// +String html =" \ + \ + \ +

ESP32 IFV Soft access point

\ +

Web Server

\ + \ +"; +/////////////////////////// +/* FONCTIONS DU COMPTEUR */ +/////////////////////////// void start_compteur() { @@ -69,7 +87,7 @@ void start_compteur() { Serial.println("Initialisation du compteur"); pcnt_config_t pcnt_config = { - pulsePin, // Pulse input gpio_num, if you want to use gpio16, pulse_gpio_num = 16, a negative value will be ignored + PCNT_INPUT_SIG_IO, // Pulse input gpio_num, if you want to use gpio16, pulse_gpio_num = 16, a negative value will be ignored PCNT_PIN_NOT_USED, // Control signal input gpio_num, a negative value will be ignored PCNT_MODE_KEEP, // PCNT low control mode PCNT_MODE_KEEP, // PCNT high control mode @@ -78,78 +96,270 @@ void start_compteur() { //PCNT_H_LIM_VAL, // Maximum counter value //PCNT_L_LIM_VAL, // Minimum counter value PCNT_TEST_UNIT, // PCNT unit number - PCNT_CHANNEL_0, // the PCNT channel + PCNT_TEST_CHANNEL, // the PCNT channel }; if(pcnt_unit_config(&pcnt_config) == ESP_OK) //init unit Serial.println("Config Unit_0 = ESP_OK"); - /*Configure input filter value*/ - pcnt_set_filter_value(PCNT_TEST_UNIT, 100); - /*Enable input filter*/ - pcnt_filter_enable(PCNT_TEST_UNIT); - /*Set value for watch point thresh1*/ - //pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_1, PCNT_THRESH1_VAL); - /*Enable watch point event of thresh1*/ - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_1); - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_1); - /*Set value for watch point thresh0*/ - //pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_0, PCNT_THRESH0_VAL); - /*Enable watch point event of thresh0*/ - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_0); - //pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_THRES_0); - /*Enable watch point event of h_lim*/ - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_H_LIM); - //pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_H_LIM); - /*Enable watch point event of l_lim*/ - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_L_LIM); - //pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_L_LIM); - /*Enable watch point event of zero*/ - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_ZERO); - //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_ZERO); + pcnt_set_filter_value(PCNT_TEST_UNIT, 100); /*Configure input filter value*/ + pcnt_filter_enable(PCNT_TEST_UNIT); /*Enable input filter*/ + pcnt_counter_pause(PCNT_TEST_UNIT); + pcnt_counter_clear(PCNT_TEST_UNIT); /*Reset counter value*/ + pcnt_counter_resume(PCNT_TEST_UNIT); /*Resume counting*/ +} + +void stop_compteur() { /*Pause counter*/ - //pcnt_counter_pause(PCNT_TEST_UNIT); + pcnt_counter_pause(PCNT_TEST_UNIT); /*Reset counter value*/ pcnt_counter_clear(PCNT_TEST_UNIT); - /*Register ISR handler - à activer par défaut? */ - //pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, NULL); - /*Enable interrupt for PCNT unit*/ - //pcnt_intr_enable(PCNT_TEST_UNIT); - /*Resume counting*/ - //pcnt_counter_resume(PCNT_TEST_UNIT); - pcnt_get_counter_value(PCNT_TEST_UNIT, &pulsations); } -void pid () { - Input = analogRead(PIN_INPUT); - myPID.Compute(); - analogWrite(PIN_OUTPUT, Output); + +void compte_tour() { + if ( sem_compteur == false ) { + compteur_minuteur = millis(); + sem_compteur = true; + } + if ( sem_compteur == true && compteur_minuteur - millis() > freq_ecriture ){ + /// vitesse = readPcntCounter_0() / 2; //vitesse en tours par min + /// scribe_sd (); + /// pcnt_counter_clear(); + compteur_minuteur = millis(); + sem_compteur = false; + } } -void pidsetup() { - //initialize the variables we're linked to - Input = analogRead(PIN_INPUT); - Setpoint = vitesse; - //turn the PID on - myPID.SetMode(AUTOMATIC); + +///////////////////////// +/* FONCTIONS DU MOTEUR */ +///////////////////////// + +void start_moteur() { + ESP32PWM::allocateTimer(0); + moteur.setPeriodHertz(50); + moteur.attach(moteurPin, minUs, maxUs); + delay(15); + moteur.write(0); // envoi du 0 à l'ESC pour initialisation + delay(1500); // délai permettant au variateur de détecter le zero + moteur.write(pos); // vitesse initiale +} + +void gaz_moteur() { + if (vRotVis > vRotReel) { + pos ++; + } + if (vRotReel > vRotVis) { + pos --; + } + moteur.write(pos); +} + + +void stop_moteur() { + moteur.write(0); + delay(1000); + moteur.detach(); +} + +///////////////////////// +/// FONCTIONS SD CARD /// +///////////////////////// + +void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ + Serial.printf("Listing directory: %s\n", dirname); + + File root = fs.open(dirname); + if(!root){ + Serial.println("Failed to open directory"); + return; + } + if(!root.isDirectory()){ + Serial.println("Not a directory"); + return; + } + + File file = root.openNextFile(); + while(file){ + if(file.isDirectory()){ + Serial.print(" DIR : "); + Serial.println(file.name()); + if(levels){ + listDir(fs, file.name(), levels -1); + } + } else { + Serial.print(" FILE: "); + Serial.print(file.name()); + Serial.print(" SIZE: "); + Serial.println(file.size()); + } + file = root.openNextFile(); + } +} + +void createDir(fs::FS &fs, const char * path){ + Serial.printf("Creating Dir: %s\n", path); + if(fs.mkdir(path)){ + Serial.println("Dir created"); + } else { + Serial.println("mkdir failed"); + } +} + +void removeDir(fs::FS &fs, const char * path){ + Serial.printf("Removing Dir: %s\n", path); + if(fs.rmdir(path)){ + Serial.println("Dir removed"); + } else { + Serial.println("rmdir failed"); + } +} + +void readFile(fs::FS &fs, const char * path){ + Serial.printf("Reading file: %s\n", path); + + File file = fs.open(path); + if(!file){ + Serial.println("Failed to open file for reading"); + return; + } + + Serial.print("Read from file: "); + while(file.available()){ + Serial.write(file.read()); + } + file.close(); +} + +void writeFile(fs::FS &fs, const char * path, const char * message){ + Serial.printf("Writing file: %s\n", path); + + File file = fs.open(path, FILE_WRITE); + if(!file){ + Serial.println("Failed to open file for writing"); + return; + } + if(file.print(message)){ + Serial.println("File written"); + } else { + Serial.println("Write failed"); + } + file.close(); +} + +void appendFile(fs::FS &fs, const char * path, const char * message){ + Serial.printf("Appending to file: %s\n", path); + + File file = fs.open(path, FILE_APPEND); + if(!file){ + Serial.println("Failed to open file for appending"); + return; + } + if(file.print(message)){ + Serial.println("Message appended"); + } else { + Serial.println("Append failed"); + } + file.close(); +} + +void renameFile(fs::FS &fs, const char * path1, const char * path2){ + Serial.printf("Renaming file %s to %s\n", path1, path2); + if (fs.rename(path1, path2)) { + Serial.println("File renamed"); + } else { + Serial.println("Rename failed"); + } +} + +void deleteFile(fs::FS &fs, const char * path){ + Serial.printf("Deleting file: %s\n", path); + if(fs.remove(path)){ + Serial.println("File deleted"); + } else { + Serial.println("Delete failed"); + } +} + +void testFileIO(fs::FS &fs, const char * path){ + File file = fs.open(path); + static uint8_t buf[512]; + size_t len = 0; + uint32_t start = millis(); + uint32_t end = start; + if(file){ + len = file.size(); + size_t flen = len; + start = millis(); + while(len){ + size_t toRead = len; + if(toRead > 512){ + toRead = 512; + } + file.read(buf, toRead); + len -= toRead; + } + end = millis() - start; + Serial.printf("%u bytes read for %u ms\n", flen, end); + file.close(); + } else { + Serial.println("Failed to open file for reading"); + } + + + file = fs.open(path, FILE_WRITE); + if(!file){ + Serial.println("Failed to open file for writing"); + return; + } + + size_t i; + start = millis(); + for(i=0; i<2048; i++){ + file.write(buf, 512); + } + end = millis() - start; + Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); + file.close(); } void sd_init(){ - if (!SD.begin(broche_CS)) { - Serial.println("Carte SD introuvable , reboot"); - delay(1000); - ESP.restart(); + if(!SD.begin()){ + Serial.println("Card Mount Failed"); + return; } - else{ - Serial.println("Carte SD détectée"); // ligne de debug à commenter en prod - //writeFile(SD, );// ajouter une fonction : "écrire fichier d'identité et créer fichier data sur la carte SD + uint8_t cardType = SD.cardType(); + + if(cardType == CARD_NONE){ + Serial.println("No SD card attached"); + return; } + + Serial.print("SD Card Type: "); + if(cardType == CARD_MMC){ + Serial.println("MMC"); + } else if(cardType == CARD_SD){ + Serial.println("SDSC"); + } else if(cardType == CARD_SDHC){ + Serial.println("SDHC"); + } else { + Serial.println("UNKNOWN"); + } + + uint64_t cardSize = SD.cardSize() / (1024 * 1024); + Serial.printf("SD Card Size: %lluMB\n", cardSize); + + // créer un dossier avec un numéro incrémental + } -void start_moteur() { - moteur.attach(pinMoteur); - moteur.writeMicroseconds(1500); // envoi d'un 'neutre' au variateur - delay(1000); - moteur.writeMicroseconds(2000); //valeur de départ pour atteindre 2400tr/min +void scribe_sd (){ + fichier ; + writeFile(SD, "data", horodatage); } +///////////////////// +/// FONCTIONS RTC /// +///////////////////// + void rtc_init() { if (! rtc.begin()) { Serial.println("RTC introuvable !"); // ligne de debug à commenter en prod @@ -171,12 +381,9 @@ void rtc_init() { } -void stop_compteur() { - /*Pause counter*/ - pcnt_counter_pause(PCNT_TEST_UNIT); - /*Reset counter value*/ - pcnt_counter_clear(PCNT_TEST_UNIT); -} +////////////////////// +/// FONCTIONS WIFI /// +////////////////////// void start_wifiAP() { pinMode(LED_BUILTIN, OUTPUT); @@ -242,43 +449,9 @@ void wifi_AP() { ESP.restart(); } -void stop_moteur() { - moteur.writeMicroseconds(1500); - delay(1000); - moteur.detach(); -} +/////FONCTIONS COMMUNES////// -void compte_tour() { - if ( sem_compteur == false ) { - compteur_minuteur = millis(); - sem_compteur = true; - } - if ( sem_compteur == true && compteur_minuteur - millis() > freq_ecriture ){ - /// vitesse = readPcntCounter_0() / 2; //vitesse en tours par min - /// scribe_sd (); - /// pcnt_counter_clear(); - compteur_minuteur = millis(); - sem_compteur = false; - } -} - -void scribe_sd (fs::FS &fs, const char * path, const char * horodatage) { - Serial.printf("Ecriture dans le fichier: %s\n", path); - - File file = fs.open(path, FILE_APPEND); - if (!file) { - Serial.println("Echec d'ouverture du fichier"); - return; - } - if (file.print(horodatage)) { - Serial.println("Fichier modifié avec succes."); - } else { - Serial.println("Echec de la modification du fichier."); - } - file.close(); -} - -void vigie () { +void vigie_Wifi () { etat_bouton_wifi = digitalRead(bouton_wifi); if ( etat_bouton_wifi == HIGH && sem_wifi == false ) { sem_wifi = true; @@ -294,28 +467,26 @@ void vigie () { void setup() { // serial just for feedback - Serial.begin(115200); + Serial.begin(9600); + // RTC + rtc_init(); + // lecteur de carte SD + sd_init (); // bouton wifi pinMode(bouton_wifi, INPUT); sem_wifi = false; // initialisation du sémaphore // moteur - moteur.attach(pinMoteur); start_moteur(); // compteur de pulsations sem_compteur = false; // initialisation du sémaphore - pinMode(pulsePin,INPUT_PULLUP); + //pinMode(pulsePin,INPUT_PULLUP); start_compteur(); - // lecteur de carte SD - sd_init (); - // RTC - rtc_init(); - //PID - pidsetup(); } void loop (){ - vigie(); - pid(); + vigie_Wifi(); compte_tour(); + gaz_moteur(); + scribe_sd(); delay(10000); }