
S05APP2: Noyau temps réel
main.cpp
- Committer:
- benjaminroy
- Date:
- 2017-01-31
- Revision:
- 26:faaca34daf91
- Parent:
- 25:9428c29c50dc
File content as of revision 26:faaca34daf91:
#include "AnalogIn.h" #include "DigitalIn.h" #include "Ticker.h" #include "Serial.h" #include "rtos.h" #define seuil 0.125 Serial pc(USBTX, USBRX); // tx, rx Ticker ticker; DigitalIn en_1(p15); DigitalIn en_2(p16); AnalogIn ea_1(p19); AnalogIn ea_2(p20); Thread *t1; Thread *t2; Mutex mutex; uint8_t compteur = 0; bool verifierSiStable = false; /* Mail */ typedef struct { char* temps; // Étampe indiquant l’heure et la date de l'occurrence uint8_t broche; // Le numéro de la broche float valeur; } mail_t; Mail<mail_t, 4> mail_box; // ------------------------------------------------------- // ------------------------------------------------------- void envoyer_mail(uint8_t broche, float valeur) { mutex.lock(); time_t secondes = time(NULL); mutex.unlock(); mail_t *mail = mail_box.alloc(); mail->temps = ctime(&secondes); mail->broche = broche; mail->valeur = valeur; mail_box.put(mail); } void lecture_analog(void const *args) { uint8_t i = 0; float moyenne_passee[2] = {-1, -1}; float moyenne_courante[2] = {0}; float echantillons[2][5]; while (true) { /*** Synchronisation sur la période d'échantillonnage ***/ Thread::signal_wait(0x1); /*** Lecture des échantillons analogiques ***/ echantillons[0][i] = ea_1.read(); echantillons[1][i] = ea_2.read(); i++; if (i == 5) { /*** Calcul de la moyenne courante du signal (calculée sur 5 échantillons successifs) ***/ moyenne_courante[0] = (echantillons[0][0] + echantillons[0][1] + echantillons[0][2] + echantillons[0][3] + echantillons[0][4]) / 5; moyenne_courante[1] = (echantillons[1][0] + echantillons[1][1] + echantillons[1][2] + echantillons[1][3] + echantillons[1][4]) / 5; if (moyenne_passee[0] != -1) { if (((moyenne_courante[0] < moyenne_passee[0]) && (1 - (moyenne_courante[0] / moyenne_passee[0]) > seuil)) || (1 - (moyenne_passee[0] / moyenne_courante[0]) > seuil)) { envoyer_mail(19, moyenne_courante[0]); /*** Génération éventuelle d'un événement ***/ } } if (moyenne_passee[1] != -1) { if (((moyenne_courante[1] < moyenne_passee[1]) && (1 - (moyenne_courante[1] / moyenne_passee[1]) > seuil)) || (1 - (moyenne_passee[1] / moyenne_courante[1]) > seuil)) { envoyer_mail(20, moyenne_courante[1]); /*** Génération éventuelle d'un événement ***/ } } moyenne_passee[0] = moyenne_courante[0]; moyenne_passee[1] = moyenne_courante[1]; i = 0; } } } void lecture_num(void const *args) { bool valeurs[2] = {0}; bool entreenum[2] = {0}; while (true) { /*** Synchronisation sur la période d'échantillonnage ***/ Thread::signal_wait(0x1); /*** Lecture des échantillons numériques ***/ entreenum[0] = en_1.read(); entreenum[1] = en_2.read(); /*** Prise en charge du phénomène de rebond ***/ if (entreenum[0] != valeurs[0]) { verifierSiStable = true; Thread::signal_wait(0x2); valeurs[0] = entreenum[0]; if (entreenum[0] == en_1.read()) { envoyer_mail(15, entreenum[0]); /*** Génération d'un évènement... ***/ } } if (entreenum[1] != valeurs[1]) { verifierSiStable = true; Thread::signal_wait(0x2); valeurs[1] = entreenum[1]; if (entreenum[1] == en_2.read()) { envoyer_mail(16, entreenum[1]); /*** Génération d'un évènement... ***/ } } Thread::yield(); } } void collection(void const *args) { while (true) { /*** Attente et lecture d'un événement ***/ osEvent evt = mail_box.get(); if (evt.status == osEventMail) { mail_t *mail = (mail_t*)evt.value.p; /*** Écriture de l'événement en sortie (port série) ***/ pc.printf("Broche %d; Valeur: %f; Date: %s\n", mail->broche, mail->valeur, mail->temps); mail_box.free(mail); } } } void alarm() { compteur++; if (verifierSiStable) { t1->signal_set(0x2); verifierSiStable = false; } if (compteur % 2 == 0) { // Entrées numériques échantillionnées à tous les 100 ms t1->signal_set(0x1); } if (compteur % 5 == 0) { // Entrées analogiques échantillonnées à tous les 250 ms t2->signal_set(0x1); } if (compteur % 10 == 0) { compteur = 0; } } int main() { /*** Démarrage des tâches ***/ Thread t_lectureNum(lecture_num); Thread t_lectureAnalog(lecture_analog); Thread t_collection(collection); t1 = &t_lectureNum; t2 = &t_lectureAnalog; /*** Initialisation du RTC ***/ set_time(1485514920); // Set RTC time to... ticker.attach(&alarm, 0.05); while(1); }