S05APP2: Noyau temps réel

Dependencies:   mbed mbed-rtos

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