lalallaa

Dependencies:   MMA8452 mbed

main.cpp

Committer:
EtienneB
Date:
2017-10-03
Revision:
1:6738a65b699f
Parent:
0:4a3d5d86258c

File content as of revision 1:6738a65b699f:

/*
BEAE3011
PERV2807    

Noeuds Capteur Version 2
    - Accelerometre
    - Bouton poussoir
    
TO DO
    - Architecture logicielle qui permet reconfiguration facile
    - Utiliser pointeur de fonction pour la lecture et appeler les differentes fonctions a travers un tableau de fonctions
    - Un fichier de configuration qui doit contenir les parametres de l'appli   https://os.mbed.com/cookbook/ConfigFile
        -> Identifiant reseau PAN
        -> Periode de lecture des capteurs (en secondes)
    - Simplifier la configuration de noeuds
        -> Adresse 64 bits doivent etre decouvertes dynamiquement
        
    - Ajouter une led qui allume 1 seconde lorsquune erreur est detectee  
    - Communication doit etre BIDIRECTIONNELLE
        -> Faire allumer une led du noeud capteur par une commande du coordo. en utilisant une commande de configuration a distance (Remote AT Cmds)
        -> Clignote a une frequence de 1Hz et seulement controlee par coordo.
*/

#include "mbed.h"
#include "xbee_command.h"
#include "MMA8452.h"


Serial          pc(USBTX, USBRX);    // Initialiser le porte serie du PC
DigitalOut      resetXBEE(p8);       // Initialiser P8 comme broche de sortie numerique
Serial          serialXBEE(p13, p14);// Initialiser le port de comm serie des broches p13 p14
DigitalIn       button(p7);          // Initialiser le bouton (capteur contact seche)
MMA8452         acc(p9, p10, 10000); // Initialiser l'accelerometre
LocalFileSystem local("local");      // Pour lecture fichier de configuration

// LED LPC1768
DigitalOut led1(LED1); 
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

// Fonctions de lecture des capteurs
uint16_t read_button(); 
uint16_t read_acc_x();
uint16_t read_acc_y();
uint16_t read_acc_z();
void     read_capteurs(int frequence, uint16_t* capteurs_value);

// Fonction de lecture du fichier de configuration
void read_config_file(uint16_t *config_variables); 

// Tableau de fonction pour lecture des capteurs
uint16_t (*p_fonction[4])();    

//Template frame
uint8_t  at_cmd_frame[255];
uint8_t  remote_command_request_frame[255];
uint8_t  tx_request_frame[255];
uint64_t parameter_value;
uint8_t  at_cmd;
uint8_t  message_recu[255];

uint8_t get_MSB(uint16_t info);
uint8_t get_LSB(uint16_t info);

uint8_t mac_adresse[8];

int main() {
    uint16_t  button_state      = 0;
    uint8_t   lsb_button_state = 0;
    uint16_t  acc_x             = 0; 
    uint8_t   msb1_acc_x        = 0; 
    uint8_t   msb2_acc_x        = 0; 
    uint8_t   msb3_acc_x        = 0; 
    uint8_t   msb4_acc_x        = 0; 
    uint8_t   lsb1_acc_x        = 0; 
    uint8_t   lsb2_acc_x        = 0; 
    uint8_t   lsb3_acc_x        = 0; 
    uint8_t   lsb4_acc_x        = 0; 
    uint16_t  acc_y            = 0; 
    uint16_t  acc_z            = 0; 
    uint16_t  capteurs_value[] = {button_state, acc_x, acc_y, acc_z};
    uint8_t   frame_length = 0;
    uint16_t* config_values[]  = {&PAN_ID, &FREQ_LECTURE_CAPTEURS}; // Tableau de pointeur pour variables de configurations
    
    read_config_file(*config_values);   // Lecture du fichier de configuration  
    xbee_init(PAN_ID);                  // Init xbee avec pan ID provenant du fichier de configuration
    
    frame_length = build_remote_cmd_request_frame(FRAME_ID01, PAN_ID, AT_CMD_ID, remote_command_request_frame);
    send_frame_2xbee(remote_command_request_frame, frame_length);
    wait_ms(400);
    
    receive_Xbee(message_recu);
    message_received(message_recu);
    
    pc.printf("MAC = ");
    for(uint8_t i = 0; i < 8; i++){
        pc.printf("%02X ", mac_adresse[i]);
    }
    pc.printf("%\r\n"); 
    
    while(1) {     
        read_capteurs(FREQ_LECTURE_CAPTEURS, capteurs_value);
        
        if((capteurs_value[0] & 0x0001 == 0x0001)){
            lsb_button_state = 0x31;
        }
        else{
            lsb_button_state = 0x30;    
        }
        
        for(uint8_t a; a < 16; a++){
                
        }
        
        msb1_acc_x = 0x31;
        msb2_acc_x = 0x32;
        msb3_acc_x = 0x33;
        msb4_acc_x = 0x34;
        lsb1_acc_x = 0x35;
        lsb2_acc_x = 0x36;
        lsb3_acc_x = 0x37;
        lsb4_acc_x = 0x38;
        
        
        
        uint8_t data[] = {'B', '=', lsb_button_state,
                          0x09,
                          'X', '=', msb1_acc_x, msb2_acc_x, msb3_acc_x, msb4_acc_x};
        
        frame_length = build_tx_request_frame(mac_adresse, PAN_ID, tx_request_frame, data, sizeof(data));
        send_frame_2xbee(tx_request_frame, frame_length);
        //receive_Xbee(message_recu);
        
    } 
}
/**
    Analyse des trames recues par le xbee
*/
bool message_received(uint8_t* message_recu){
    uint8_t frame_id = message_recu[3];
    //pc.printf("\n\r frame id = %02X\r\n", frame_id);
    switch(frame_id){
        case RMT_CMD_RSPNS:
            for(uint8_t i = 0; i < 8; i++){
                mac_adresse[i] = message_recu[5 + i];  
            } 
    }
    return true;
}
/**
    Envoie de la valeur du pan id lu dans le fichier vers le registre 
    correspondant du xbee
*/
bool xbee_init(uint16_t pan_id){      
    uint8_t MSB_pan_id = get_MSB(PAN_ID);
    uint8_t LSB_pan_id = get_LSB(PAN_ID);
    
    uint8_t enter_at_cmd_mode[] = {'+', '+', '+'};
    uint8_t data_pan_id[]   = {MSB_pan_id, LSB_pan_id};
    
    uint8_t frame_length = 0;
    
    // Mettre a 0 la broche RESET pour 400ms
    resetXBEE = 0; wait_ms(400);
    resetXBEE = 1;     
    
    // +++
    send_frame_2xbee(enter_at_cmd_mode, sizeof(enter_at_cmd_mode)); 
    wait_ms(400);
    
    receive_Xbee(message_recu);
    // ID = 9600
    frame_length = build_AT_cmd_frame(FRAME_ID01, AT_CMD_ID, data_pan_id, sizeof(data_pan_id), at_cmd_frame);
    send_frame_2xbee(at_cmd_frame, frame_length);
    wait_ms(30);

    receive_Xbee(message_recu);
    // WR
    frame_length = build_AT_cmd_frame(FRAME_ID01, AT_CMD_WR, NULL, 0, at_cmd_frame);
    send_frame_2xbee(at_cmd_frame, frame_length);
    wait_ms(30);

    receive_Xbee(message_recu);
    
    // AC
    frame_length = build_AT_cmd_frame(FRAME_ID01, AT_CMD_AC, NULL, 0, at_cmd_frame);
    send_frame_2xbee(at_cmd_frame, frame_length);
    wait_ms(30);
    
    receive_Xbee(message_recu);    
    
    return true;
}
/**
    Envoie de la trame vers le xbee
*/
bool send_frame_2xbee(uint8_t* frame, uint8_t frame_length){
    for(uint8_t i = 0; i < frame_length; i++){
        led2 = !led2;
        serialXBEE.putc(frame[i]); 
        pc.printf("%02X ", frame[i]);
        wait_ms(50);
    }
    pc.printf("%\r\n"); 
    return true;
 
}
/**
    Mise dans un tableau de la trame recue par le xbee
*/
uint8_t receive_Xbee(uint8_t* message_recu){
    uint8_t caratere_recu;
    uint8_t message_length = 0;
    
    while(serialXBEE.readable() == 0){
        //pc.printf(" ");
    }

    while(serialXBEE.readable() == 1){
        //pc.printf("%d %d \r\n", serialXBEE.readable(), pc.readable());
        led1 = !led1;  
        caratere_recu = serialXBEE.getc();  pc.printf("%02X ", caratere_recu);// ST 
        message_recu[message_length] = caratere_recu;
        message_length++;
        wait_ms(50);
    }
    
    pc.printf("\r\n"); 
    return message_length;
}
/**
    Construit la trame pour envoie de commande AT 
*/
uint8_t build_AT_cmd_frame(uint8_t frame_id, uint16_t p_AT_cmd, uint8_t* p_value, uint8_t p_value_length, uint8_t* p_at_cmd_frame){  
    uint8_t at_cmd_char1 = get_MSB(p_AT_cmd);
    uint8_t at_cmd_char2 = get_LSB(p_AT_cmd);
    uint8_t checksum     = 0; 
    uint8_t frame_index  = 0;
    
    uint16_t length = p_value_length + 0x04;
    uint8_t  MSB    = get_MSB(length);
    uint8_t  LSB    = get_LSB(length);
    //                                                                                       (optional)
    //                {ST,    MSB,    LSB,    0x08,    frameID,   AT_cmd_1,     AT_cmd_2,     p_value,  checksum}
    
    p_at_cmd_frame[0] = START;
    p_at_cmd_frame[1] = MSB;
    p_at_cmd_frame[2] = LSB;
    p_at_cmd_frame[3] = AT_CMD;
    p_at_cmd_frame[4] = frame_id;
    p_at_cmd_frame[5] = at_cmd_char1;
    p_at_cmd_frame[6] = at_cmd_char2;
    
    if(p_value_length != 0){
        for(frame_index = 7; frame_index < p_value_length + 7; frame_index++){
            p_at_cmd_frame[frame_index] = p_value[frame_index - 7];
        }
    }
    
    // Calculate checksum
    for(frame_index = 3; frame_index < 7 + p_value_length; frame_index++){
        checksum += p_at_cmd_frame[frame_index]; 
        //pc.printf(" checksum = %02X \r\n", checksum);   
    }

    checksum = 0xFF - checksum;
    
    p_at_cmd_frame[frame_index] = checksum; // checksum
    
    return frame_index + 1;
}
/**
    Construit la trame pour envoie de commande AT a un xbee distant
*/
uint8_t build_remote_cmd_request_frame(uint8_t p_frame_id,  uint16_t p_pan_id, uint16_t p_AT_cmd, uint8_t* p_remote_cmd_request_frame){  
    uint64_t mask_mac_id = 0x00000000000000FF;
    
    
    p_pan_id = 0xFFFE;
    uint8_t  mac_bit_shift = 56;
    uint8_t  frame_index   = 0;
    uint16_t checksum      = 0x0000;
    
    uint16_t length = 15;
    uint8_t MSB = get_MSB(length);
    uint8_t LSB = get_LSB(length);

    uint8_t at_cmd_char1 = get_MSB(p_AT_cmd);
    uint8_t at_cmd_char2 = get_LSB(p_AT_cmd);
    
    uint64_t mac_address = 0x00000000;     // broadcast
    
    p_remote_cmd_request_frame[0] = START;         // ST
    p_remote_cmd_request_frame[1] = MSB;           // MSB
    p_remote_cmd_request_frame[2] = LSB;           // LSB
    p_remote_cmd_request_frame[3] = RMT_AT_RQST;    // frame type 0x10
    p_remote_cmd_request_frame[4] = p_frame_id;    // frame id
    // 64b destination address 5 a 12
    for(frame_index = 5; frame_index < 5 + 8; frame_index++){       
        p_remote_cmd_request_frame[frame_index]  = (mac_address >> mac_bit_shift) & mask_mac_id;
        mac_bit_shift = mac_bit_shift - 8;
    }
    // 16b destination network address 13 et 14
    p_remote_cmd_request_frame[13] = (p_pan_id >> 8) & 0x00FF;    // MSB pan_id 
    p_remote_cmd_request_frame[14] = p_pan_id & 0x00FF;   // LSB_pan_id 
    
    p_remote_cmd_request_frame[15] = 0x02;  // Remote Command Option
    
    p_remote_cmd_request_frame[16] = at_cmd_char1;  // AT Command char1
    p_remote_cmd_request_frame[17] = at_cmd_char2;  // At Command char2
    
    // Calculate checksum
    for(frame_index = 3; frame_index < 18; frame_index++){
        checksum += p_remote_cmd_request_frame[frame_index]; 
        //pc.printf(" checksum = %02X \r\n", checksum);   
    }
    
    checksum = 0xFF - checksum;
    
    p_remote_cmd_request_frame[frame_index] = checksum; // checksum
    
    return frame_index + 1;
}
/**
    Construit la trame pour envoie de de trame vers un xbee distant
*/
uint8_t build_tx_request_frame(uint8_t* p_mac_address, uint16_t p_pan_id, uint8_t* p_tx_request_frame, uint8_t *data, uint8_t data_length){ //{ST, MSB, LSB, 0x08, frameID, AT_cmd_1, AT_cmd_2, parameter_value (optional), checksum}   
    uint64_t mask_mac_id = 0x00000000000000FF;
    
    uint8_t  mac_bit_shift = 56;
    uint8_t  frame_index   = 0;
    uint16_t checksum      = 0x0000;
    
    uint16_t length = data_length + 14;
    uint8_t MSB = get_MSB(length);
    uint8_t LSB = get_LSB(length);
    
    p_tx_request_frame[0] = START;         // ST
    p_tx_request_frame[1] = MSB;           // MSB
    p_tx_request_frame[2] = LSB;           // LSB
    p_tx_request_frame[3] = TX_REQUEST;    // frame type 0x10
    p_tx_request_frame[4] = FRAME_ID01;    // frame id

    for(frame_index = 5; frame_index < 5 + 8; frame_index++){       
        p_tx_request_frame[frame_index]  = p_mac_address[frame_index - 5];
    }    

    p_tx_request_frame[13] = (p_pan_id >> 8) & 0x00FF;    // MSB pan_id 
    p_tx_request_frame[14] = p_pan_id & 0x00FF;   // LSB_pan_id 
    
    p_tx_request_frame[15] = 0x00;  // broadcast radius
    p_tx_request_frame[16] = 0x00;  // option
    
    // RF data
    for(frame_index = 17; frame_index < 17 + data_length; frame_index++){       
        p_tx_request_frame[frame_index]  = data[frame_index - 17];
    } 
    // Calculate checksum
    for(frame_index = 3; frame_index < 17 + data_length; frame_index++){
        checksum += p_tx_request_frame[frame_index]; 
        //pc.printf(" checksum = %02X \r\n", checksum);   
    }
    
    checksum = 0xFF - checksum;
    
    p_tx_request_frame[frame_index] = checksum; // checksum
    
    return frame_index + 1;
}
/**
    Isole les 4 bits les plus significatif dune valeur short et la renvoie 
    en char
*/
uint8_t get_MSB(uint16_t info){
    uint8_t MSB = (info >> 8) & 0x00FF;    
    
    return MSB;
}
/**
    Isole les 4 bits les moins significatif dune valeur short et la renvoie 
    en char
*/
uint8_t get_LSB(uint16_t info){
    uint8_t LSB =  info & 0x00FF;
    
    return LSB;
}

uint16_t read_button(){
    if(button){
        return 1;    
    }
    else{
        return 0;
    }
}

/**
    Lecture acceleration grav. en x
*/
uint16_t read_acc_x(){
    int x;
    acc.readXCount(&x);
    return (uint16_t)x;
}
/**
    Lecture acceleration grav. en y
*/
uint16_t read_acc_y(){
    int y;
    acc.readYCount(&y);
    return (uint16_t)y;
}
/**
    Lecture acceleration grav. en z
*/
uint16_t read_acc_z(){
    int z;
    acc.readZCount(&z);
    return (uint16_t)z;
}
/**
    Lecture periodique de tout les capteurs
*/
void read_capteurs(int frequence, uint16_t* capteurs_value){    
    p_fonction[0] = &read_button;
    p_fonction[1] = &read_acc_x; 
    p_fonction[2] = &read_acc_y; 
    p_fonction[3] = &read_acc_z; 
    
    capteurs_value[0] = (*p_fonction[0])(); // bouton
    capteurs_value[1] = (*p_fonction[1])(); // x
    capteurs_value[2] = (*p_fonction[2])(); // y
    capteurs_value[3] = (*p_fonction[3])(); // z
    
    wait(frequence);
}
/**
    Lecture du fichier de configuration pour etablir la valeur
    du temps de lecture des capteur et du pan_id (en decimal dans le fichier)
*/
void read_config_file(uint16_t *config_variables){    
    char    ch;
    char    valeur[10];
    uint8_t len          = 0;
    uint8_t cpt_variable = 0;
    
    FILE *fp = fopen("/local/config.txt", "r");  
    
    while(!feof(fp)){
        ch=fgetc(fp);

        if((((ch >= '0') & (ch <= '9'))) | (ch == '\n')){
            //pc.printf("%c", ch);
            valeur[len] = ch;
            len++;
            if(ch == '\n'){
                config_variables[cpt_variable] = atoi(valeur);
                cpt_variable++;
                for(int i = 0; i < 10; i++){
                    valeur[i] = NULL;    
                }
                len  = 0;   
            }
        }
    }
    fclose(fp);
}