gfdh

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
RufflesAllD
Date:
2014-01-28
Revision:
3:350e3a76ff72
Parent:
2:6009cb96f273

File content as of revision 3:350e3a76ff72:

#include "mbed.h"
#include "rtos.h"

DigitalIn en_1(p15);
DigitalIn en_2(p16);

AnalogIn ea_1(p19);
AnalogIn ea_2(p20);

Serial pc(USBTX, USBRX);

Mutex event_mutex;

struct Event {
    char *def;
    time_t time;
    
    Event (char *d, time_t t): def(d), time(t){}
};

Queue<Event, 16> queue;

void put(char *def, time_t time)
{
    event_mutex.lock();
    queue.put(new Event(def, time));
    event_mutex.unlock();
}

void showTime(char *buffer, time_t time)
{
    strftime(buffer, 22, "%Y-%m-%d %H:%M:%S\n\r", localtime(&time));
}

unsigned short moyenne(unsigned short* mean_values)
{
    unsigned int mean = 0;

    for (int i = 0; i < 5; i++) {
        mean += mean_values[i];
    }

    return mean/5;
}

void lecture_analog(void const *args)
{
    unsigned short values_ea_1[5] = {0};
    unsigned short values_ea_2[5] = {0};

    const unsigned short valeur_ecart = 0x1FFF; // le huitième de 0xFFFF

    int init_mean = 0;

    int compteur = 0;

    while (true) {
        // synchronisation sur la période d'échantillonnage
        Thread::signal_wait(0x2);

        if (init_mean < 5) {
            values_ea_1[init_mean] = ea_1.read_u16();
            values_ea_2[init_mean] = ea_2.read_u16();
            init_mean++;
        } else {
            // lecture de l'étampe temporelle
            time_t t = time(NULL);

            // lecture des échantillons analogiques
            unsigned short value_ea_1 = ea_1.read_u16();
            unsigned short value_ea_2 = ea_2.read_u16();

            // calcul de la nouvelle moyenne courante
            unsigned short mean_value_ea_1 = moyenne(values_ea_1);
            unsigned short mean_value_ea_2 = moyenne(values_ea_2);

            // génération éventuelle d'un événement
            if (abs(value_ea_1 - mean_value_ea_1) > valeur_ecart) {
                put("analog1", t);
            }
            if (abs(value_ea_2 - mean_value_ea_2) > valeur_ecart) {
                put("analog2", t);
            }

            values_ea_1[compteur] = value_ea_1;
            values_ea_2[compteur] = value_ea_2;

            compteur = (compteur+1) % 5;
        }
    }
}

void timer250ms(void const *thread)
{
    Thread *t = (Thread*)thread;
    t->signal_set(0x02);
}

void lecture_num(void const *args)
{
    int state1 = en_1;
    int state2 = en_2;
    bool stateChanged[2] = {false, false};

    while (true) {
        // synchronisation sur la période d'échantillonnage
        Thread::signal_wait(0x1);

        // lecture de l'étampe temporelle
        time_t t = time(NULL);

        // lecture des échantillons numériques
        stateChanged[0] = (state1 != en_1);
        stateChanged[1] = (state2 != en_2);

        // prise en charge du phénomène de rebond
        // génération éventuelle d'un événement
        if (stateChanged[0] || stateChanged[1]) {
            wait(0.05);
            if (state1 != en_1 && stateChanged[0]) {
                put("digital1", t);
                state1 = en_1;
            }
            if (state2 != en_2 && stateChanged[1]) {
                put("digital2", t);
                state2 = en_2;
            }

            stateChanged[0] = false;
            stateChanged[1] = false;
        }
    }
}

void timer100ms(void const *thread)
{
    Thread *t = (Thread*)thread;
    t->signal_set(0x01);
}

void collection(void const *args)
{
    while (true) {
        // attente et lecture d'un événement
        osEvent evt = queue.get();

        // écriture de l'événement en sortie (port série)
        if (evt.status == osEventMessage) {
            Event *ev = (Event*)evt.value.p;

            char buffer[22];
            showTime(buffer, ev->time);

            pc.printf("%s: %s", ev->def, buffer);
            
            delete ev;
        }
    }
}

int main()
{
    // initialisation du RTC
    set_time(1390820561); //2014-01-27 11:02:41

    // démarrage des tâches
    Thread thread1(lecture_num);
    RtosTimer timer_num(timer100ms, osTimerPeriodic, (void*)&thread1);
    timer_num.start(100);

    Thread thread2(lecture_analog);
    RtosTimer timer_analog(timer250ms, osTimerPeriodic, (void*)&thread2);
    timer_analog.start(250);

    Thread thread3(collection);

    while(true) {}
}