g

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
ShaolinPoutine
Date:
2017-01-31
Revision:
2:2d84e5bf72bd
Parent:
1:8475f46f050b

File content as of revision 2:2d84e5bf72bd:

#include "rtos.h"
DigitalIn* en_1 = new DigitalIn(p15, PullUp);
DigitalIn* en_2 = new DigitalIn(p16, PullUp);
AnalogIn* ea_1 = new AnalogIn(p19);
AnalogIn* ea_2 = new AnalogIn(p20);

short signal100ms = 0x1 << 5;
short signal50ms = 0x1 << 4;
short signal250ms = 0x1 << 3;
bool new_numeric = true;

short typeAnalog = 0;
short typeNumeric = 1;
time_t begin_time = 0;

MemoryPool<short, 16> *analogpool = NULL;
MemoryPool<short, 16> *numericpool = NULL;

Thread* panalog_thread = NULL;
Thread* pnumeric_thread = NULL;


typedef struct
{
    bool analog;               // Which type of event
    short id;                 // Which pins changed
    short* position;          // Position in the memory pool
    time_t seconds;  // Timestamp when the event occured
} reading;

Queue<reading, 16> *queue = NULL;

void SendMessage(time_t seconds, bool analog, short id, short state)
{
    reading *message = NULL;
    message = new reading();
    // type analog == true
    if(analog)
        message->position = analogpool->alloc();
    else
        message->position = numericpool->alloc();
    
    *message->position = state;
    message->analog = analog;
    message->id = id;
    message->seconds = seconds;
    queue->put(message);
}

void lecture_analog(void const *args) {
    int state[] = {0,0};
    int newstate[2] = {0,0};
    int mean1[5] = {0,0,0,0,0};
    int mean2[5] = {0,0,0,0,0};
    short i = 0;
    while (true) {
        // synchronisation sur la période d'échantillonnage
        Thread::signal_wait(signal250ms);
        // lecture de l'étampe temporelle
        // lecture des échantillons analogiques
        mean1[i] = ea_1->read()*3300;
        mean2[i] = ea_2->read()*3300;
        // calcul de la nouvelle moyenne courante
        newstate[0] = (mean1[0] + mean1[1] + mean1[2] + mean1[3] + mean1[4]) / 5;
        newstate[1] = (mean2[0] + mean2[1] + mean2[2] + mean2[3] + mean2[4]) / 5;
        // génération éventuelle d'un événement
        if (abs(newstate[0] - state[0]) > 413)
        {
           state[0] = newstate[0];
           SendMessage(begin_time,true,1,(short) state[0]);
        }
        if (abs(newstate[1] - state[1]) > 413)
        {
           state[1] = newstate[1];
           SendMessage(begin_time,true,2,(short) state[1]);
        }
        i = (i + 1) % 5;
        Thread::yield();
    }
}

void lecture_num(void const *args) {
    bool state[2] = {false, false};
    bool newstate[2] = {false, false};
    bool changed[2] = {false, false};
    while (true) {
        // synchronisation sur la période d'échantillonnage
        //numeric_thread.signal_clr(signal100ms);
        Thread::signal_wait(signal100ms);
        
        // lecture de l'étampe temporelle
        
        // lecture des échantillons numériques
        newstate[0] = !(en_1->read());
        newstate[1] = !(en_2->read());
        
        // prise en charge du phénomène de rebond
        changed[0] = newstate[0] != state[0];
        changed[1] = newstate[1] != state[1];
        
        if (changed[0] || changed [1])
        {
            pnumeric_thread->signal_clr(signal50ms);
            //flag isp
            Thread::signal_wait(signal50ms);
            
            newstate[0] = !(en_1->read());
            newstate[1] = !(en_2->read());
            if(newstate[0] != state[0] && changed[0])
            {
               state[0] = newstate[0];
               SendMessage(begin_time,false,1,state[0]);
            }
            if(newstate[1] != state[1] && changed[1])
            {
               state[1] = newstate[1];
               SendMessage(begin_time,false,2,state[1]);
            }
        }
        else
        {
            Thread::yield();   
        }
    }
}

void collection(void const *args) {
    osEvent event;
    reading* message;
    while (true) {
        
        // attente et lecture d'un événement
        event = queue->get();
        message = (reading*) event.value.p;
        short sec, min, heure, jour;
        sec = (short) message->seconds % 60;
        min = (short) (message->seconds / 60) % 60;
        heure = (short) (message->seconds / 3600) % 24;
        jour = (short) message->seconds / 86400;
        if (!message->analog)
        {
            // écriture de l'événement en sortie (port série)
            printf("N%d is %d at %02dj %02d:%02d:%02d\r\n", message->id, *message->position, jour, heure, min, sec);
            numericpool->free(message->position);
        }
        else
        {
            // écriture de l'événement en sortie (port série)
            printf("A%d is %dmV at %02dj %02d:%02d:%02d\r\n", message->id, *message->position, jour, heure, min, sec);
            analogpool->free(message->position);
        }
        delete message;
    }
}

void signalnumeric()
{
    if (new_numeric)
    {
        new_numeric = !new_numeric;
        begin_time = time(NULL);
        pnumeric_thread->signal_set(signal100ms);
    }
    else
        pnumeric_thread->signal_set(signal100ms | signal50ms);
}

void signalanalog()
{
    begin_time = time(NULL);
    panalog_thread->signal_set(signal250ms);
}

int main(){
    //initialisation des variables
    MemoryPool<short, 16> apool;
    analogpool = &apool;
    MemoryPool<short, 16> npool;
    numericpool = &npool;
    Queue<reading, 16> onequeue;
    queue = &onequeue;

    // initialisation du RTC
    Ticker analogtimer;
    Ticker numerictimer;
    analogtimer.attach(&signalanalog, 0.250);
    numerictimer.attach(&signalnumeric, 0.05);
    
    // démarrage des tâches
    Thread analog_thread(lecture_analog);
    panalog_thread = &analog_thread;
    Thread num_thread(lecture_num);
    pnumeric_thread = &num_thread;
    Thread q(collection);
    while(1){
    }
}