TR

Dependencies:   TextLCD angleandposition mbed

main.cpp

Committer:
walki
Date:
2016-05-19
Revision:
0:bbf9c257d841

File content as of revision 0:bbf9c257d841:

#include "mbed.h"
#include "TextLCD.h"
#include "math.h"
#include "angleandposition.h"


#define Nmax 200 // nombre d'échantillonnages sur une période
#define nb_echantillon_max 10000 // 1s/20ms(temps acquisition pour une période) * Techantillonnage = 50 * 200 = 10 000 soit 10 000 éhantillons par seconde
#define ID 0x09 // ID commun entre les modules XBEE

// Entrées :
AnalogIn  Iana(p16); // intensité mesurée
AnalogIn  Uana(p17); // tension mesurée

// Sorties :
DigitalOut led_temoin(LED1); // LED témoin (sur la carte)

// Objets :
Serial pc(USBTX, USBRX); // (tx, rx) communication par port serie pour l'aide au débogage
TextLCD lcd(p21, p22, p23, p24, p25, p26, TextLCD::LCD16x2); // (d4-d7, rs, e) afficheur LCD
Serial xbee(p9, p10); // (tx,rx) module XBee

// Interruptions :
InterruptIn bouton_gauche(p27); // interruption du bouton gauche
InterruptIn bouton_droit(p28); // interruption du bouton droit

// Fonctions d'échantillonnages :
Ticker echantillonnage; // déclaration d'un programme d'interruption
Ticker echantillonnage_puissance; // déclaration d'un programme d'interruption

// Fichiers externes :
LocalFileSystem local("local"); // fichier créer afin de stocker des valeurs

// Variables :
char pos_menu = 0; // choix du menu à afficher
char trame[14]; // tableau servant à l'envoi des trames

float U0,  U20, U2n_1, Un, U2n, Veff, Ufinal = 0;
float I0,  I20, I2n_1, In, I2n, Ieff, Ifinal = 0;
float P = 0, S, Q, phi, energie_1 = 0, energie = 0;

int ancien_en = 0; // on utilise un INT car la LED s'allume tous les Wh. Avec un float, la LED s'allume tous les 1,XXX Wh
int compteur_echantillonnage = 0;


void calcul() { // fonction de calcul

    if (compteur_echantillonnage == 0) {
        
        
        Veff = 0;
        Ieff = 0;
        U0 = Uana;
        
        U0 = U0 - 0.5;
        U20 = U0 * U0; // U0²
        U2n_1 = U20;


        I0 = Iana;
        I0 = I0 - 0.5;
        I20 = I0 * I0; // I0²
        I2n_1 = I20;

        compteur_echantillonnage++;
    }



    if (compteur_echantillonnage > 0 && (compteur_echantillonnage < nb_echantillon_max)) {

        Un = Uana;
        Un = Un - 0.5;
        U2n = Un * Un;

        Veff = (U2n + U2n_1) / 2 + Veff;
        U2n_1 = U2n;


        In = Iana;
        In = In - 0.5;
        I2n = In * In;

        Ieff = (I2n + I2n_1) / 2 + Ieff;
        I2n_1 = I2n;

        compteur_echantillonnage++;
    }



    if (compteur_echantillonnage >= nb_echantillon_max) {
        
        Ufinal = 707.1*sqrt(Veff/nb_echantillon_max); // 707.1 = 2*sqrt(2)*250 (250 étant 250V, la tension maximale du secteur)
        Ifinal = 14.14*sqrt(Ieff/nb_echantillon_max); // 14.14 = 2*sqrt(2)*5 (5 étant 5A, l'intensité maximale du secteur)

        S = Ufinal * Ifinal; // puissance apparente
        phi = acos(P/S);
        Q = P * tan(phi); // puisance réactive
    }
}

void puissance() { // calcul de la puissance active toutes les secondes par interruption
    
    compteur_echantillonnage = 0; // réinitialisation du compteur pour la fonction calcul()
        
    P = Veff * Ieff; // puissance active
    energie_1 = (energie_1 + P) / 3600; // énergie en Ws et non en Wh
    energie = energie + energie_1;  // calcul de l'énergie consommée au total depuis le démarrage du microcontroleur
    
    if(energie > ancien_en + 1) { // si l'énergie augmente d'un Wh
        
        led_temoin = 1;  // allumer la LED
        wait_ms(500);
        led_temoin = 0;  // éteindre la LED

        ancien_en = energie;    // on garde en mémoire l'ancienne valeur de l'énergie

        FILE* pfile = fopen ("/local/log.txt",""); // ouverture du fichier log.txt
        fprintf(pfile,"En = %.4f Wh\n", energie);   // écriture sur le fichier de l'énergie
        fclose(pfile); // fermeture du fichier
        
    }
}

void menu() { // affichage de l'écran
    
    lcd.cls(); // clear de l'écran

    switch(pos_menu) {
        
        case 0:
            lcd.printf("En = %.4f Wh\n",energie); // on affiche 4 nombres après la virgule
            break;
        case 1:
            lcd.printf("Ueff = %.4f V\n",Ufinal);
            lcd.printf("Ieff = %.4f A\n",Ifinal);
            break;
        case 2:
            lcd.printf("P = %.4f W\n",P);
            lcd.printf("Q = %.4f Var\n",Q);
            break;
        case 3:
            lcd.printf("S = %.4f VA\n",S);
            lcd.printf("cos(phi)= %.0f deg\n",cos(phi));
            break;
        default:
            lcd.printf("En = %.4f Wh\n",energie);
            break;
    }

    wait_ms(200); // délai afin que l'affichage des nouvelles valeurs soit suffisament lent pour être lisible
}


void interupt_btn_gauche() { // interruption lors d'un appui sur le bouton gauche
    
    wait_ms(20); // délai d'attente pour que les parasites, liés à la pression du bouton, ne redéclanchent la fonction
    
    if(pos_menu == 0) { // si l'on arrive à la position 0 du menu
        pos_menu = 4;   // on retournes à la 3ème position du menu (max)
    } else pos_menu--; // on passe à l'affichage de gauche
}


void interupt_btn_droit() { // interruption lors d'un appui sur le bouton droit
    
    wait_ms(20); // délai d'attente pour que les parasites, liés à la pression du bouton, ne redéclanchent la fonction
    
    if(pos_menu == 3) { // si l'on arrive à la 3ème position du menu (max)
        pos_menu = 0;   // on retournes à la position 0
    } else pos_menu++; // on passe à l'affichage de droite
}


void envoi() {
    uint16_t trame_4 = (Ufinal*100);
    uint16_t trame_6 = (Ifinal*100);
    uint16_t trame_8 = (P*100);
    uint16_t trame_10 = (energie*100);
    char sum;
    
    //trame[0] = 0x55;
    trame[1] = 0x55;            // synchronisation du récepteur
    trame[2] = ID;              // octet d'identification
    trame[3] = Ufinal*100;      // octet de poids fort de la tension efficace
    trame[4] = trame_4 >> 8;    // octet de poids faible de la tension efficace
    trame[5] = Ifinal*100;      // octet de poids fort de l'intensité efficace
    trame[6] = trame_6 >> 8;    // octet de poids faible de l'intensité efficace
    trame[7] = P*100;           // octet de poids fort de la puissance active
    trame[8] = trame_8 >> 8;    // octet de poids faible de la puissance active
    trame[9] = energie*100;     // octet de poids fort de la valeur du compteur d'énergie
    trame[10] = trame_10 >> 8;  // second octet de poids fort de la valeur du compteur d'énergie
    trame[11] = trame_10 >> 16; // troisième octet de poids fort de la valeur du compteur d'énergie
    trame[12] = trame_10 >> 24; // octet de poids faible de la valeur du compteur d'énergie
    for(int i = 1; i < 13; i++) { sum = sum + trame[i]; };  // calcul du check sum
    trame[13] = sum;            // Check sum
    
    for(int i = 1; i < 14; i++) {// boucle d'envoi des trames
        
        xbee.putc(trame[i]);
        wait(0.01);
        pc.printf("%d \t",trame[i]);
    }
    pc.printf("\r");
    
}

int main() {
    
    bouton_gauche.mode(PullUp);
    bouton_droit.mode(PullUp);

    bouton_gauche.fall(&interupt_btn_gauche);
    bouton_droit.fall(&interupt_btn_droit);
    
    led_temoin = 0; // la LED témoin est éteinte

    echantillonnage.attach(&calcul, 0.0001); // interruption toutes les 100µs
    echantillonnage_puissance.attach(&puissance, 1); // interruption toutes les 1s
 
    while(1) { // boucle infinie
        
        menu(); // fonction d'affichage
        envoi(); // fonction d'envoi des trames
        //wait(5);
    }
}