asd
Dependencies: mbed-rtos mbed RTC
main.cpp
- Committer:
- manl2003
- Date:
- 2016-01-29
- Revision:
- 3:1c077a1de3e5
- Parent:
- 2:ebbca46b415f
File content as of revision 3:1c077a1de3e5:
//Laurent et Laurent //manl2003 huol2102 #include "mbed.h" #include "rtos.h" #include "RTC.h" //Pins DigitalIn en_1(p27); DigitalIn en_2(p28); AnalogIn ea_1(p19); AnalogIn ea_2(p20); RawSerial pc(USBTX,USBRX); //Mutex Mutex mute; //Compteurs int tic_count = 0; int tic_count_num1 = 0; int FREQ_NUM_MS = 100; int FREQ_ANAL_MS = 250; //Constantes #define FREQ_NUM_STAB_MS 50 #define SIGNAL_NUM 0x1 #define SIGNAL_ANALOG 0x2 #define SEUIL_ANAL 0xB999 //Timers RtosTimer *ticker_num1 = NULL; RtosTimer *ticker_num2 = NULL; RtosTimer *ticker_analog1 = NULL; RtosTimer *ticker_analog2 = NULL; struct MailData { //Structure permettant d'encapsuler toutes les données nécessaires à l'affichage void FillData(int _eventType, time_t _seconds) { eventType = _eventType; seconds = _seconds; } int eventType; time_t seconds; void print() { char buffer[32]; strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds)); switch(eventType) { case 0: pc.printf("Evenement detecte sur le premier canal numerique a %s.\r\n", buffer); break; case 1: pc.printf("Evenement detecte sur le deuxieme canal numerique a %s.\r\n", buffer); break; case 2: pc.printf("Evenement detecte sur le premier canal analogique a %s.\r\n", buffer); break; case 3: pc.printf("Evenement detecte sur le deuxieme canal analogique a %s.\r\n", buffer); break; } } }; //Mailbox Mail<MailData, 16> mailBox; struct num_args { //Structure permettant d'encapsuler toutes les arguments pour un événement numérique num_args(DigitalIn *in_arg, int type_arg) { in = in_arg; type = type_arg; } int type; DigitalIn *in; }; struct analog_args { //Structure permettant d'encapsuler toutes les arguments pour un événement analogique analog_args(AnalogIn *in_arg, int type_arg){ in = in_arg; type = type_arg; } int type; AnalogIn* in; }; void collection(void const *args) { //Thread collecteur while (1) { // attente et lecture d'un événement osEvent evt = mailBox.get(); if (evt.status == osEventMail) { mute.lock(); // écriture de l'événement en sortie (port série) MailData *mail = (MailData*)evt.value.p; mail->print(); mailBox.free(mail); mute.unlock(); } } } void lecture_analog(void const *args) { //Lecture des événements analogues analog_args *analArgs = (analog_args*)args; bool premiereLectureDispo = false, deuxMoyennesPretes = false; uint16_t echantillonsAnal[5] = {0, 0, 0, 0, 0}; int compteur = 0; int moyenneCourante = 0, moyennePrecedente = 0; while(1) { Thread::signal_wait(SIGNAL_ANALOG); // lecture des échantillons analogiques echantillonsAnal[compteur] = analArgs->in->read_u16(); // calcul de la nouvelle moyenne courante if(premiereLectureDispo == true) { moyennePrecedente = moyenneCourante; moyenneCourante = 0; for(int i = 0; i < 5; i++) { moyenneCourante += echantillonsAnal[i]; } } compteur++; if(compteur >= 5) { compteur = 0; premiereLectureDispo = true; } // génération éventuelle d'un événement if(!deuxMoyennesPretes) { deuxMoyennesPretes = true; } else if(abs(moyenneCourante - moyennePrecedente) > SEUIL_ANAL) { //On écrit dans la mailbox lorsqu'une variation excède le seuil mute.lock(); MailData * mailData = mailBox.alloc(); mailData->FillData(analArgs->type, time(NULL)); mailBox.put(mailData); mute.unlock(); } } } void lecture_num(void const *args) { // lecture des échantillons numériques num_args *numArgs = (num_args*)args; bool lectureDebut; while (1) { Thread::signal_wait(SIGNAL_NUM); lectureDebut = numArgs->in->read(); wait_ms(FREQ_NUM_STAB_MS); if(lectureDebut != numArgs->in->read()) { //On écrit dans la mailbox lorsqu'un événement numérique est détecté mute.lock(); MailData * mailData = mailBox.alloc(); mailData->FillData(numArgs->type, time(NULL)); mailBox.put(mailData); mute.unlock(); } if (numArgs->type == 0) { tic_count_num1++; } } } void signaleur_num(void const *args){ //Fonction qui envoie periodiquement un signal aux threads numériques Thread* signaled_thread = (Thread*)args; signaled_thread->signal_set(SIGNAL_NUM); } void signaleur_analog(void const *args){ //Fonction qui envoie periodiquement un signal aux threads analogiques Thread* signaled_thread = (Thread*)args; signaled_thread->signal_set(SIGNAL_ANALOG); } void starttickers() { ticker_num1->start(FREQ_NUM_MS); ticker_num2->start(FREQ_NUM_MS); ticker_analog1->start(FREQ_ANAL_MS); ticker_analog2->start(FREQ_ANAL_MS); pc.printf("Tickers started \n\r"); } void restartTickers() { ticker_num1->stop(); ticker_num2->stop(); ticker_analog1->stop(); ticker_analog2->stop(); ticker_num1->start(FREQ_NUM_MS); ticker_num2->start(FREQ_NUM_MS); ticker_analog1->start(FREQ_ANAL_MS); ticker_analog2->start(FREQ_ANAL_MS); } void tictoc() { //Fonction servant a vérifier et corriger l'écart entre la RTC et la CPU clock int tic_diff; tic_count++; if (tic_count == 10) { if (!(99 < tic_count_num1 < 101)) { tic_diff = 100-tic_count_num1; FREQ_NUM_MS += tic_diff; FREQ_ANAL_MS += tic_diff; restartTickers(); pc.printf("Modif: %i %i", FREQ_NUM_MS, FREQ_ANAL_MS); } pc.printf("RTC Tic count: %i, Real Tic count: %i\r\n", tic_count, tic_count_num1); tic_count = 0; tic_count_num1 = 0; } } int main() { en_1.mode(PullUp); en_2.mode(PullUp); pc.printf("Depart\r\n"); //Création des specs des threads num_args argsNum1(&en_1, 0); num_args argsNum2(&en_2, 1); analog_args argsAnalog1(&ea_1, 2); analog_args argsAnalog2(&ea_2, 3); //Créations des threads Thread num1(lecture_num, &argsNum1); Thread num2(lecture_num, &argsNum2); Thread analog1(lecture_analog, &argsAnalog1); Thread analog2(lecture_analog, &argsAnalog2); Thread collecteur(collection); //Initialisation des tickers RtosTimer temp_ticker_num1(signaleur_num, osTimerPeriodic, &num1); ticker_num1 = &temp_ticker_num1; RtosTimer temp_ticker_num2(signaleur_num, osTimerPeriodic, &num2); ticker_num2 = &temp_ticker_num2; RtosTimer temp_ticker_analog1(signaleur_analog, osTimerPeriodic, &analog1); ticker_analog1 = &temp_ticker_analog1; RtosTimer temp_ticker_analog2(signaleur_analog, osTimerPeriodic, &analog2); ticker_analog2 = &temp_ticker_analog2; // initialisation du RTC set_time(1453667014); //Lancement des tickers starttickers(); RTC::attach(&tictoc, RTC::Second); while(1); }