Gestion du Traffic Adaptatif- Code du mbed coordinateur

Dependencies:   XBeeLib mbed mbed-rtos EthernetInterface

main.cpp

Committer:
leomerel
Date:
2018-12-05
Revision:
30:f8df12b28719
Parent:
29:109a6834f399
Child:
31:7ca80c48a6d7

File content as of revision 30:f8df12b28719:

#include "mbed.h"
#include "XBeeLib.h"
#include "rtos.h"
#include "EthernetInterface.h"

const char* ECHO_SERVER_ADDRESS = "192.168.1.133";
const int ECHO_SERVER_PORT = 7;

#if defined(ENABLE_LOGGING)
#include "DigiLoggerMbedSerial.h"
using namespace DigiLog;
#endif

//Adressage
#define REMOTE_NODE_ADDR64_MSB  ((uint32_t)0x0013A200)
#define REMOTE_NODE_ADDR64_LSB1  ((uint32_t)0x40C0E3A1) // adresse du recepteur 1
#define REMOTE_NODE_ADDR64_LSB2  ((uint32_t)0x4086DA0E) // adresse du recepteur 2
#define REMOTE_NODE_ADDR64_1      UINT64(REMOTE_NODE_ADDR64_MSB, REMOTE_NODE_ADDR64_LSB1)
#define REMOTE_NODE_ADDR64_2      UINT64(REMOTE_NODE_ADDR64_MSB, REMOTE_NODE_ADDR64_LSB2)

using namespace XBeeLib;

//Nombre de voitures au feu
int voituresFeu1 = 0;
int voituresFeu2 = 0;
Thread t_nbVoiture;
Thread t_gestion;

//Gestion
int temps = 5000; //durée (en ms) pour qu'une voiture traverse le chantier
Timer timer;
int whosred;
Thread t_setFeu1Vert;
Thread t_setFeu2Vert;
bool stay1=0; /* stay est une variable qui est à 1 lorsqu'on veut qu'un feu reste à une              */
bool stay2=0; /* certaine couleur jusqu'à ce qu'une autre commande lui dise de changer de couleur    */

//Communication
Serial *log_serial;
XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 9600);
const RemoteXBeeZB remoteDevice1 = RemoteXBeeZB(REMOTE_NODE_ADDR64_1);
const RemoteXBeeZB remoteDevice2 = RemoteXBeeZB(REMOTE_NODE_ADDR64_2);
char set_rouge[]="r"; // message pour demander a un recepteur de passer au rouge
char set_vert[]="v"; // message pour demander a un recepteur de passer au vert


InterruptIn button(p5);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
uint8_t vehicule_urgence=0;
Thread t_urgence;
Thread t_blink;
Thread t_Ethernet;

Mail<int,128> mail_box;

void sendMessage() {
    EthernetInterface eth;
    eth.init(); //Use DHCP
    eth.connect();
    printf("\nClient IP Address is %s\n", eth.getIPAddress());
    
    // Connect to Server
    TCPSocketConnection socket;
    while (socket.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) {
        printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
        wait(1);
    }
    printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
    int * i = 0;
    char hello[] = "10";
    while(1) {
        osEvent evt = mail_box.get();
        if (evt.status == osEventMail) {
            i = (int*)evt.value.p;
            sprintf(hello, "%d", i);
            printf("Sending  message to Server : '%s' \n",hello);
            socket.send_all(hello, sizeof(hello) - 1);
            mail_box.free(i);
        }
    }
    
    
}

static void send_explicit_data_to_remote_node(XBeeZB& xbee, const RemoteXBeeZB& RemoteDevice,const char * data)
{
    const uint8_t dstEP = 0xE8;
    const uint8_t srcEP = 0xE8;
    const uint16_t clusterID = 0x0011;
    const uint16_t profileID = 0xC105;

    const TxStatus txStatus = xbee.send_data(RemoteDevice, dstEP, srcEP, clusterID, profileID, (const uint8_t *)data, strlen(data)); 
}

//Fonction callback invoquée à la réception d'un message
static void receive_cb(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len)
{
    const uint64_t remote_addr64 = remote.get_addr64(); //adresse de l'expéditeur du message
        
    if (data[0]==0x6D){
        // baisse le compteur de voiture au feu 1
        if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1) && (voituresFeu1!=0)){
            voituresFeu1--; 
        }
        // baisse le compteur de voiture au feu 2
        else if ( (UINT64_LO32(remote_addr64)==UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)) && (voituresFeu2!=0)){
            voituresFeu2--;
        }
        log_serial->printf("Nombre de voitures feu 1 : %d\r\n",voituresFeu1);
        log_serial->printf("Nombre de voitures feu 2 : %d\r\n",voituresFeu2);
        int *a = mail_box.alloc();
        a = voituresFeu1+voituresFeu2;
        mail_box.put(a);
    }
    else if (data[0]==0x70){
        // augmente le compteur de voiture au feu 1
        if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1)){
            voituresFeu1++; 
        }
        // augmente le compteur de voiture au feu 2
        else if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)){
            voituresFeu2++;
        }
        log_serial->printf("Nombre de voitures feu 1 : %d\r\n",voituresFeu1);
        log_serial->printf("Nombre de voitures feu 2 : %d\r\n",voituresFeu2);
        int *a = mail_box.alloc();
        a = voituresFeu1+voituresFeu2;
        mail_box.put(a);
    }
    else if (data[0]==0x72){
        // confirmation que r1 est bien rouge, donc peut demander au r2 de passer au vert
        if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1)){
            if(vehicule_urgence==0){
                whosred = 1;
                t_setFeu2Vert.signal_set(0x1);
            }
        }
        // confirmation que r2 est bien rouge, donc peut demander au r1 de passer au vert
        else if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)){
            if(vehicule_urgence==0){
                whosred = 2;
                t_setFeu1Vert.signal_set(0x1);
            }
        }
    }
    log_serial->printf("\r\n");
}

void setFeu1Vert(){
    while(1){
        Thread::signal_wait(0x1);
        Thread::wait(temps);
        if(vehicule_urgence==0){
            send_explicit_data_to_remote_node(xbee, remoteDevice1,set_vert);
            log_serial->printf("r1 passe au vert"); 
        }
    }
}

void setFeu2Vert(){
    while(1){
        Thread::signal_wait(0x1);
        Thread::wait(temps);
        if(vehicule_urgence==0){
            send_explicit_data_to_remote_node(xbee, remoteDevice2,set_vert);  
        }
        log_serial->printf("r2 passe au vert");
    }
}

void connect_Xbee()
{
    log_serial = new Serial(DEBUG_TX, DEBUG_RX);
    log_serial->baud(9600);
    
    #if defined(ENABLE_LOGGING)
    new DigiLoggerMbedSerial(log_serial, LogLevelInfo);
    #endif

    // Register callbacks
    xbee.register_receive_cb(&receive_cb);

    RadioStatus const radioStatus = xbee.init();
    MBED_ASSERT(radioStatus == Success);

    //Attend que l'appareil rejoigne le réseau
    log_serial->printf("En attente de connexion au reseau: ");
    while (!xbee.is_joined()) {
        wait_ms(1000);
        log_serial->printf(".");
    }
    log_serial->printf("Connection reussie.\r\n");
    whosred=1;
}

void gestion()
{
    while(1)
    {
        /* Si il n'y a pas de voitures à un feu ou si il y a beaucoup plus de voitures à l'autre feu,    */
        /* alors l'autre feu passera au vert et le feu avec le moins de voitures passera au rouge.       */
        if ( ((voituresFeu1==0) && (voituresFeu2!=0)) || (voituresFeu2-voituresFeu1>=10) ){
            if(stay1==0){
                stay2=0;
                stay1=1;
                send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
                Thread::wait(100);
            }
        }
        else if ( ((voituresFeu2==0) && (voituresFeu1!=0)) || (voituresFeu1-voituresFeu2>=10) ){
            if(stay2==0){
                stay1=0;
                stay2=1;
                send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
                Thread::wait(100);
            }
        }
        /* Si on est dans aucun de ces deux cas, alors les feux suivront un cycle d'allumage classique.  */
        else{
            stay1=0;
            stay2=0;
            if(whosred==1){
                send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
            }
            else if(whosred==2){
                send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
            }
            Thread::wait(10000);
        }
    }
}

void rise() {
    led3 = !led3;
    t_urgence.signal_set(0x1);
}
void fall() {
    led2 = !led2;
}

void blink(){
    while(1){
        Thread::signal_wait(0x1);
        while(vehicule_urgence){
            led4 = !led4;
            Thread::wait(200);
        }
        led4 = 0;
    }
}

void urgence(){
    while(1){
        Thread::signal_wait(0x1); 
        t_blink.signal_set(0x1);
        vehicule_urgence = 1;
        send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
        send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
        Thread::wait(10000);
        stay1=0;
        stay2=0;
        vehicule_urgence = 0;
    }
}

int main()
{
    
    led2=0;
    led3=0;
    led4=0;
    connect_Xbee();
    
    t_gestion.start(gestion);
    t_setFeu1Vert.start(setFeu1Vert);
    t_setFeu2Vert.start(setFeu2Vert);
    t_urgence.start(urgence);
    t_blink.start(blink);
    t_Ethernet.start(sendMessage);
    
    button.rise(&rise);  // attach the address of the flip function to the rising edge
    button.fall(&fall);
    
    while (true) {        
        uint32_t receive_value = xbee.process_rx_frames();//nécessaire pour lire (constamment) la valeur recue
    }
}