gfdh

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
joGenie
Date:
2014-01-28
Revision:
4:6a242f5bc7fa
Parent:
2:6009cb96f273

File content as of revision 4:6a242f5bc7fa:

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

// Digital in
DigitalIn en_1(p15);
DigitalIn en_2(p16);

// Analog in
AnalogIn ea_1(p19);
AnalogIn ea_2(p20);

// Serial port usb
Serial pc(USBTX, USBRX);

// Mutex
Mutex event_mutex;

/**
    Event definition
*/
struct Event
{
    char *def; //! Description of event
    time_t time; //! Timestamps
};

// List FIFO of events
Queue<Event, 16> queue;

/** Put event in a queue
*
*   @param ev Event to put
*/
void put(Event *ev)
{
    event_mutex.lock();
    queue.put(ev);
    delete ev;
    event_mutex.unlock();
}

void showTime(char *buffer, time_t time)
{
    strftime(buffer, 32, "%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
        {
            Event *ev = new Event;
            
            // lecture de l'étampe temporelle
            ev->time = 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)
            {
                ev->def = "analog1";
                put(ev);
            }
            if (abs(value_ea_2 - mean_value_ea_2) > valeur_ecart)
            {
                ev->def = "analog2";
                put(ev);
            }
            
            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);
        
        Event *ev = new Event;
        
        // lecture de l'étampe temporelle
        ev->time = 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])
            {
                ev->def = "digital1";
                put(ev);
                state1 = en_1;
            }
            if (state2 != en_2 && stateChanged[1])
            {
                ev->def = "digital2";
                put(ev);
                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 = new char;
            showTime(buffer, ev->time);
            
            pc.printf("%s: %s", ev->def, buffer);
        }
    }
}

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