![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Shared by Polytech Marseille to contribute to the improvement of the mbed community !
Dependencies: Adafruit_SGP30_mbed mbed GSM X_NUCLEO_IKS01A2 max31865 GroveGPS SDFileSystem DFPlayerMini BME280 DS1820
Revision 3:cb77ea3370e8, committed 2019-04-30
- Comitter:
- ayoubzahir
- Date:
- Tue Apr 30 15:00:03 2019 +0000
- Parent:
- 2:6d26817a1503
- Commit message:
- This Program is shared by PolytechMarseille_MT to contribute to the improvement of the mbed community.; Have fun !
Changed in this revision
diff -r 6d26817a1503 -r cb77ea3370e8 define_myIO.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/define_myIO.h Tue Apr 30 15:00:03 2019 +0000 @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////// +// AMU - Aix-Marseille Université +// Polytech Marseille - Microelectronique & Telecommunications (MT) +// Projet MT5A "STM32 In the Sky - HAB", 2018-2019 +// Enseignants : C.Dufaza & H. Aziza +// Etudiants : ... +///////////////////////////////////////////////////////////////////////// +// Version avril 2019, C.Dufaza + +///////////////////////////////////////////////////////////////////////// +// Assignation des entrées/sorties des différents modules + +// Autres +#define IO_BUZZER PB_3 +#define IO_UV PC_2 +#define IO_PHOTORES PC_3 +#define IO_VBATT PB_0 + +// Carte SD +#define IO_SD_MOSI PB_15 // SPI 2 +#define IO_SD_MISO PB_14 +#define IO_SD_SCK PB_13 +#define IO_SD_CS PB_2 + +// Thermomètre PT100 (RTD) MAX31865 +#define IO_PT100_MOSI PB_15 // SPI 2 +#define IO_PT100_MISO PB_14 +#define IO_PT100_SCK PB_13 +#define IO_PT100_CS PB_1 + +// Lecteur MP3 DFPlayer +#define IO_MP3_TX PB_6 // UART 1 +#define IO_MP3_RX PA_10 + +// DS18 thermomètre +#define IO_DS18 PC_6 + +// Shield XNUCLEO +#define IO_XNUC_SDA PB_9 // I2C 1 +#define IO_XNUC_SCL PB_8 + +// Triple capteur Bosch BME280 (hum, temp, press) +#define IO_BOSCH_SDA PB_9 // I2C 1 +#define IO_BOSCH_SCL PB_8 + +// Capteur eCO2 TVOC Gas sensor +#define IO_CO2_SDA PB_9 // I2C 1 +#define IO_CO2_SCL PB_8 + +// Ozone O3 +#define IO_O3_MOSI PB_15 // SPI 2 +#define IO_O3_MISO PB_14 +#define IO_O3_SCK PB_13 +#define IO_O3_CS PB_12 + +// GPS +#define IO_GPS_TX PC_1 // LPUART +#define IO_GPS_RX PC_0 + +// GSM/GPRS/2G+/téléphone +#define IO_GSM_TX PA_0 // UART 4 +#define IO_GSM_RX PA_1 +#define IO_GSM_PWR PC_7 +#define IO_GSM_NET PA_8 +#define IO_GSM_STAT PA_9 +#define IO_GSM_RST PA_7 + +// LoRa +#define IO_LORA_TX PC_12 // UART 5 +#define IO_LORA_RX PD_2 +
diff -r 6d26817a1503 -r cb77ea3370e8 define_myMODULES.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/define_myMODULES.h Tue Apr 30 15:00:03 2019 +0000 @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////// +// AMU - Aix-Marseille Université +// Polytech Marseille - Microelectronique & Telecommunications (MT) +// Projet MT5A "STM32 In the Sky - HAB", 2018-2019 +// Enseignants : C.Dufaza & H. Aziza +// Etudiants : ... +///////////////////////////////////////////////////////////////////////// +// Version avril 2019, C.Dufaza + +///////////////////////////////////////////////////////////////////////// +// Activation des différents modules de ce code (via directives de compilation) +// Permet de désactiver rapidement la compilation de certaines parties du code +// Commentez les lignes pour désactiver les modules/fonctionnalités : + +#define DEBUG_SERIAL_PC 1 // Debug sur Serial PC COM Port +#define DEBUG_SERIAL_PC_BAUDRATE 115200 +//#define BUZZ_FUNCTION 1 // Buzzer +#define BUZZ_FUNCTION_DURATION 1500 // Nbre de périodes du buzzer +#define BUZZ_FUNCTION_HZ 333 // 1/2 Période de la Hz buzzer (en us) + +#define SD_GPRS_DATA_SIZE 150 // Chaine car pour SD et SMS + +#define HAB_FUNCTION 1 // HAB Ticker +#define TICKER_HAB_TIME 5.0 // HAB Ticker toutes les ... secondes +#define BASE_PRESSURE 1016 // Pression du jour, altitude = 0 + +#define SD_FUNCTION 1 // Carte SD +#define SD_FUNCTION_SDNAME "sd" // Nom de la carte SD +#define SD_FUNCTION_FILENAME "/sd/data.txt" // Nom du fichier sur carte SD +#define SD_FUNCTION_TESTFILENAME "/sd/sdtest.txt" // Nom du fichier sur carte SD + +#define MP3_FUNCTION 1 // Module lecteur MP3 + +#define GSM_FUNCTION 1 // Module GSM +#define TICKER_CHECK_GSM_TIME 60.0 // GSM Ticker toutes les ... secondes +#define GSM_BAUDRATE 9600 +#define GSM_SIM_NUMBER "0758897561" // SIM mobile number +#define GSM_START_ALTITUDE 5000 // Vérification du GSM à partir de 5Km pendant en attérissage + +#define GPRS_FUNCTION 1 // Données mobiles +#define SMS_FUNCTION 1 // SMS de données toute les 10 min +#define TICKER_SMS_DATA_TIME 6000.0 // SMS Ticket toutes les ... secondes + +#define POLYTECH_SERVER "http://147.94.16.160/etudiantmt/index.php?message=" +#define GSM_SEND_NUMBER "+33676040268" // SMS to this phone number +#define GSM_SEND_SMS_HELLO "AMU - Polytech Marseille MT - STM32 In the Sky" // SMS Welcome Message +// +#define GPS_FUNCTION 1 // Module GPS +//#define GPS_DEBUG // Transmission des données serie GPS sur UART +#define GPS_BAUDRATE 9600 +// + +#define XNUCLEO_FUNCTION 1 // Shield capteurs XNUCLEO +#define PT100_FUNCTION 1 // Module PT100 +//#define DS18_FUNCTION // Capteur temperature DS18 +#define UV_FUNCTION 1 // Capteur UV +#define PHOTORES_FUNCTION 1 // Capteur photoresistance +#define BOSCH_FUNCTION 1 // Module triple capteur Bosch +#define CO2_FUNCTION 1 // Module CO2 +#define O3_FUNCTION 1 // Module spi_ozone O3 + +/* +#define LORA_FUNCTION 1 // Carte LoRa, not used !! +#define LORA_FUNCTION_BAUDRATE 9600 +#define LORA_FUNCTION_DATASIZE 50 +*/
diff -r 6d26817a1503 -r cb77ea3370e8 main.cpp --- a/main.cpp Sun Feb 03 20:52:47 2019 +0000 +++ b/main.cpp Tue Apr 30 15:00:03 2019 +0000 @@ -1,1178 +1,1122 @@ -// Projet HAB "ST in the sky", Polytech Marseille -// Programme de la carte mère du HAB, la STM32 Nucleo-L073RZ -// 20 Janvier 2019 - -/* todo : -- resoudre incompatibilité mbed thermomètre DS18 -- utilisation de l'entrée Reset du module GSM -- check si le lecteur MP3 est bien actif -*/ - -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -// Activation des différents modules de ce code (via directives de compilation) -// Permet de désactiver rapidement la compilation de certaines parties du code - -// Commentez les lignes pour désactiver les modules/fonctionnalités : - -#define SD_COMP 1 // Carte SD -#define GSM_COMP 1 // module GSM -#define GPRS_COMP 1 // Données mobiles -#define SMS_COMP 1 // SMS de données toute les 10 min -#define GPS_COMP 1 // module GPS -//#define GPS_DEBUG // Transmission des données serie GPS sur le moniteur série -#define XNUCLEO_COMP 1 // shield capteurs XNUCLEO -#define PT100_COMP 1 // module PT100 -#define CO2_COMP 1 // module CO2 -#define BUZZ_COMP // Buzzer -#define UV_COMP 1 // Capteur UV -#define PHOTORES_COMP 1 // Capteur photoresistance -#define BOSCH_COMP 1 // module triple capteur Bosch -#define MP3_COMP 1 // module lecteur MP3 -//#define LORA_COMP 1 // Carte LoRa -#define O3_COMP 1 // module spi_ozone O3 -//#define DS18_COMP // Capteur temperature DS18 - - -// Assignation des entrées/sorties des différents modules - -// DS18 thermomètre -#define IO_DS18 PC_6 - -// Carte SD -#define IO_SD_MOSI PB_15 // SPI 2 -#define IO_SD_MISO PB_14 -#define IO_SD_SCK PB_13 -#define IO_SD_SS PB_2 - -// Shield XNUCLEO -#define IO_XNUC_SDA PB_9 // I2C 1 -#define IO_XNUC_SCL PB_8 - -// GPS -#define IO_GPS_TX PC_1 // LPUART -#define IO_GPS_RX PC_0 - -// GSM/GPRS/2G+/téléphone -#define IO_GSM_TX PA_0 // UART 4 -#define IO_GSM_RX PA_1 -#define IO_GSM_PWR PC_7 -#define IO_GSM_NET PA_8 -#define IO_GSM_STAT PA_9 -#define IO_GSM_RST PA_7 - -// Thermomètre PT100 (RTD) MAX31865 -#define IO_PT100_MOSI PB_15 // SPI 2 -#define IO_PT100_MISO PB_14 -#define IO_PT100_SCK PB_13 -#define IO_PT100_SS PB_1 - -// Capteur eCO2 TVOC -#define IO_CO2_SDA PB_9 // I2C 1 -#define IO_CO2_SCL PB_8 - -// Triple capteur Bosch (hum, temp, press) -#define IO_BOSCH_SDA PB_9 // I2C 1 -#define IO_BOSCH_SCL PB_8 - -// Lecteur MP3 DFPlayer -#define IO_MP3_TX PB_6 // UART 1 -#define IO_MP3_RX PA_10 - -// LoRa -#define IO_LORA_TX PC_12 // UART 5 -#define IO_LORA_RX PD_2 - -// Ozone O3 -#define IO_O3_MOSI PB_15 // SPI 2 -#define IO_O3_MISO PB_14 -#define IO_O3_SCK PB_13 -#define IO_O3_SS PB_12 - -// Autres -#define IO_BUZZER PB_3 -#define IO_UV PC_2 -#define IO_PHOTORES PC_3 -#define IO_VBATT PB_0 - -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -//////////////////////// Début du code //////////////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -//Autres - -#include <stdio.h> -#include <string> -#include "mbed.h" - -Serial serial_pc(SERIAL_TX, SERIAL_RX, 115200); - -#ifdef LORA_COMP // Debut directive de compilation LoRa -// todo: liaison UART avec carte LoRa + watchdog carte mère -Serial lora_serial(IO_LORA_TX, IO_LORA_RX, 9600); - -char chaine_lora[50]; //chaine contenant la trame des données des capteurs à envoyer -#endif // Fin directive de compilation LoRa - - -#ifdef BUZZ_COMP // Debut directive de compilation buzzer -DigitalOut pin_buzzer(IO_BUZZER,0); -#endif // Fin directive de compilation buzzer - -unsigned int compteur = 0; //compteur du nombre de fois que la recolte de données à été effectuée depuis le démarrage - -// Mesure de la tension de la batterie -float vbatt = 0.0; // Tension de la batterie -AnalogIn pin_vbatt(IO_VBATT); - -//chaine contenant la trame des données des capteurs à stocker sur la crate sd et à envoyer par GPRS -char chaine_data[150]; - -///////////////////////////////////////////////////////////////////////// - -//Tickers - -// Ticker executé toute les 5s pour recolter toute les données des capteurs, -// les enregistrer sur la carte SD et les envoyer en UART à la carte LoRa -Ticker ticker_hab; // Object Ticker -void isr_ticker_hab(); // Routine ISR appellée lors du tick -void f_ticker_hab(); // Fonction utile appellée à la suite du tick -bool flag_ticker_hab = 0; // Flag levé par l'ISR pour appeller la fonction utile - -// Ticker executé toute les 30 s pour vérifier l'etat du module GSM -#ifdef GSM_COMP // Debut directive de compilation module GSM -Ticker ticker_check_gsm; // Object Ticker -void isr_ticker_check_gsm(); // Routine ISR appellée lors du tick -void f_ticker_check_gsm(); // Fonction utile appellée à la suite du tick -bool flag_ticker_check_gsm = 0; // Flag levé par l'ISR pour appeller la fonction utile -#endif // Fin directive de compilation module GSM - -// Ticker executé toute les 10 min pour vérifier l'etat du module GSM -#ifdef SMS_COMP // Debut directive de compilation SMS de données toutes les 10 min -Ticker ticker_sms_chaine; // Object Ticker -void isr_ticker_sms_chaine(); // Routine ISR appellée lors du tick -void f_ticker_sms_chaine(); // Fonction utile appellée à la suite du tick -bool flag_ticker_sms_chaine = 0; // Flag levé par l'ISR pour appeller la fonction utile -#endif // Fin directive de compilation SMS de données toutes les 10 min - -///////////////////////////////////////////////////////////////////////// - -// Carte SD - -#ifdef SD_COMP // Debut directive de compilation carte SD - -#include "SDFileSystem.h" -SDFileSystem sd(IO_SD_MOSI, IO_SD_MISO, IO_SD_SCK, IO_SD_SS, "sd"); // MOSI, MISO, SCK, SS - -bool flag_sd_ok = 0; // Flag mit à '1' après la 1ere initialisation reussie de la carte SD - -#endif // Fin directive de compilation carte SD - -///////////////////////////////////////////////////////////////////////// - -// Shield capteurs ST X_NUCLEO_IKS01A2 - -#ifdef XNUCLEO_COMP // Debut directive de compilation shield capteurs XNUCLEO - -#include "XNucleoIKS01A2.h" - -// Instantiate the expansion board -static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(IO_XNUC_SDA, IO_XNUC_SCL); // SDA, SCL, option(INT1, INT2) - -static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; -static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; -static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; - -#endif // Fin directive de compilation shield capteurs XNUCLEO - -float xnuc_t = 0.0, xnuc_h = 0.0, xnuc_t2 = 0.0, xnuc_p = 0.0; -int32_t xnuc_acc[3]; - -///////////////////////////////////////////////////////////////////////// - -// Module GPS -#ifdef GPS_COMP // Debut directive de compilation module GPS - -#include "GroveGPS.h" -Serial gps_serial(IO_GPS_TX, IO_GPS_RX, 9600); //TX, RX, liaison STM --> GPS -GroveGPS gps; -void isr_gps_serial(); // Fonction d'interuption de reception sur le port UART GPS -char timeUTCBuffer[16], latBuffer[16], lonBuffer[16], altBuffer[16], speedBuffer[16]; - -#endif // Fin directive de compilation module GPS - -unsigned int timeUTC = 0; -float lat = 0, lon = 0, alt = 0, speed = 0; - -///////////////////////////////////////////////////////////////////////// - -// Module GSM -#ifdef GSM_COMP // Debut directive de compilation module GSM - -// Flag mis à jour par interruption externe sur la LED NET. -// Passe a true lorsque sa période de clignotement est d'environs 3 s -bool flag_gsm_net_ok = 1; - -// Flag a abaisser lors de la 1ere réponse materielle du module GSM -bool flag_gsm_absent = 1; - -// Flag à lever lors de la confirmation de la présence matérielle du module GSM -// et de son démarrage en cours, et a abaisser lorsque celui ci a également démarrer logiciellement -bool flag_gsm_starting = 0; - -// Compteur calé sur le ticker HAB de période ~5 s, qui compte le temps depuis -// le dernier reset du module GSM, pour eviter de le reset trop souvent si -// la connexion est mauvaise. -unsigned int last_reset_gsm = 0; - -DigitalOut gsm_pwr(IO_GSM_PWR); // Sortie d'allumage du GSM -// todo sortie RESET du GSM -InterruptIn gsm_net(IO_GSM_NET); // Entrée de la LED "NET" -DigitalIn gsm_status(IO_GSM_STAT); // Entrée de la LED "STATUS" - -#include <GSM.h> -GSM gsm(IO_GSM_TX, IO_GSM_RX, 9600,"0649980191"); //TX, RX, PWR, NET, STATUS, baudrate, num par defaut - -char * url_srv_paul = "http://37.59.60.112/public/HAB/index.php?message="; // URL du serveur web - -#endif // Fin directive de compilation module GSM - - -///////////////////////////////////////////////////////////////////////// - -// Sonde de température PT100 sur ampli MAX31865 - -#ifdef PT100_COMP // Debut directive de compilation module PT100 - -#include "MAX31865.h" -MAX31865_RTD PT100(MAX31865_RTD::RTD_PT100,IO_PT100_MOSI, IO_PT100_MISO, IO_PT100_SCK, IO_PT100_SS); // MOSI, MISO, SCK, SS : SPI du MAX311865 - -#endif // Fin directive de compilation module PT100 - -double tempPT100 = 0; - -///////////////////////////////////////////////////////////////////////// - -// Capteur eCO2/TVOC SGP30 - -// /!\ Indication : -// Le module eCO2/TVOC produira pendant ~20 s des resultats invalides pendant son echauffement -// eCO2=400 et TVOC=0, patientez quelques instants -// module à allumer 48h à l'avance pour résultats optimums - -#ifdef CO2_COMP // Debut directive de compilation module CO2 - -#include "Adafruit_SGP30.h" - -Adafruit_SGP30 co2(IO_CO2_SDA, IO_CO2_SCL); // SDA, SCL - -#endif // Fin directive de compilation module CO2 - -int eco2 = 0; -int tvoc = 0; - -///////////////////////////////////////////////////////////////////////// - -// Capteur de temperature (exterieur haut) DS181B20 - -#ifdef DS18_COMP // Debut directive de compilation DS181B20 - -#include "DS1820.h" -DS1820 ds18(IO_DS18); - -#endif // Fin directive de compilation DS181B20 - -float tempDS18 = 0; - -///////////////////////////////////////////////////////////////////////// - -// Capteurs lumière (UV et photoresistance) - -//#ifdef UV_COMP // Debut directive de compilation capteur UV -AnalogIn pin_UV(IO_UV); -//#endif // Fin directive de compilation capteur UV - -//#ifdef PHOTORES_COMP // Debut directive de compilation capteur lumière -AnalogIn pin_photores(IO_PHOTORES); -//#endif // Fin directive de compilation capteur lumière - -float uv = 0; -float photores = 0; - -///////////////////////////////////////////////////////////////////////// - -// Capteur Bosch BME280 (temperature, pression, humidité exterieure) - -#ifdef BOSCH_COMP // Debut directive de compilation Bosch - -#include "BME280.h" -BME280 bosch(IO_BOSCH_SDA, IO_BOSCH_SCL); // SDA, SCL - -#endif // Fin directive de compilation Bosch - -float bosch_t = 0; -float bosch_p = 0; -float bosch_h = 0; - -///////////////////////////////////////////////////////////////////////// - -// Lecteur MP3 DFPlayer - -#ifdef MP3_COMP // Debut directive de compilation lecteur MP3 - -#include "DFPlayerMini.h" -DFPlayerMini mp3(IO_MP3_TX, IO_MP3_RX); //TX, RX - -#endif // Fin directive de compilation MP3 - -///////////////////////////////////////////////////////////////////////// - -// Capteur Ozone O3 - -// todo - -#ifdef O3_COMP // Debut directive de compilation spi_ozone - -SPI spi_ozone(PB_15, PB_14, PB_13); // MOSI,MISO,SCK -DigitalOut ozone_SS(IO_O3_SS,1); - -#endif // Fin directive de compilation spi_ozone - -double ozone = 0; - -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////// Fonctions annexes /////////////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -// Ozone O3 -double lecture_ozone() { - - uint32_t chiffre=0; - uint8_t Buff[4]; - - for(int i=0; i<3;i++) Buff[i] = 0; - - spi_ozone.format(8,3); - spi_ozone.frequency(1000000); - - ozone_SS.write(0); // Selection de l'esclave - - //spi_ozone.write(0x8F); - - wait_ms(100); - - Buff[0] = spi_ozone.write(0); - Buff[1] = spi_ozone.write(0); - Buff[2] = spi_ozone.write(0); - Buff[3] = spi_ozone.write(0); - - ozone_SS.write(1); // Deselection de l'esclave - - - chiffre = ((uint32_t)(Buff[0]) << 24) | ((uint32_t)(Buff[1]) << 16) | ((uint32_t)(Buff[2]) << 8) | (uint32_t)(Buff[3]); - chiffre = chiffre >> 7; - - double resultat = 0.0; - resultat = 100 - (chiffre/41943.040); // Conversion en %ADC - - return resultat; - -} - -///////////////////////////////////////////////////////////////////////// - -// Fonctions d'activation et de desactivation de l'interruption UART pour GPS - -void irq_gps_off() { - // IRQ OFF : desactivation de l'interruption pour le port UART du GPS - #ifdef GPS_COMP // Debut directive de compilation module GPS - gps_serial.attach(NULL); - #endif // Fin directive de compilation module GPS -} - -void irq_gps_on() { - // IRQ ON : activation de l'interruption pour le port UART du GPS - #ifdef GPS_COMP // Debut directive de compilation module GPS - gps_serial.attach(&isr_gps_serial,Serial::RxIrq); - #endif // Fin directive de compilation module GPS -} - -///////////////////////////////////////////////////////////////////////// - -// SD -#ifdef SD_COMP // Debut directive de compilation carte SD - -// Fonction qui ecrit le message dans le fichier passés en arguments sur la carte SD initialisée -void ecriture_sd(char * fichier, char * message) { - - // Si la carte SD n'est pas initialisée on quitte - if(flag_sd_ok == 0) return; - - irq_gps_off(); //désactivation de l'interruption UART pour GPS - - // fichier du type "/sd/data.txt" - FILE *fp = fopen(fichier, "a"); - if(fp == NULL) { - serial_pc.printf("ERREUR : carte SD\n"); - } - else { - fprintf(fp, message); - fprintf(fp, "\n"); - fclose(fp); - } - - irq_gps_on(); //ré-activation de l'interruption UART pour GPS -} - -#endif // Fin directive de compilation carte SD - - -//////////////////////////////////////////////////////////////////////// - -//Pression - Altitude - -double sealevel(double P, double A) -// Given a pressure P (mb) taken at a specific altitude (meters), -// return the equivalent pressure (mb) at sea level. -// This produces pressure readings that can be used for weather measurements. -{ - return (P / pow(1 - (A / 44330.0), 5.255)); -} - - -double altitude(double P, double P0) -// Given a pressure measurement P (mb) and the pressure at a baseline P0 (mb), -// return altitude (meters) above baseline. -{ - return (44330.0 * (1 - pow(P / P0, 1 / 5.255))); -} - -///////////////////////////////////////////////////////////////////////// - -// GSM - -#ifdef GSM_COMP // Debut directive de compilation module GSM - -void init_GSM(); - -Timer timer_gsm_net; // Compteur de la période de clignotement de la LED "NET" -unsigned int last_time_gsm_net = 0; - -void isr_net_gsm() { - - // Arret de toute les sources d'interruptions - irq_gps_off(); - gsm_net.disable_irq(); - - - timer_gsm_net.stop(); // Arret du compteur - - last_time_gsm_net = timer_gsm_net.read_ms(); // Lecture du compteur - - serial_pc.printf("last_time_gsm_net : %d\n", last_time_gsm_net); - - // Seulement si la période de clignotement est d'environs 3 s alors le module - // GSM est bien connecté au réseau et est pret a etre utilisé. - if(last_time_gsm_net > 2800 && last_time_gsm_net < 3200) { - flag_gsm_net_ok = 1; - if(flag_gsm_starting == 1) { - init_GSM(); - flag_gsm_starting = 0; - } - } - else flag_gsm_net_ok = 0; - - timer_gsm_net.reset(); // Remise a zéro et départ à nouveau du compteur - timer_gsm_net.start(); - - // Re-allumage des interruptions - irq_gps_on(); - gsm_net.enable_irq(); -} - -///////////////////////////////////////////////////////////////////////// - -// GSM - -void init_GSM() { - // Initialise (logiciellement) le module GSM - - if(gsm_status == 0) return; // Si module GSM arreté ou absent c'est inutile - - // Arret de toute les sources d'interruptions - irq_gps_off(); // Int sur RX UART - gsm_net.disable_irq(); // Int sur LED NET GSM - ticker_hab.detach(); // Ticker HAB - ticker_check_gsm.detach(); // Ticker check GSM - - serial_pc.printf("****************\nInit GSM : %d\n",gsm.init()); - serial_pc.printf("Statut SIM : %d\n",gsm.checkSIMStatus()); - serial_pc.printf("Force signal : %d\n",gsm.checkSignalStrength()); - serial_pc.printf("Reglage SMS : %d\n",gsm.settingSMS()); - serial_pc.printf("Test SMS : %d \n****************\n",gsm.sendSMS("+33649980191", "coucou")); - - flag_gsm_starting = 0; // Init logiciel effectué - - // Re-allumage des interruptions - irq_gps_on(); - gsm_net.enable_irq(); - ticker_hab.attach(&isr_ticker_hab, 5.0); - ticker_check_gsm.attach(&isr_ticker_check_gsm, 30.0); -} - -///////////////////////////////////////////////////////////////////////// - -void gsm_pwr_on() { - - // Fonction qui allume le module GSM (matériellement) si besoin - // Entrée : "bool attendre", specifie si la fonction doit attendre que le - // module GSM démarre. - - - if(gsm_status == 0) { - - // Arret de toute les sources d'interruptions - irq_gps_off(); // Int sur RX UART - gsm_net.disable_irq(); // Int sur LED NET GSM - ticker_hab.detach(); // Ticker HAB - ticker_check_gsm.detach(); // Ticker check GSM - - // Creation et lancement d'un timer de time out du démarrage du module GSM - Timer timer_gsm_init; - timer_gsm_init.start(); - - gsm_pwr = 1; - while(gsm_status == 0) { - wait(0.1); - - if(timer_gsm_init.read() > 5) { - - serial_pc.printf("ERREUR : module GSM absent\n"); - flag_gsm_absent = 1; // Constatation de l'absence du module GSM - timer_gsm_net.stop(); - gsm_pwr = 0; - - // Re-allumage des interruptions - irq_gps_on(); - gsm_net.enable_irq(); - ticker_hab.attach(&isr_ticker_hab, 5.0); - ticker_check_gsm.attach(&isr_ticker_check_gsm, 30.0); - return; - } - } - gsm_pwr = 0; - timer_gsm_net.stop(); - - } - else serial_pc.printf("Module GSM deja allume\n"); - - flag_gsm_absent = 0; // Constatation de la présence du module GSM - - // Indication que le module GSM est en train de démarrer materiellement - // ou du moins qu'il faudra bientot faire l'init logiciel dès qu'il - // sera pret (NET LED avec bonne période de 3s. - flag_gsm_starting = 1; - - // Re-allumage des interruptions - irq_gps_on(); - gsm_net.enable_irq(); - ticker_hab.attach(&isr_ticker_hab, 5.0); - ticker_check_gsm.attach(&isr_ticker_check_gsm, 30.0); - -} - -#endif // Fin directive de compilation module GSM - -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -/////////////// Tickers, Interruptions, Threads /////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -//GSM -#ifdef GSM_COMP // Debut directive de compilation module GSM - -void f_ticker_check_gsm() { - // Fonction du ticker de surveillance du module GSM, lancée toute les 30 s - - // Si module GSM absent, on retourne - if(flag_gsm_absent == 1) return; - - irq_gps_off(); //désactivation de l'interruption UART pour GPS - - // Si le module GSM est éteint, bé on l'allume - if(gsm_status == 0) gsm_pwr_on(); - - // Si module GSM non connecté - if(flag_gsm_net_ok == 0) { - - // Si cela fais plus d'une minute qu'on a démarré alors - if(compteur - last_reset_gsm > 15) { - serial_pc.printf("/:\\ Reset du module GSM...\n"); - - // todo : appui sur bouton reset du module gsm - - - last_reset_gsm = compteur; - } - } - - - // met fin à l'envoi d'un sms, le module reste parfois bloqué dans la - // commande d'envoi et ne répond pas "OK" lorsqu'on check power en envoyant "AT" - gsm.gprsSerial.putc((char)0x1A); - - int stat = gsm.checkSIMStatus(); - serial_pc.printf("\n-- Check statut SIM : %d --\n", stat); - - if(stat != 0) { - init_GSM(); - } - - irq_gps_on(); //ré-activation de l'interruption UART pour GPS - - - flag_ticker_check_gsm = 0; // Abaissage du flag -} -#endif // Fin directive de compilation module GSM - -///////////////////////////////////////////////////////////////////////// - -//GPS -#ifdef GPS_COMP // Debut directive de compilation module GPS - -// Routine d'interruption (ISR) pour la reception sur port UART du GPS -void isr_gps_serial() { - - if (gps_serial.readable()) { - #ifdef GPS_DEBUG - char c = gps_serial.getc(); - serial_pc.putc(c); - gps.readCharacter(c); - #else - gps.readCharacter(gps_serial.getc()); - #endif - } -} -#endif // Fin directive de compilation module GPS - -//////////////////////////////////////////////////////////////////////// - -// Ticker executé toute les 10 min pour envoier les données par sms -#ifdef GSM_COMP // Debut directive de compilation module GSM -void f_ticker_sms_chaine() { - - gsm.sendSMS("+33649980191", chaine_data); - - flag_ticker_sms_chaine = 0; -} -#endif // Fin directive de compilation module GSM - -//////////////////////////////////////////////////////////////////////// - -/* -Ticker executé toute les 5 s pour recolter toute les données, -les enregistrer sur la carte SD et les envoyer en UART à la carte LoRa -*/ - - -void f_ticker_hab() { - - - //DS18 thermomètre pt1 (en 2 parties pour eviter d'attendre) - #ifdef DS18_COMP // Debut directive de compilation DS181B20 - - //todo - - #endif // Fin directive de compilation DS181B20 - - - - // Recuperation donnees capteurs ST X_NUCLEO_IKS01A2 - #ifdef XNUCLEO_COMP // Debut directive de compilation shield capteurs XNUCLEO - hum_temp->get_temperature(&xnuc_t); - hum_temp->get_humidity(&xnuc_h); - press_temp->get_temperature(&xnuc_t2); - press_temp->get_pressure(&xnuc_p); - #endif // Fin directive de compilation shield capteurs XNUCLEO - - - //PT100 - #ifdef PT100_COMP // Debut directive de compilation module PT100 - PT100.read_all(); - if(PT100.status() == 0) { - tempPT100 = PT100.temperature(); - //serial_pc.printf(" T = %f degC \r\n",temp); - } - else { - tempPT100 = 0; - serial_pc.printf("Registre d'erreur PT100 : %d - ",PT100.status( )); - if(PT100.status() & MAX31865_FAULT_HIGH_THRESHOLD) { - serial_pc.printf("ERREUR PT100 seuil haut franchi\n"); - } - else if(PT100.status() & MAX31865_FAULT_LOW_THRESHOLD) { - serial_pc.printf("ERREUR PT100 seuil bas franchi\n"); - } - else if(PT100.status() & MAX31865_FAULT_REFIN) { - serial_pc.printf("ERREUR REFIN- > 0,85 x V_BIAS\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_REFIN_FORCE) { - serial_pc.printf("ERREUR REFIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_RTDIN_FORCE ) { - serial_pc.printf("ERREUR RTDIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_VOLTAGE) { - serial_pc.printf("ERREUR sur/sous-tension\n"); - } - else serial_pc.printf("ERREUR inconnue\n"); - } - #endif // Fin directive de compilation module PT100 - - - // CO2 - #ifdef CO2_COMP // Debut directive de compilation module CO2 - co2.IAQmeasure(); - /*serial_pc.printf("TVOC : %d\n", co2.TVOC); - serial_pc.printf("eCO2: %d\n", co2.eCO2);*/ - eco2 = co2.eCO2; - tvoc = co2.TVOC; - #endif // Fin directive de compilation module CO2 - - - //DS18 thermomètre pt2 (en 2 parties pour eviter d'attendre) - #ifdef DS18_COMP // Debut directive de compilation DS181B20 - - //todo - - #endif // Fin directive de compilation DS181B20 - - // Capteurs UV et lumiere - #ifdef UV_COMP // Debut directive de compilation capteur UV - uv = pin_UV.read(); - #endif // Fin directive de compilation capteur UV - #ifdef PHOTORES_COMP // Debut directive de compilation capteur lumière - photores = pin_photores.read(); - #endif // Fin directive de compilation capteur lumière - - - // Triple capteur Bosch BME280 - #ifdef BOSCH_COMP // Debut directive de compilation Bosch - bosch_t = bosch.getTemperature(); - bosch_p = bosch.getPressure(); - bosch_h = bosch.getHumidity(); - //serial_pc.printf("Bosch : %.2f *C, %.2f mbar, %.2f %%\n", bosch.getTemperature(), bosch.getPressure(), bosch.getHumidity()); - #endif // Fin directive de compilation Bosch - - - // Ozone - #ifdef O3_COMP // Debut directive de compilation spi_ozone - ozone = lecture_ozone(); - #endif // Fin directive de compilation spi_ozone - - // Mesure tension batterie (tension ref* pont diviseur + chute diode) - vbatt = pin_vbatt.read()*3.3*11.07+0.52; - - // Recuperation données GPS - #ifdef GPS_COMP // Debut directive de compilation module GPS - gps.getTimestamp(timeUTCBuffer); - gps.getLatitude(latBuffer); - gps.getLongitude(lonBuffer); - gps.getAltitude(altBuffer); - gps.getSpeed(speedBuffer); - //printf("UTC: %s\t Latitude: %s\t Longitude: %s\t altitude: %s\t speed: %s\n", timeUTCBuffer, latBuffer, lonBuffer, altBuffer, speedBuffer); - // Convertion des chaine en entier et flottant - timeUTC = atoi(timeUTCBuffer); - lat = (float)atof(latBuffer); - lon = (float)atof(lonBuffer); - alt = (float)atof(altBuffer); - speed = (float)atof(speedBuffer); - #endif // Fin directive de compilation module GPS - - - // mise en forme dans un tableau de caractères - sprintf((char*) chaine_data, "%d-%.2f-%d-%f-%f-%.1f-%.1f-%.1f-%.1f-%.3f-%.3f-%.3f-%.1f-%.3f-%.2f-%.2f-%d-%d-%f-%.3f-%.3f", compteur, vbatt, timeUTC, lat, lon, alt, speed, xnuc_t, xnuc_t2, tempPT100, tempDS18, bosch_t, xnuc_h, bosch_h, xnuc_p, bosch_p, eco2, tvoc, ozone, uv*100.0, photores*100.0); - - - // Affichage des données sur port série debug - serial_pc.printf("*Compteur : %d\n", compteur); - serial_pc.printf("*Tension batterie : %f V\n", vbatt); - #ifdef GPS_COMP // Debut directive de compilation module GPS - serial_pc.printf("*Temps UTC : %d\n", timeUTC); - serial_pc.printf("*Latitude : %f\n", lat); - serial_pc.printf("*Longitude : %f\n", lon); - serial_pc.printf("*Altitude : %.2f m\n", alt); - serial_pc.printf("*Vitesse : %.2f km/h\n", speed); - #endif // Fin directive de compilation module GPS - #ifdef XNUCLEO_COMP // Debut directive de compilation shield capteurs XNUCLEO - serial_pc.printf("*Temperature 1 (XNUCLEO) : %.3f *C\n", xnuc_t); - serial_pc.printf("*Temperature 2 (XNUCLEO) : %.3f *C\n", xnuc_t2); - #endif // Fin directive de compilation shield capteurs XNUCLEO - #ifdef PT100_COMP // Debut directive de compilation module PT100 - serial_pc.printf("*Temperature 3 (PT100) : %.3f *C\n", tempPT100); - #endif // Fin directive de compilation module PT100 - #ifdef DS18_COMP // Debut directive de compilation DS181B20 - serial_pc.printf("*Temperature 4 (DS18) : %.3f *C\n", tempDS18); - #endif // Fin directive de compilation DS181B20 - #ifdef BOSCH_COMP // Debut directive de compilation Bosch - serial_pc.printf("*Temperature 5 (Bosch) : %.3f *C\n",bosch_t); - #endif // Fin directive de compilation Bosch - #ifdef XNUCLEO_COMP // Debut directive de compilation shield capteurs XNUCLEO - serial_pc.printf("*Humidite 1 (XNUCLEO) : %.2f %%\n", xnuc_h); - #endif // Fin directive de compilation shield capteurs XNUCLEO - #ifdef BOSCH_COMP // Debut directive de compilation Bosch - serial_pc.printf("*Humidite 2 (Bosch) : %.2f %%\n",bosch_h); - #endif // Fin directive de compilation Bosch - #ifdef XNUCLEO_COMP // Debut directive de compilation shield capteurs XNUCLEO - serial_pc.printf("*Pression 1 (XNUCLEO) : %.2f mbar - altitude calculee : %.2f m\n", xnuc_p, altitude(xnuc_p, 1016)); - #endif // Fin directive de compilation shield capteurs XNUCLEO - #ifdef BOSCH_COMP // Debut directive de compilation Bosch - serial_pc.printf("*Pression 2 (Bosch) : %.2f mbar - altitude calculee : %.2f m\n",bosch_p, altitude(bosch_p, 1016)); - #endif // Fin directive de compilation Bosch - #ifdef CO2_COMP // Debut directive de compilation module CO2 - serial_pc.printf("*eCO2 : %d ppm\n", eco2); - serial_pc.printf("*TVOC : %d ppb\n", tvoc); - #endif // Fin directive de compilation module CO2 - #ifdef UV_COMP // Debut directive de compilation capteur UV - serial_pc.printf("*UV : %.3f %%ADC\n", uv*100.0); - #endif // Fin directive de compilation capteur UV - #ifdef PHOTORES_COMP // Debut directive de compilation capteur lumière - serial_pc.printf("*Lum : %.3f %%ADC\n", photores*100.0); - #endif // Fin directive de compilation capteur lumière - #ifdef O3_COMP // Debut directive de compilation spi_ozone - serial_pc.printf("*Ozone O3 : %f %%ADC\n", ozone); - #endif // Fin directive de compilation spi_ozone - - - serial_pc.printf(">> %s\n", chaine_data); - - - // Envoie de la chaine par GPRS au serveur de Paul - #ifdef GSM_COMP // Debut directive de compilation module GSM - #ifdef GPRS_COMP // Debut directive de compilation données mobiles - if(flag_gsm_net_ok == 1) gsm.gprs_message(url_srv_paul , chaine_data); - #endif // Fin directive de compilation données mobiles - //if(flag_gsm_net_ok == 1) serial_pc.printf("SMS : %d\n",gsm.sendSMS("+33649980191", chaine_data)); // Envoi de la chaine par SMS - #endif // Fin directive de compilation module GSM - - // Sauvegarde sur carte SD - #ifdef SD_COMP // Debut directive de compilation carte SD - ecriture_sd("/sd/data.txt", chaine_data); - #endif // Fin directive de compilation carte SD - - - // Creation de la chaine à envoyer à la carte LoRa - #ifdef LORA_COMP // Debut directive de compilation LoRa - sprintf((char*) chaine_lora, "%.2f-%f-%f-%.1f-%.3f", vbatt, lat, lon, alt, tempPT100); - serial_pc.printf(">> %s\n", chaine_lora); - #endif // Fin directive de compilation LoRa - - serial_pc.printf("************************************************\n"); - compteur++; - - flag_ticker_hab = 0; // Abaissage du flag -} - -///////////////////////////////////////////////////////////////////////// - -// Routines d'interruption appelées au tick des tickers et servant juste à lever un flag -// Pensez à abaisser le flag dans f_ticker_hab() et f_ticker_gsm() ! - -void isr_ticker_hab() { flag_ticker_hab = 1; } -#ifdef GSM_COMP -void isr_ticker_check_gsm() { flag_ticker_check_gsm = 1; } -#endif // Fin directive de compilation module GSM -#ifdef SMS_COMP -void isr_ticker_sms_chaine() { flag_ticker_sms_chaine = 1; } -#endif - -///////////////////////////////////////////////////////////////////////// - -// LoRa - -#ifdef LORA_COMP // Debut directive de compilation LoRa - -void envoi_chaine_lora() { - - lora_serial.printf("%s\n", chaine_lora); - serial_pc.printf("lora!\n"); // debug -} - -void isr_lora_serial() { - - char c = lora_serial.getc(); - if(c == 'a') envoi_chaine_lora(); - #ifdef MP3_COMP // Debut directive de compilation lecteur MP3 - elseif(c == 'b') mp3.mp3_play(); - elseif(c == 'c') mp3.mp3_pause(); - #endif // Fin directive de compilation lecteur MP3 - #ifdef BUZZ_COMP // Debut directive de compilation buzzer - elseif(c == 'd') pin_buzzer.write(1); - elseif(c == 'e') pin_buzzer.write(0); - #endif // Fin directive de compilation buzzer - -} -#endif // Fin directive de compilation LoRa - - -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////////////// MAIN //////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -int main() { - - // Affichage/listage des modules compilés/activés sur port série STLINK - serial_pc.printf("--- Programme HAB carte mere ---\n"); - vbatt = pin_vbatt.read()*3.3*11.07+0.52; // Tension batterie (tension ref * pont diviseur + chute diode) - serial_pc.printf("Tension batterie : %f V\n", vbatt); - serial_pc.printf("Modules compiles :\n"); - - - //Buzzer, léger bip au démarrage - #ifdef BUZZ_COMP - serial_pc.printf("- Buzzer\n"); - pin_buzzer.write(1); - wait(0.1); - pin_buzzer.write(0); - #endif - - // Shield ST X_NUCLEO_IKS01A2 - #ifdef XNUCLEO_COMP - hum_temp->enable(); - press_temp->enable(); - accelerometer->enable(); - // lecture des capteurs - hum_temp->get_temperature(&xnuc_t); - hum_temp->get_humidity(&xnuc_h); - press_temp->get_temperature(&xnuc_t2); - press_temp->get_pressure(&xnuc_p); - serial_pc.printf("- XNUCLEO : %.3f *C, %.3f *C, %.3f mbar, %.2f %%\n",xnuc_t, xnuc_t2, xnuc_p, xnuc_h); - - accelerometer->get_x_axes(xnuc_acc); - serial_pc.printf(" accelerometre : x = %ld, y = %ld, z = %ld\n", xnuc_acc[0], xnuc_acc[1], xnuc_acc[2]); - - #endif - - // GSM - #ifdef GSM_COMP - serial_pc.printf("- GSM : "); - gsm_pwr_on(); - #endif - #ifdef GPRS_COMP - serial_pc.printf("- Donnees mobiles\n"); - #endif - - #ifdef PT100_COMP - serial_pc.printf("- PT100 : "); - // Configuration initiale du MAX31865 - /* - 1: v_biais : Vbias (tension de polarisation) activée (true) ou non (false) - 2: conversion_mode : mode de conversion automatique activé (true) ou non (false) - 3: one_shot : mesure au coup par coup (true) ou en continue (false) - 4: three_wire : mesure 3 fils activée (true) ou 2/4 fils (false) - 5: fault_cycle : detection d'erreur (voir datasheet) activée (true) ou non (false) - 6: fault_clear : acquittement automatique des erreurs activée (true) ou non (false) - 7: filter_50hz : filtre 50 Hz activé (true) ou non (false) - 8: low_threshold : seuil d'erreur bas. (0x0000 = 0) - 9: high_threshold : seuil d'erreur haut. (0x7fff = 32767) - */ - PT100.configure(true, true, false, false, MAX31865_FAULT_DETECTION_NONE, true, true, 0x0000, 0x7fff); - PT100.read_all(); - if(PT100.status() == 0) { - serial_pc.printf("%.3f *C\n",PT100.temperature()); - } - else { - serial_pc.printf("Registre d'erreur PT100 : %d - ",PT100.status( )); - if(PT100.status() & MAX31865_FAULT_HIGH_THRESHOLD) { - serial_pc.printf("ERREUR PT100 seuil haut franchi\n"); - } - else if(PT100.status() & MAX31865_FAULT_LOW_THRESHOLD) { - serial_pc.printf("ERREUR PT100 seuil bas franchi\n"); - } - else if(PT100.status() & MAX31865_FAULT_REFIN) { - serial_pc.printf("ERREUR REFIN- > 0,85 x V_BIAS\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_REFIN_FORCE) { - serial_pc.printf("ERREUR REFIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_RTDIN_FORCE ) { - serial_pc.printf("ERREUR RTDIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); - } - else if(PT100.status( ) & MAX31865_FAULT_VOLTAGE) { - serial_pc.printf("ERREUR sur/sous-tension\n"); - } - else serial_pc.printf("ERREUR inconnue\n"); - } - #endif - - // Carte SD, initialisation, et creation d'un fichier de test d'ecriture - // /!\ Faire cette étape après l'initialisation du capteur PT100 qui partage le même SPI - #ifdef SD_COMP - serial_pc.printf("- SD : "); - mkdir("/sd/TEST", 0777); - FILE *fp = fopen("/sd/TEST/sdtest.txt", "w"); - if(fp == NULL) { - serial_pc.printf("ERREUR, ecriture carte SD\n"); - // Desactivation de la sauvegarde sur carte SD - flag_sd_ok = 0; - } - else { - fprintf(fp, "test ecriture"); - fclose(fp); - serial_pc.printf("ecriture ok\n"); - //Activation de la sauvegarde sur carte SD - flag_sd_ok = 1; - } - #endif - - // CO2 - #ifdef CO2_COMP - co2.begin(); - co2.IAQmeasure(); - serial_pc.printf("- CO2 : TVOC = %d, eCO2 = %d\n", co2.TVOC, co2.eCO2); - #endif - - //DS18 thermomètre - #ifdef DS18_COMP // Debut directive de compilation DS181B20 - - if (ds18.begin()) { - while (1) { - ds18.startConversion(); // start temperature conversion from analog to digital - wait(1.0); // let DS1820 complete the temperature conversion - result = ds18.read(tempDS18); // read temperature from DS1820 and perform cyclic redundancy check (CRC) - switch (result) { - case 0: // no errors -> 'tempDS18' contains the value of measured temperature - serial_pc.printf("temp = %3.1f%cC\r\n", tempDS18, 176); - break; - case 1: // no sensor present -> 'tempDS18' is not updated - serial_pc.printf("no sensor present\n\r"); - break; - case 2: // CRC error -> 'tempDS18' is not updated - serial_pc.printf("CRC error\r\n"); - } - } - } - else - serial_pc.printf("No DS1820 sensor found!\r\n"); - - #endif // Fin directive de compilation DS181B20 - - //UV - #ifdef UV_COMP - serial_pc.printf("- UV : %.3f %%ADC\n",pin_UV.read()); - #endif - - //Photoresistance - #ifdef PHOTORES_COMP - serial_pc.printf("- Photoresistance : %.3f %%ADC\n",pin_photores.read()*100.0); - #endif - - // Triple capteur Bosch BME280 - #ifdef BOSCH_COMP // Debut directive de compilation Bosch - serial_pc.printf("- Bosch : %.2f *C, %.2f mbar, %.2f %%\n", bosch.getTemperature(), bosch.getPressure(), bosch.getHumidity()); - #endif // Fin directive de compilation Bosch - - // Lecteur MP3 - // Creer un fichier 0.mp3 à la racine de la carte SD - #ifdef MP3_COMP // Debut directive de compilation lecteur MP3 - serial_pc.printf("- MP3\n"); - mp3.mp3_reset(); - wait(1); - mp3.mp3_set_EQ(0); - wait(0.5); - mp3.mp3_set_volume(20); - wait(0.5); - mp3.mp3_set_device(2); // 1,2,3,4,5 : USB,SD,AUX,SLEEP,FLASH - wait(0.5); - mp3.mp3_single_loop(0); - wait(0.5); - mp3.mp3_play(); - #endif // Fin directive de compilation MP3 - - - #ifdef LORA_COMP - serial_pc.printf("- LoRa\n"); - #endif - #ifdef GPS_COMP - serial_pc.printf("- GPS\n"); - #endif - - #ifdef O3_COMP - serial_pc.printf("- Ozone O3 : %f %%ADC\n", lecture_ozone()); - #endif - - - - serial_pc.printf("************************************************\n"); - - ////// Lancement des ticker et des interruptions //////// - - // GPS - // Mise en place de l'interruption pour le port UART du GPS - #ifdef GPS_COMP // Debut directive de compilation module GPS - gps_serial.attach(&isr_gps_serial,Serial::RxIrq); - #endif // Fin directive de compilation module GPS - - - // Ticker de creation de la chaine de données toute les 5s - ticker_hab.attach(&isr_ticker_hab, 5.0); - - - // GSM - #ifdef GSM_COMP // Debut directive de compilation module GSM - if(flag_gsm_absent == 0) { - - // Interruption sur LED "NET" et compteur de sa période - timer_gsm_net.reset(); // Démarrage du compteur de la période de clignotement de la LED "NET" - timer_gsm_net.start(); - gsm_net.rise(&isr_net_gsm); // Attachement de l'interruption externe sur la LED "NET" - - // Ticker de surveillance GSM toute les 30s - ticker_check_gsm.attach(&isr_ticker_check_gsm, 30.0); - - // Ticker d'envoi de données par sms toute les 10 min - #ifdef SMS_COMP // Debut directive de compilation envoi SMS - ticker_sms_chaine.attach(&isr_ticker_sms_chaine, 600.0); - #endif // Fin directive de compilation SMS de données toutes les 10 min - } - #endif // Fin directive de compilation module GSM - - - // LoRa - // Mise en place de l'interruption pour le port UART LoRa - #ifdef LORA_COMP // Debut directive de compilation LoRa - lora_serial.attach(&isr_lora_serial,Serial::RxIrq); - #endif // Fin directive de compilation LoRa - - /////////////////// BOUCLE PRINCIPALE ///////////////// - - while(1) { - - // Vérification du flag d'interruption pour la routine de recuperation - // des données des capteurs, enregistrement, envoi LoRa, etc. - if(flag_ticker_hab == 1) f_ticker_hab(); - - - // Vérification du flag d'interruption pour la routine de vérification - // de l'état du module - #ifdef GSM_COMP // Debut directive de compilation module GSM - if(flag_ticker_check_gsm == 1) f_ticker_check_gsm(); - #endif // Fin directive de compilation module GSM - - // Vérification du flag d'interruption pour la routine d'envoi de SMS - // de donnée toute les 10 min - #ifdef GPS_COMP // Debut directive de compilation module GPS - #ifdef SMS_COMP // Debut directive de compilation SMS de données toutes les 10 min - if(flag_ticker_sms_chaine == 1) f_ticker_sms_chaine(); - #endif // Fin directive de compilation SMS de données toutes les 10 min - #endif // Fin directive de compilation module GSM - - } -} +///////////////////////////////////////////////////////////////////////// +// AMU - Aix-Marseille Université +// Polytech Marseille - Microelectronique & Telecommunications (MT) +// Projet MT5A "STM32 In the Sky - HAB", 2018-2019 +// Enseignants : C.Dufaza & H. Aziza +// Etudiants : ... +///////////////////////////////////////////////////////////////////////// +// Version avril 2019, C.Dufaza +/* todo : +- resoudre incompatibilité mbed thermomètre DS18 +- utilisation de l'entrée Reset du module GSM +- check si le lecteur MP3 est bien actif +*/ + +///////////////////////////////////////////////////////////////////////// +//// ... Includes + +// Activation des différents modules de ce code (via directives de compilation) +#include "define_myMODULES.h" +// Assignation des entrées/sorties des différents modules +#include "define_myIO.h" +// Include usuels ... +#include <stdio.h> +#include <string> +#include "mbed.h" + +///////////////////////////////////////////////////////////////////////// +//// Main code +///////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////// +//// Variables globales ... + +// Compteur du nombre de recolte de données depuis le démarrage +unsigned int hab_frame_counter = 1; +// Mesure de la tension de la batterie +float vbatt = 0.0; +AnalogIn pin_vbatt(IO_VBATT); +// Trame des données des capteurs à stocker sur la carte sd et au GPRS +char sd_gprs_data[SD_GPRS_DATA_SIZE]; +// GPS variables +unsigned int timeUTC = 0; +float lat = 0, lon = 0, alt = 0, speed = 0; +// Xnucleo variables +float xnuc_t = 0.0, xnuc_h = 0.0, xnuc_t2 = 0.0, xnuc_p = 0.0; +int32_t xnuc_acc[3]; +// PT100 variables +double tempPT100 = 0; +// SGP30 variables +int eco2 = 0, tvoc = 0; +// Temperature DS18 variable +float tempDS18 = 0; +// UV & Photo variables +float uv = 0, photores = 0; +// BME280 variables (temperature, pression, humidité exterieure) +float bosch_t = 0, bosch_p = 0, bosch_h = 0; +// Ozone variable +double ozone = 0; + +///////////////////////////////////////////////////////////////////////// +//// Tickers d'interruption + +// Ticker executé toute les xx s pour recolter toute les données des capteurs, +// les enregistrer sur la carte SD et les envoyer en UART à la carte LoRa +#ifdef HAB_FUNCTION // Debut directive de compilation module HAB + Ticker ticker_hab; // Object Ticker + void isr_ticker_hab(); // Routine ISR appellée lors du tick + void f_ticker_hab(); // Fonction utile appellée à la suite du tick + bool flag_ticker_hab = 0; // Flag levé par l'ISR pour appeller la fonction utile +#endif // Fin directive de compilation module HAB + +// Ticker executé toute les xx s pour vérifier l'etat du module GSM +#ifdef GSM_FUNCTION // Debut directive de compilation module GSM + Ticker ticker_check_gsm; // Object Ticker + void isr_ticker_check_gsm(); // Routine ISR appellée lors du tick + void f_ticker_check_gsm(); // Fonction utile appellée à la suite du tick + bool flag_ticker_check_gsm = 0; // Flag levé par l'ISR pour appeller la fonction utile +#endif // Fin directive de compilation module GSM + +// Ticker executé toute les 10 min pour vérifier l'etat du module GPRS SMS +#ifdef SMS_FUNCTION // Debut directive de compilation SMS de données toutes les 10 min + Ticker ticker_sms_data; // Object Ticker + void isr_ticker_sms_data(); // Routine ISR appellée lors du tick + void f_ticker_sms_data(); // Fonction utile appellée à la suite du tick + bool flag_ticker_sms_data = 0; // Flag levé par l'ISR pour appeller la fonction utile +#endif // Fin directive de compilation SMS de données toutes les 10 min + +///////////////////////////////////////////////////////////////////////// +// UART PC Debug +#ifdef DEBUG_SERIAL_PC // ACtivation de la liaison UART PC pour Debug + Serial serial_pc(SERIAL_TX, SERIAL_RX, DEBUG_SERIAL_PC_BAUDRATE); +#endif + +///////////////////////////////////////////////////////////////////////// +// Buzzer digital Out pin +#ifdef BUZZ_FUNCTION // Debut directive de compilation buzzer + DigitalOut pin_buzzer(IO_BUZZER,0); +#endif // Fin directive de compilation buzzer + +///////////////////////////////////////////////////////////////////////// +// Carte SD +#ifdef SD_FUNCTION // Debut directive de compilation carte SD + #include "SDFileSystem.h" + // MOSI, MISO, SCK, SS + SDFileSystem sd(IO_SD_MOSI, IO_SD_MISO, IO_SD_SCK, IO_SD_CS, SD_FUNCTION_SDNAME); + // flag_sd_ok = 1 après la 1ere initialisation reussie de la carte SD + bool flag_sd_ok = 0; +#endif // Fin directive de compilation carte SD + +///////////////////////////////////////////////////////////////////////// +// Lecteur MP3 DFPlayer +#ifdef MP3_FUNCTION // Debut directive de compilation lecteur MP3 + #include "DFPlayerMini.h" + DFPlayerMini mp3(IO_MP3_TX, IO_MP3_RX); //TX, RX +#endif // Fin directive de compilation MP3 + +///////////////////////////////////////////////////////////////////////// +// Module GSM +#ifdef GSM_FUNCTION // Debut directive de compilation module GSM + #include <GSM.h> // GSM Library + // Flag mis à jour par interruption externe sur la LED NET. + // Passe a true lorsque sa période de clignotement est d'environ 3s + bool flag_gsm_network_ok = 0; + // Flag a abaisser lors de la 1ere réponse materielle du module GSM + bool flag_gsm_absent = 1; + // Flag à lever lors de la confirmation de la présence matérielle du module GSM + // et de son démarrage en cours, et à abaisser lorsque celui ci a également démarrer logiciellement + bool flag_gsm_starting = 0; + // Compteur calé sur le ticker HAB de période ~5 s, qui compte le temps depuis + // le dernier reset du module GSM, pour eviter un reset trop fréquent si la connexion est mauvaise. + unsigned int last_reset_gsm = 0; + // GSM I/O PinInOut + DigitalOut gsm_pwr(IO_GSM_PWR); // Sortie d'allumage du GSM + // todo sortie RESET du GSM + InterruptIn gsm_net(IO_GSM_NET); // Entrée de la LED "NET" + DigitalIn gsm_status(IO_GSM_STAT); // Entrée de la LED "STATUS" + //TX, RX, PWR, NET, STATUS, baudrate, num par defaut + GSM gsm(IO_GSM_TX, IO_GSM_RX, GSM_BAUDRATE, GSM_SIM_NUMBER); + // URL du serveur web + char * url_srv_polytech = POLYTECH_SERVER; +#endif // Fin directive de compilation module GSM + +///////////////////////////////////////////////////////////////////////// +// Module GPS +#ifdef GPS_FUNCTION // Debut directive de compilation module GPS + #include "GroveGPS.h" + //TX, RX, liaison STM --> GPS + Serial gps_serial(IO_GPS_TX, IO_GPS_RX, GPS_BAUDRATE); + GroveGPS gps; + void isr_gps_serial(); // Fonction d'interuption de reception sur le port UART GPS + char timeUTCBuffer[16], latBuffer[16], lonBuffer[16], altBuffer[16], speedBuffer[16]; +#endif // Fin directive de compilation module GPS + +///////////////////////////////////////////////////////////////////////// +// Shield capteurs ST X_NUCLEO_IKS01A2 +#ifdef XNUCLEO_FUNCTION // Debut directive de compilation shield capteurs XNUCLEO + #include "XNucleoIKS01A2.h" + // Instantiate the expansion board: SDA, SCL, option(INT1, INT2) + static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(IO_XNUC_SDA, IO_XNUC_SCL); + static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; + static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; + static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; +#endif // Fin directive de compilation shield capteurs XNUCLEO + +///////////////////////////////////////////////////////////////////////// +// Sonde de température PT100 sur ampli MAX31865 +#ifdef PT100_FUNCTION // Debut directive de compilation module PT100 + #include "MAX31865.h" + // MOSI, MISO, SCK, SS : SPI du MAX311865 + MAX31865_RTD PT100(MAX31865_RTD::RTD_PT100,IO_PT100_MOSI, IO_PT100_MISO, IO_PT100_SCK, IO_PT100_CS); +#endif // Fin directive de compilation module PT100 + +///////////////////////////////////////////////////////////////////////// +// Capteur de temperature (exterieur haut) DS181B20 +#ifdef DS18_FUNCTION // Debut directive de compilation DS181B20 + #include "DS1820.h" + DS1820 ds18(IO_DS18); +#endif // Fin directive de compilation DS181B20 + +///////////////////////////////////////////////////////////////////////// +// Capteurs lumière (UV et photoresistance) +#ifdef UV_FUNCTION // Debut directive de compilation capteur UV + AnalogIn pin_UV(IO_UV); +#endif // Fin directive de compilation capteur UV +#ifdef PHOTORES_FUNCTION // Debut directive de compilation capteur lumière + AnalogIn pin_photores(IO_PHOTORES); +#endif // Fin directive de compilation capteur lumière + +///////////////////////////////////////////////////////////////////////// +// Capteur Bosch BME280 (temperature, pression, humidité exterieure) +#ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + #include "BME280.h" + BME280 bosch(IO_BOSCH_SDA, IO_BOSCH_SCL); // SDA, SCL +#endif // Fin directive de compilation Bosch + +///////////////////////////////////////////////////////////////////////// +// Capteur eCO2/TVOC SGP30, voir note : +// Le module eCO2/TVOC produira pendant ~20 s des resultats invalides +// eCO2=400 et TVOC=0, patientez quelques instants +// module à allumer 48h à l'avance pour résultats optimums +#ifdef CO2_FUNCTION // Debut directive de compilation module CO2 + #include "Adafruit_SGP30.h" + Adafruit_SGP30 co2(IO_CO2_SDA, IO_CO2_SCL); // SDA, SCL +#endif // Fin directive de compilation module CO2 + +///////////////////////////////////////////////////////////////////////// +// Capteur Ozone O3 +// ... todo +#ifdef O3_FUNCTION // Debut directive de compilation spi_ozone + SPI spi_ozone(PB_15, PB_14, PB_13); // MOSI, MISO, SCK + DigitalOut ozone_SS(IO_O3_CS,1); +#endif // Fin directive de compilation spi_ozone + +///////////////////////////////////////////////////////////////////////// +// LORA Module +#ifdef LORA_FUNCTION // Debut directive de compilation LoRa + // todo: liaison UART avec carte LoRa + watchdog carte mère + Serial lora_serial(IO_LORA_TX, IO_LORA_RX, LORA_FUNCTION_BAUDRATE); + // Chaine de char contenant la trame des données des capteurs à envoyer + char lora_data_tx[LORA_FUNCTION_DATASIZE]; +#endif // Fin directive de compilation LoRa + +///////////////////////////////////////////////////////////////////////// +//// Fonctions annexes + +//////////////////////////////////////////////////////////////////////// +// Pression - Altitude +double sealevel(double P, double A) +// Given a pressure P (mb) taken at a specific altitude (meters), +// return the equivalent pressure (mb) at sea level. +// This produces pressure readings that can be used for weather measurements. +{ return (P / pow(1 - (A / 44330.0), 5.255)); +} + +double altitude(double P, double P0) +// Given a pressure measurement P (mb) and the pressure at a baseline P0 (mb), +// return altitude (meters) above baseline. +{ return (44330.0 * (1 - pow(P / P0, 1 / 5.255))); +} + +// Initialise l'interruption GPS ... pré-déclaration +void irq_gps_on(); +void irq_gps_off(); + +// Permet de gérer les modes On-Off des Interruption & Tickers +void all_irq_on_off(int gps_on_off, int gsm_on_off, int ticker_hab_on_off, int ticker_gsm_on_off) { + // Interruption GPS On ou Off + if(gps_on_off == 1) { irq_gps_on(); } + if(gps_on_off == 0) { irq_gps_off(); } + // Module GSM Enable ou Disable + if(gsm_on_off == 1) { gsm_net.enable_irq(); } + if(gsm_on_off == 0) { gsm_net.disable_irq(); } + // Ticker HAB Attach ou Detach + if(ticker_hab_on_off == 1) { ticker_hab.attach(&isr_ticker_hab, TICKER_HAB_TIME); } + if(ticker_hab_on_off == 0) { ticker_hab.detach(); } + // Ticker GSM Attach ou Detach + if(ticker_gsm_on_off == 1) { ticker_check_gsm.attach(&isr_ticker_check_gsm, TICKER_CHECK_GSM_TIME); } + if(ticker_gsm_on_off == 0) { ticker_check_gsm.detach(); } +} + +///////////////////////////////////////////////////////////////////////// +// SD +#ifdef SD_FUNCTION // Debut directive de compilation carte SD + +// Fonction qui ecrit le message dans le fichier passés en arguments sur la carte SD initialisée +void ecriture_sd(char * fichier, char * message) { + // Si la carte SD n'est pas initialisée on quitte + if(flag_sd_ok == 0) return; + // On désactive l'interruption UART pour GPS + all_irq_on_off(0, 2, 2, 2); // irq_gps_off(); + // Fichier en mode a - append ... du type "/sd/data.txt" + FILE *fp = fopen(fichier, "a"); + if(fp == NULL) { // Erreur d'ouverture du fichier + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("<<<< ERREUR >>>> carte SD, ouverture fichier impossible\n"); + #endif + } + else { // Fichier correctement ouvert en mode append, écriture puis fermeture + fprintf(fp, message); fprintf(fp, "\n"); + fclose(fp); + } + // Ré-activation de l'interruption UART pour GPS + all_irq_on_off(1, 2, 2, 2); // irq_gps_on(); +} + +#endif // Fin directive de compilation carte SD + +///////////////////////////////////////////////////////////////////////// +// GSM +#ifdef GSM_FUNCTION // Debut directive de compilation module GSM + +// Initialise le GSM ... pré-déclaration +void init_GSM(); + +// Variables GSM +Timer timer_gsm_network; // Compteur de la période de clignotement de la LED "NET" +unsigned int last_time_gsm_network = 0; + +void isr_network_gsm() { + // Arret de toute les sources d'interruptions + all_irq_on_off(0, 0, 2, 2); + //irq_gps_off(); // Interruption GPS off + //gsm_net.disable_irq(); // Disable interrupt GSM + + timer_gsm_network.stop(); // Arret du timer GSM + last_time_gsm_network = timer_gsm_network.read_ms(); // Lecture du timer GSM + #ifdef DEBUG_SERIAL_PC + //debug_if(DEBUG_SERIAL_PC, "Timer GSM Network (ms) : %d\n", last_time_gsm_network); + //serial_pc.printf("Timer GSM Network (ms) : %d\n", last_time_gsm_network); + #endif + // Seulement si la période de clignotement est d'environs 3s alors le module + // GSM est bien connecté au réseau et est pret a etre utilisé. + if(last_time_gsm_network > 2800 && last_time_gsm_network < 3200) { + #ifdef DEBUG_SERIAL_PC + //serial_pc.printf("> Timer GSM Network (ms) : %d\n", last_time_gsm_network); + #endif + flag_gsm_network_ok = 1; // le GSM est ok + if(flag_gsm_starting == 1) { // est-il tjs en démarrage ? + init_GSM(); + flag_gsm_starting = 0; + } } + else flag_gsm_network_ok = 0; // le GSM n'est pas ok + + timer_gsm_network.reset(); // Raz et nouveau départ du timer GSM + timer_gsm_network.start(); + + // On autorise de nouveau les interruptions GPS et GSM + all_irq_on_off(1, 1, 2, 2); + //irq_gps_on(); + //gsm_net.enable_irq(); +} + +// On initialise le GSM +void init_GSM() { + // Initialise (logiciellement) le module GSM + if(gsm_status == 0) return; // Si module GSM arreté ou absent c'est inutile + + // Arret de toute les sources d'interruptions + all_irq_on_off(0, 0, 0, 0); + //irq_gps_off(); // Int sur RX UART + //gsm_net.disable_irq(); // Int sur LED NET GSM + //ticker_hab.detach(); // Ticker HAB + //ticker_check_gsm.detach(); // Ticker check GSM + + #ifdef DEBUG_SERIAL_PC + serial_pc.printf(">>> GSM Initialisation <<<\n"); + serial_pc.printf(" Init GSM : %d\n",gsm.init()); + serial_pc.printf(" Statut SIM : %d\n",gsm.checkSIMStatus()); + serial_pc.printf(" Force signal : %d\n",gsm.checkSignalStrength()); + serial_pc.printf(" Reglage SMS : %d\n",gsm.settingSMS()); + //serial_pc.printf(" Test SMS : %d\n",gsm.sendSMS(GSM_SEND_NUMBER, GSM_SEND_SMS_HELLO)); + #endif + + // On considere le GSM initialisé et n'est donc plus en phase de démarrage + flag_gsm_starting = 0; + + // On autorise de nouveau les interruptions GPS et GSM, ticker HAB + all_irq_on_off(1, 1, 1, 1); + //irq_gps_on(); + //gsm_net.enable_irq(); + //ticker_hab.attach(&isr_ticker_hab, TICKER_HAB_TIME); + //ticker_check_gsm.attach(&isr_ticker_check_gsm, TICKER_CHECK_GSM_TIME); +} + +// Fonction qui allume le module GSM (matériellement) +void gsm_pwr_on() { + // Entrée : "bool attendre", specifie si la fonction doit attendre que le + // module GSM démarre. + if(gsm_status == 0) { + // Arret de toute les sources d'interruptions + all_irq_on_off(0, 0, 0, 0); + + // Creation et lancement d'un timer de time out du démarrage du module GSM + Timer timer_gsm_init; + timer_gsm_init.start(); + + // On considere que le GSM est sous-tension, on verifiera ... + gsm_pwr = 1; + + while(gsm_status == 0) { + wait(0.5); + if(timer_gsm_init.read() > 5) { // Si après 5s ... ? + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("<<<< ERREUR >>>> module GSM absent\n"); + #endif + flag_gsm_absent = 1; // Constatation de l'absence du module GSM + timer_gsm_network.stop(); // Arrêt du timer GSM + gsm_pwr = 0; // le GSM n'est donc pas sous tension + // On autorise de nouveau les interruptions GPS et GSM, ticker HAB + all_irq_on_off(1, 1, 1, 1); + return; + } + } + gsm_pwr = 0; + timer_gsm_network.stop(); + } + else + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("Module GSM deja allume "); + #endif + // Constatation de la présence du module GSM + flag_gsm_absent = 0; + // Indication que le module GSM est en train de démarrer materiellement + // ou du moins qu'il faudra bientot faire l'init logiciel dès qu'il + // sera pret (NET LED avec bonne période de 3s. + flag_gsm_starting = 1; + + // On autorise de nouveau les interruptions GPS et GSM, ticker HAB + all_irq_on_off(1, 1, 1, 1); + +} + +#endif // Fin directive de compilation module GSM + +///////////////////////////////////////////////////////////////////////// +// Ozone O3 +#ifdef O3_FUNCTION // Debut directive de compilation spi_ozone + +double lecture_ozone() { + // Variables + double resultat = 0.0; + uint32_t chiffre=0; + uint8_t Buff[4]; + for(int i=0; i<3;i++) Buff[i] = 0; + + // Paramètres Ozone + spi_ozone.format(8,3); + spi_ozone.frequency(1000000); + ozone_SS.write(0); // Selection de l'esclave + //spi_ozone.write(0x8F); + wait_ms(100); + Buff[0] = spi_ozone.write(0); + Buff[1] = spi_ozone.write(0); + Buff[2] = spi_ozone.write(0); + Buff[3] = spi_ozone.write(0); + ozone_SS.write(1); // Deselection de l'esclave + + chiffre = ((uint32_t)(Buff[0]) << 24) | ((uint32_t)(Buff[1]) << 16) | ((uint32_t)(Buff[2]) << 8) | (uint32_t)(Buff[3]); + chiffre = chiffre >> 7; + resultat = 100 - (chiffre/41943.040); // Conversion en %ADC + return resultat; +} + +#endif // Fin directive de compilation spi_ozone + +///////////////////////////////////////////////////////////////////////// +//// Tickers, Interruptions, Threads + +///////////////////////////////////////////////////////////////////////// +// GSM +#ifdef GSM_FUNCTION // Debut directive de compilation module GSM + +void f_ticker_check_gsm() { + // Fonction du ticker de surveillance du module GSM, lancée toute les .. s + + // Si module GSM absent, on retourne + if(flag_gsm_absent == 1) return; + + // Arret de toute les sources d'interruptions + all_irq_on_off(0, 2, 2, 2); + + // Si le module GSM est éteint, on l'allume + if(gsm_status == 0) gsm_pwr_on(); + + // Si module GSM non connecté + if(flag_gsm_network_ok == 0) { + // Si cela fait plus de 15 trames que l'on a démarré alors + if(hab_frame_counter - last_reset_gsm > 15) { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("\n Reset du module GSM ..."); + #endif + // todo : appui sur bouton reset du module gsm + last_reset_gsm = hab_frame_counter; + } } + + // met fin à l'envoi d'un sms, le module reste parfois bloqué dans la + // commande d'envoi et ne répond pas "OK" lorsqu'on check power en envoyant "AT" + gsm.gprsSerial.putc((char)0x1A); + + int sim_status = gsm.checkSIMStatus(); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("\n>>> Check statut SIM : %d\n", sim_status); + #endif + if(sim_status != 0) { init_GSM(); } // Il est nécessaire d'initialiser de nouveau le GSM + + // On autorise de nouveau les interruptions GPS et GSM, ticker HAB + all_irq_on_off(1, 2, 2, 2); + // Flag ticker GSM inactif + flag_ticker_check_gsm = 0; +} + +#endif // Fin directive de compilation module GSM + +///////////////////////////////////////////////////////////////////////// +// GPS +#ifdef GPS_FUNCTION // Debut directive de compilation module GPS +///////////////////////////////////////////////////////////////////////// + +// GPS = fonctions d'activation et de desactivation de l'interruption UART +void irq_gps_off() { + // IRQ OFF : desactivation de l'interruption pour le port UART du GPS + gps_serial.attach(NULL); +} +void irq_gps_on() { + // IRQ ON : activation de l'interruption pour le port UART du GPS + gps_serial.attach(&isr_gps_serial,Serial::RxIrq); +} + +// Routine d'interruption (ISR) pour la reception sur port UART du GPS +void isr_gps_serial() { + if(gps_serial.readable()) { + #ifdef GPS_DEBUG + char c = gps_serial.getc(); + serial_pc.putc(c); + gps.readCharacter(c); + #else + gps.readCharacter(gps_serial.getc()); + #endif + } +} + +#endif // Fin directive de compilation module GPS + +//////////////////////////////////////////////////////////////////////// +// SMS (GSM) +// Ticker executé toute les xx sec pour envoi des données par sms +#ifdef SMS_FUNCTION // Debut directive de compilation module SMS + +void f_ticker_sms_data() { + if(flag_gsm_network_ok == 1) { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf(">>>>>> Send HAB data to SMS\n"); + #endif + // Portable personnel de Dufaza + gsm.sendSMS(GSM_SEND_NUMBER, sd_gprs_data); + // Le SMS a ete envoyé ... + flag_ticker_sms_data = 0; +} } + +#endif // Fin directive de compilation module SMS + +//////////////////////////////////////////////////////////////////////// +// HAB +// Ticker executé toute les 5 s pour recolter toute les données, +// les enregistrer sur la carte SD et les envoyer en UART à la carte LoRa +#ifdef HAB_FUNCTION // Debut directive de compilation module HAB + +void f_ticker_hab() { + //DS18 thermomètre pt1 (en 2 parties pour eviter d'attendre) + #ifdef DS18_FUNCTION // Debut directive de compilation DS181B20 + // todo + #endif // Fin directive de compilation DS181B20 + + // Recuperation donnees capteurs ST X_NUCLEO_IKS01A2 + #ifdef XNUCLEO_FUNCTION // Debut directive de compilation shield capteurs XNUCLEO + hum_temp->get_temperature(&xnuc_t); + hum_temp->get_humidity(&xnuc_h); + press_temp->get_temperature(&xnuc_t2); + press_temp->get_pressure(&xnuc_p); + #endif // Fin directive de compilation shield capteurs XNUCLEO + + //PT100 + #ifdef PT100_FUNCTION // Debut directive de compilation module PT100 + PT100.read_all(); + if(PT100.status() == 0) { + tempPT100 = PT100.temperature(); + #ifdef DEBUG_SERIAL_PC + //serial_pc.printf(">>>>>> Temp PT100 = %f degC \r\n",tempPT100); + #endif + } + else { + tempPT100 = 0; + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("<<< ERREUR >>> Registre d'erreur PT100 : %d - ",PT100.status( )); + if(PT100.status() & MAX31865_FAULT_HIGH_THRESHOLD) { + serial_pc.printf("ERREUR PT100 seuil haut franchi\n"); + } + else if(PT100.status() & MAX31865_FAULT_LOW_THRESHOLD) { + serial_pc.printf("ERREUR PT100 seuil bas franchi\n"); + } + else if(PT100.status() & MAX31865_FAULT_REFIN) { + serial_pc.printf("ERREUR REFIN- > 0,85 x V_BIAS\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_REFIN_FORCE) { + serial_pc.printf("ERREUR REFIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_RTDIN_FORCE ) { + serial_pc.printf("ERREUR RTDIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_VOLTAGE) { + serial_pc.printf("ERREUR sur/sous-tension\n"); + } + else serial_pc.printf("ERREUR inconnue\n"); + #endif + } + #endif // Fin directive de compilation module PT100 + + // CO2 + #ifdef CO2_FUNCTION // Debut directive de compilation module CO2 + co2.IAQmeasure(); + #ifdef DEBUG_SERIAL_PC + /*serial_pc.printf("TVOC : %d\n", co2.TVOC); + serial_pc.printf("eCO2: %d\n", co2.eCO2);*/ + #endif + eco2 = co2.eCO2; + tvoc = co2.TVOC; + #endif // Fin directive de compilation module CO2 + + //DS18 thermomètre pt2 (en 2 parties pour eviter d'attendre) + #ifdef DS18_FUNCTION // Debut directive de compilation DS181B20 + // todo + #endif // Fin directive de compilation DS181B20 + + // Capteurs UV et lumiere + #ifdef UV_FUNCTION // Debut directive de compilation capteur UV + uv = pin_UV.read(); + #endif // Fin directive de compilation capteur UV + #ifdef PHOTORES_FUNCTION // Debut directive de compilation capteur lumière + photores = pin_photores.read(); + #endif // Fin directive de compilation capteur lumière + + // Triple capteur Bosch BME280 + #ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + bosch_t = bosch.getTemperature(); + //bosch_p = bosch.getPressure(); + bosch_p = 900.0 ; + + bosch_h = bosch.getHumidity(); + #ifdef DEBUG_SERIAL_PC + //serial_pc.printf("-> Bosch : %.2f *C, %.2f mbar, %.2f %%\n", bosch.getTemperature(), bosch.getPressure(), bosch.getHumidity()); + #endif + #endif // Fin directive de compilation Bosch + + // Ozone + #ifdef O3_FUNCTION // Debut directive de compilation spi_ozone + ozone = lecture_ozone(); + #endif // Fin directive de compilation spi_ozone + + // Mesure tension batterie (tension ref* pont diviseur + chute diode) + vbatt = ((double) pin_vbatt.read())*3.3*11.07+0.52; + + // Recuperation données GPS + #ifdef GPS_FUNCTION // Debut directive de compilation module GPS + gps.getTimestamp(timeUTCBuffer); + gps.getLatitude(latBuffer); + gps.getLongitude(lonBuffer); + gps.getAltitude(altBuffer); + gps.getSpeed(speedBuffer); + //printf("UTC: %s\t Latitude: %s\t Longitude: %s\t altitude: %s\t speed: %s\n", timeUTCBuffer, latBuffer, lonBuffer, altBuffer, speedBuffer); + // Convertion des chaine en entier et flottant + timeUTC = atoi(timeUTCBuffer); + lat = (float)atof(latBuffer); + lon = (float)atof(lonBuffer); + alt = (float)atof(altBuffer); + speed = (float)atof(speedBuffer); + #endif // Fin directive de compilation module GPS + + // Mise en forme dans un tableau de caractères + sprintf((char*) sd_gprs_data, "%d-%.2f-%d-%f-%f-%.1f-%.1f-%.1f-%.1f-%.3f-%.3f-%.3f-%.1f-%.3f-%.2f-%.2f-%d-%d-%f-%.3f-%.3f", + hab_frame_counter, vbatt, timeUTC, lat, lon, alt, speed, + xnuc_t, xnuc_t2, tempPT100, tempDS18, bosch_t, xnuc_h, bosch_h, xnuc_p, bosch_p, eco2, tvoc, ozone, (double)uv*100.0, (double)photores*100.0); + + #ifdef DEBUG_SERIAL_PC + // Affichage des données sur port série debug + serial_pc.printf("\n>>> HAB Frame Counter : %d\n", hab_frame_counter); + serial_pc.printf("> Tension batterie : %f V\n", vbatt); + #ifdef GPS_FUNCTION // Debut directive de compilation module GPS + serial_pc.printf("> Temps UTC : %d\n", timeUTC); + serial_pc.printf("> Latitude : %f\n", lat); + serial_pc.printf("> Longitude : %f\n", lon); + serial_pc.printf("> Altitude : %.2f m\n", alt); + serial_pc.printf("> Vitesse : %.2f km/h\n", speed); + #endif // Fin directive de compilation module GPS + + #ifdef XNUCLEO_FUNCTION // Debut directive de compilation shield capteurs XNUCLEO + serial_pc.printf("> Temperature 1 (XNUCLEO) : %.3f *C\n", xnuc_t); + serial_pc.printf("> Temperature 2 (XNUCLEO) : %.3f *C\n", xnuc_t2); + #endif // Fin directive de compilation shield capteurs XNUCLEO + + #ifdef PT100_FUNCTION // Debut directive de compilation module PT100 + serial_pc.printf("> Temperature 3 (PT100) : %.3f *C\n", tempPT100); + #endif // Fin directive de compilation module PT100 + + #ifdef DS18_FUNCTION // Debut directive de compilation DS181B20 + serial_pc.printf("> Temperature 4 (DS18) : %.3f *C\n", tempDS18); + #endif // Fin directive de compilation DS181B20 + + #ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + serial_pc.printf("> Temperature 5 (Bosch) : %.3f *C\n",bosch_t); + #endif // Fin directive de compilation Bosch + + #ifdef XNUCLEO_FUNCTION // Debut directive de compilation shield capteurs XNUCLEO + serial_pc.printf("> Humidite 1 (XNUCLEO) : %.2f %%\n", xnuc_h); + #endif // Fin directive de compilation shield capteurs XNUCLEO + + #ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + serial_pc.printf("> Humidite 2 (Bosch) : %.2f %%\n",bosch_h); + #endif // Fin directive de compilation Bosch + + #ifdef XNUCLEO_FUNCTION // Debut directive de compilation shield capteurs XNUCLEO + serial_pc.printf("> Pression 1 (XNUCLEO) : %.2f mbar - altitude calculee : %.2f m\n", xnuc_p, altitude(xnuc_p, BASE_PRESSURE)); + #endif // Fin directive de compilation shield capteurs XNUCLEO + + #ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + serial_pc.printf("> Pression 2 (Bosch) : %.2f mbar - altitude calculee : %.2f m\n",bosch_p, altitude(bosch_p, BASE_PRESSURE)); + #endif // Fin directive de compilation Bosch + + #ifdef CO2_FUNCTION // Debut directive de compilation module CO2 + serial_pc.printf("> eCO2 : %d ppm\n", eco2); + serial_pc.printf("> TVOC : %d ppb\n", tvoc); + #endif // Fin directive de compilation module CO2 + + #ifdef UV_FUNCTION // Debut directive de compilation capteur UV + serial_pc.printf("> UV : %.3f %%ADC\n", (double)uv*100.0); + #endif // Fin directive de compilation capteur UV + + #ifdef PHOTORES_FUNCTION // Debut directive de compilation capteur lumière + serial_pc.printf("> Lum : %.3f %%ADC\n", (double)photores*100.0); + #endif // Fin directive de compilation capteur lumière + + #ifdef O3_FUNCTION // Debut directive de compilation spi_ozone + serial_pc.printf("> Ozone O3 : %f %%ADC\n", ozone); + #endif // Fin directive de compilation spi_ozone + + serial_pc.printf("%s\n", sd_gprs_data); + #endif + + // Envoi de la chaine par GPRS au Polytech Server + #ifdef GSM_FUNCTION // Debut directive de compilation module GSM + #ifdef GPRS_FUNCTION // Debut directive de compilation données mobiles + if(flag_gsm_network_ok == 1) { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf(">>>>>> Send HAB data to Polytech Server\n"); + #endif + gsm.gprs_message(url_srv_polytech , sd_gprs_data); + } + #endif // Fin directive de compilation données mobiles + /*if(flag_gsm_network_ok == 1) { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("SMS : %d\n",gsm.sendSMS("+33676040268", sd_gprs_data)); // Envoi de la chaine par SMS + #endif + */ + #endif // Fin directive de compilation module GSM + + // Sauvegarde sur carte SD + #ifdef SD_FUNCTION // Debut directive de compilation carte SD + ecriture_sd(SD_FUNCTION_FILENAME, sd_gprs_data); + #endif // Fin directive de compilation carte SD + + // Creation de la chaine à envoyer à la carte LoRa + #ifdef LORA_FUNCTION // Debut directive de compilation LoRa + sprintf((char*) lora_data_tx, "%.2f-%f-%f-%.1f-%.3f", vbatt, lat, lon, alt, tempPT100); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("%s\n", lora_data_tx); + #endif + #endif // Fin directive de compilation LoRa + + #ifdef DEBUG_SERIAL_PC + //serial_pc.printf("------------------------------------------------\n"); + serial_pc.printf("\n"); + #endif + + // Increment du numéro de la trame transmise + hab_frame_counter++; + // Flag ticker HAB inactif + flag_ticker_hab = 0; +} + +#endif // Fin directive de compilation module HAB + +///////////////////////////////////////////////////////////////////////// +// Routines d'interruption appelées au tick des tickers et servant juste à lever un flag +// Pensez à abaisser le flag dans f_ticker_hab() et f_ticker_gsm() ! +#ifdef HAB_FUNCTION + void isr_ticker_hab() { flag_ticker_hab = 1; } +#endif + +#ifdef GSM_FUNCTION + void isr_ticker_check_gsm() { flag_ticker_check_gsm = 1; } +#endif + +#ifdef SMS_FUNCTION + void isr_ticker_sms_data() { flag_ticker_sms_data = 1; } +#endif + +///////////////////////////////////////////////////////////////////////// +// LoRa +#ifdef LORA_FUNCTION // Debut directive de compilation LoRa + +void envoi_lora_data_tx() { + lora_serial.printf("%s\n", lora_data_tx); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("lora!\n"); // debug + #endif +} + +void isr_lora_serial() { + char c = lora_serial.getc(); + if(c == 'a') envoi_lora_data_tx(); + #ifdef MP3_FUNCTION // Debut directive de compilation lecteur MP3 + elseif(c == 'b') mp3.mp3_play(); + elseif(c == 'c') mp3.mp3_pause(); + #endif // Fin directive de compilation lecteur MP3 + #ifdef BUZZ_FUNCTION // Debut directive de compilation buzzer + elseif(c == 'd') pin_buzzer.write(1); + elseif(c == 'e') pin_buzzer.write(0); + #endif // Fin directive de compilation buzzer +} + +#endif // Fin directive de compilation LoRa + + +///////////////////////////////////////////////////////////////////////// +///////////////////////////// MAIN //////////////////////////////////// +///////////////////////////////////////////////////////////////////////// + +int main() { + + // Affichage/listage des modules compilés/activés sur port série STLINK + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("\n\n-----------------------------------------------------------------------------------\n"); + serial_pc.printf("--- AMU Aix-Marseille Universit\xE9 - Polytech Marseille MT - STM32 in the Sky HAB ---\n"); + vbatt = ((double)pin_vbatt.read())*3.3*11.07+0.52; // Tension batterie (tension ref * pont diviseur + chute diode) + serial_pc.printf("- Tension batterie = %f V\n", vbatt); + serial_pc.printf("- Liste des Fonctionalit\xE9s & Capteurs op\xE9rationnels ...\n"); + #endif + + //Buzzer, léger bip au démarrage + #ifdef BUZZ_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> Buzzer ON ... "); + #endif + for(int i=1; i<BUZZ_FUNCTION_DURATION; i++) // #périodes de 1,5kHz + { // 333us x 2 = 1,5k Hz + pin_buzzer.write(1); wait_us(BUZZ_FUNCTION_HZ); + pin_buzzer.write(0); wait_us(BUZZ_FUNCTION_HZ); + }; + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("OFF\n"); + #endif + #endif + + // Shield ST X_NUCLEO_IKS01A2 + #ifdef XNUCLEO_FUNCTION + // Hum, Temp, Press, Temp, Accelero enable + hum_temp->enable(); + press_temp->enable(); + accelerometer->enable(); + // Lecture des capteurs + hum_temp->get_temperature(&xnuc_t); + hum_temp->get_humidity(&xnuc_h); + press_temp->get_temperature(&xnuc_t2); + press_temp->get_pressure(&xnuc_p); + accelerometer->get_x_axes(xnuc_acc); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> XNucleo = %.3f \xB0 C, %.3f \xB0 C, %.3f mbar, %.2f %%, ",xnuc_t, xnuc_t2, xnuc_p, xnuc_h); + serial_pc.printf("Acc x = %ld, y = %ld, z = %ld\n", xnuc_acc[0], xnuc_acc[1], xnuc_acc[2]); + #endif + #endif + + // GSM + #ifdef GSM_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> GSM ON "); + #endif + gsm_pwr_on(); + #endif + + // GPRS SMS + #ifdef GPRS_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("& GPRS ON\n"); + #endif + #endif + + #ifdef PT100_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> PT100 = "); + #endif + // Configuration initiale du MAX31865 + /* + 1: v_biais : Vbias (tension de polarisation) activée (true) ou non (false) + 2: conversion_mode : mode de conversion automatique activé (true) ou non (false) + 3: one_shot : mesure au coup par coup (true) ou en continue (false) + 4: three_wire : mesure 3 fils activée (true) ou 2/4 fils (false) + 5: fault_cycle : detection d'erreur (voir datasheet) activée (true) ou non (false) + 6: fault_clear : acquittement automatique des erreurs activée (true) ou non (false) + 7: filter_50hz : filtre 50 Hz activé (true) ou non (false) + 8: low_threshold : seuil d'erreur bas. (0x0000 = 0) + 9: high_threshold : seuil d'erreur haut. (0x7fff = 32767) + */ + PT100.configure(true, true, false, false, MAX31865_FAULT_DETECTION_NONE, true, true, 0x0000, 0x7fff); + PT100.read_all(); + #ifdef DEBUG_SERIAL_PC + if(PT100.status() == 0) { + //serial_pc.printf("PT100 OK Temp = %.3f *C\n",PT100.temperature()); + serial_pc.printf("PT100 OK\n"); + } + else { + serial_pc.printf("\n!!! Registre d'erreur PT100 = %d - ",PT100.status( )); + if(PT100.status() & MAX31865_FAULT_HIGH_THRESHOLD) { + serial_pc.printf("ERREUR PT100 seuil haut franchi\n"); + } + else if(PT100.status() & MAX31865_FAULT_LOW_THRESHOLD) { + serial_pc.printf("ERREUR PT100 seuil bas franchi\n"); + } + else if(PT100.status() & MAX31865_FAULT_REFIN) { + serial_pc.printf("ERREUR REFIN- > 0,85 x V_BIAS\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_REFIN_FORCE) { + serial_pc.printf("ERREUR REFIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_RTDIN_FORCE ) { + serial_pc.printf("ERREUR RTDIN- < 0,85 x V_BIAS, FORCE- ouvert\n"); + } + else if(PT100.status( ) & MAX31865_FAULT_VOLTAGE) { + serial_pc.printf("ERREUR sur/sous-tension\n"); + } + else serial_pc.printf("ERREUR inconnue\n"); + } + #endif + #endif + + // Carte SD, initialisation, et creation d'un fichier de test d'ecriture + // /!\ Faire cette étape après l'initialisation du capteur PT100 qui partage le même SPI + #ifdef SD_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> SD = "); + #endif + //mkdir("/sd/TEST", 0777); + FILE *fp = fopen(SD_FUNCTION_TESTFILENAME, "w"); + if(fp == NULL) { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("ERREUR - Ecriture carte SD\n"); + #endif + // Desactivation de la sauvegarde sur carte SD + flag_sd_ok = 0; + } + else { + fprintf(fp, "AMU - Polytech Marseille - HAB STM32 in the Sky - Test ecriture SD"); + fclose(fp); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("Ecriture carte SD - ok\n"); + #endif + //Activation de la sauvegarde sur carte SD + flag_sd_ok = 1; + } + #endif + + // CO2 + #ifdef CO2_FUNCTION + co2.begin(); + co2.IAQmeasure(); + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> CO2 = TVOC = %d, eCO2 = %d\n", co2.TVOC, co2.eCO2); + #endif + #endif + + //DS18 thermomètre + #ifdef DS18_FUNCTION // Debut directive de compilation DS181B20 + + if (ds18.begin()) { + while (1) { + ds18.startConversion(); // start temperature conversion from analog to digital + wait(1.0); // let DS1820 complete the temperature conversion + result = ds18.read(tempDS18); // read temperature from DS1820 and perform cyclic redundancy check (CRC) + switch (result) { + case 0: // no errors -> 'tempDS18' contains the value of measured temperature + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("temp = %3.1f%cC\r\n", tempDS18, 176); + #endif + break; + case 1: // no sensor present -> 'tempDS18' is not updated + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("no sensor present\n\r"); + #endif + break; + case 2: // CRC error -> 'tempDS18' is not updated + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("CRC error\r\n"); + #endif + } + } + } + else + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("No DS1820 sensor found!\r\n"); + #endif + + #endif // Fin directive de compilation DS181B20 + + //UV + #ifdef UV_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> UV = %.3f %%ADC\n",pin_UV.read()); + #endif + #endif + + //Photoresistance + #ifdef PHOTORES_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> Photoresistance = %.3f %%ADC\n",(double)pin_photores.read()*100.0); + #endif + #endif + + // Triple capteur Bosch BME280 + #ifdef BOSCH_FUNCTION // Debut directive de compilation Bosch + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> Bosch = %.2f *C, %.2f mbar, %.2f %%\n", bosch.getTemperature(), bosch.getPressure(), bosch.getHumidity()); + #endif + #endif // Fin directive de compilation Bosch + + // Lecteur MP3 + // Creer un fichier 0.mp3 à la racine de la carte SD + #ifdef MP3_FUNCTION // Debut directive de compilation lecteur MP3 + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> MP3 ON\n"); + #endif + mp3.mp3_reset(); + wait(1); + mp3.mp3_set_EQ(0); + wait(0.5); + mp3.mp3_set_volume(20); + wait(0.5); + mp3.mp3_set_device(2); // 1,2,3,4,5 : USB,SD,AUX,SLEEP,FLASH + wait(0.5); + mp3.mp3_single_loop(0); + //mp3.mp3_single_play(0) ; + wait(0.5); + //serial_pc.printf("We are in the MP3 func !!!!!\n\r"); + mp3.mp3_play(); + #endif // Fin directive de compilation MP3 + + #ifdef LORA_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> LoRa ON\n"); + #endif + #endif + + #ifdef GPS_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> GPS ON\n"); + #endif + #endif + + #ifdef O3_FUNCTION + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("-> Ozone O3 = %f %%ADC\n", lecture_ozone()); + #endif + #endif + + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("\n"); + #endif + + ////// Lancement des ticker et des interruptions //////// + + // GPS + // Mise en place de l'interruption pour le port UART du GPS + #ifdef GPS_FUNCTION // Debut directive de compilation module GPS + gps_serial.attach(&isr_gps_serial,Serial::RxIrq); + #endif // Fin directive de compilation module GPS + + // Ticker de creation de la chaine de données toute les 5s + ticker_hab.attach(&isr_ticker_hab, TICKER_HAB_TIME); + + // GSM + #ifdef GSM_FUNCTION // Debut directive de compilation module GSM + if(flag_gsm_absent == 0) { + + // Interruption sur LED "NET" et compteur de sa période + timer_gsm_network.reset(); // Démarrage du compteur de la période de clignotement de la LED "NET" + timer_gsm_network.start(); + gsm_net.rise(&isr_network_gsm); // Attachement de l'interruption externe sur la LED "NET" + + // Ticker de surveillance GSM toute les xx sec + ticker_check_gsm.attach(&isr_ticker_check_gsm, TICKER_CHECK_GSM_TIME); + + // Ticker d'envoi de données par sms toute les xx sec + #ifdef SMS_FUNCTION // Debut directive de compilation envoi SMS + ticker_sms_data.attach(&isr_ticker_sms_data, TICKER_SMS_DATA_TIME); + #endif // Fin directive de compilation SMS de données toutes les xx sec + } + #endif // Fin directive de compilation module GSM + + // LoRa + // Mise en place de l'interruption pour le port UART LoRa + #ifdef LORA_FUNCTION // Debut directive de compilation LoRa + lora_serial.attach(&isr_lora_serial,Serial::RxIrq); + #endif // Fin directive de compilation LoRa + + /////////////////// BOUCLE PRINCIPALE ///////////////// + while(1) { + + // Vérification du flag d'interruption pour la routine de recuperation + // des données des capteurs, enregistrement, envoi LoRa, etc. + #ifdef HAB_FUNCTION + if(flag_ticker_hab == 1) f_ticker_hab(); + #endif + + // Vérification du flag d'interruption pour la routine de vérification + // de l'état du module + #ifdef GSM_FUNCTION // Debut directive de compilation module GSM + if(flag_ticker_check_gsm == 1) + { if ( (altitude(xnuc_p, BASE_PRESSURE) < GSM_START_ALTITUDE ) || (altitude(bosch_p, BASE_PRESSURE) < GSM_START_ALTITUDE) ) + { + #ifdef DEBUG_SERIAL_PC + serial_pc.printf("> Pression 1 (XNUCLEO) : %.2f mbar - altitude GSM : %.2f m\n", xnuc_p, altitude(xnuc_p, BASE_PRESSURE)); + serial_pc.printf("> Pression 1 (BOSCH) : %.2f mbar - altitude GSM : %.2f m\n", bosch_p, altitude(bosch_p, BASE_PRESSURE)); + #endif + f_ticker_check_gsm(); + } + } + #endif // Fin directive de compilation module GSM + + // Vérification du flag d'interruption pour la routine d'envoi de SMS + // de donnée toute les 10 min + #ifdef SMS_FUNCTION // Debut directive de compilation SMS de données toutes les 10 min + if(flag_ticker_sms_data == 1) f_ticker_sms_data(); + #endif // Fin directive de compilation SMS de données toutes les 10 min + } +}