Gestion du Traffic Adaptatif- Code du mbed coordinateur

Dependencies:   XBeeLib mbed mbed-rtos EthernetInterface

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 * GTA (Gestion du Trafic Adaptatif) Sherbrooke
00003 * Code à mettre dans le mbed du noeud fixe 
00004 * Par : Léo MEREL, Jean-Philippe BAILLARGEON, Pierre BLOUET, Alex VIGNEAULT, Mikaël LAMONTAGNE
00005 */
00006 
00007 #include "mbed.h"
00008 #include "XBeeLib.h"
00009 #include "rtos.h"
00010 #include "EthernetInterface.h"
00011 
00012 const char* ECHO_SERVER_ADDRESS = "192.168.1.133";
00013 const int ECHO_SERVER_PORT = 7;
00014 
00015 #if defined(ENABLE_LOGGING)
00016 #include "DigiLoggerMbedSerial.h"
00017 using namespace DigiLog;
00018 #endif
00019 
00020 //Adressage
00021 #define REMOTE_NODE_ADDR64_MSB  ((uint32_t)0x0013A200)
00022 #define REMOTE_NODE_ADDR64_LSB1  ((uint32_t)0x40C0E3A1) // adresse du recepteur 1
00023 #define REMOTE_NODE_ADDR64_LSB2  ((uint32_t)0x4086DA0E) // adresse du recepteur 2
00024 #define REMOTE_NODE_ADDR64_1      UINT64(REMOTE_NODE_ADDR64_MSB, REMOTE_NODE_ADDR64_LSB1)
00025 #define REMOTE_NODE_ADDR64_2      UINT64(REMOTE_NODE_ADDR64_MSB, REMOTE_NODE_ADDR64_LSB2)
00026 
00027 using namespace XBeeLib;
00028 
00029 //Nombre de voitures au feu
00030 int voituresFeu1 = 0;
00031 int voituresFeu2 = 0;
00032 Thread t_nbVoiture;
00033 Thread t_gestion;
00034 
00035 //Gestion
00036 int temps = 5000; //durée (en ms) pour qu'une voiture traverse le chantier
00037 int duree_cycle = 10000; // durée (en ms) du cycle d'allumage classique
00038 Timer timer;
00039 int isRed;
00040 Thread t_setFeu1Vert;
00041 Thread t_setFeu2Vert;
00042 bool stay1=0; /* stay est une variable qui est à 1 lorsqu'on veut qu'un feu reste à une              */
00043 bool stay2=0; /* certaine couleur jusqu'à ce qu'une autre commande lui dise de changer de couleur    */
00044 
00045 //Communication
00046 Serial *log_serial;
00047 XBeeZB xbee = XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 9600);
00048 const RemoteXBeeZB remoteDevice1 = RemoteXBeeZB(REMOTE_NODE_ADDR64_1);
00049 const RemoteXBeeZB remoteDevice2 = RemoteXBeeZB(REMOTE_NODE_ADDR64_2);
00050 char set_rouge[]="r"; // message pour demander a un recepteur de passer au rouge
00051 char set_vert[]="v"; // message pour demander a un recepteur de passer au vert
00052 
00053 
00054 InterruptIn button(p5);
00055 DigitalOut led1(LED1);
00056 DigitalOut led2(LED2);
00057 DigitalOut led3(LED3);
00058 DigitalOut led4(LED4);
00059 uint8_t vehicule_urgence=0;
00060 Thread t_urgence;
00061 Thread t_blink;
00062 Thread t_Ethernet;
00063 
00064 Mail<int,128> mail_box;
00065 
00066 // Envoyer un message au rasberryPi
00067 void sendMessage() {
00068     EthernetInterface eth;
00069     eth.init(); //Use DHCP
00070     eth.connect();
00071     printf("\r\nClient IP Address is %s\r\n", eth.getIPAddress());
00072     
00073     // Connect to Server
00074     TCPSocketConnection socket;
00075     while (socket.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) {
00076         printf("Unable to connect to (%s) on port (%d)\r\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
00077         wait(1);
00078     }
00079     printf("Connected to Server at %s\r\n",ECHO_SERVER_ADDRESS);
00080     int * i = 0;
00081     char hello[] = "100";
00082     while(1) {
00083         osEvent evt = mail_box.get();
00084         if (evt.status == osEventMail) {
00085             i = (int*)evt.value.p;
00086             if(*i<10){
00087                 sprintf(hello, "00%d\r\n", *i);
00088             }
00089             else if(*i<100){
00090                 sprintf(hello, "0%d\r\n", *i);
00091             }
00092             else{
00093                 sprintf(hello, "%d\r\n", *i);
00094             }
00095             printf("Sending  message to Server : '%s' \r\n",hello);
00096             socket.send_all(hello, sizeof(hello) - 1);
00097             mail_box.free(i);
00098         }
00099     }
00100     
00101     
00102 }
00103 
00104 // Envoyer un message à un autre mbed, via un xbee d'adresse connue
00105 static void send_explicit_data_to_remote_node(XBeeZB& xbee, const RemoteXBeeZB& RemoteDevice,const char * data)
00106 {
00107     const uint8_t dstEP = 0xE8;
00108     const uint8_t srcEP = 0xE8;
00109     const uint16_t clusterID = 0x0011;
00110     const uint16_t profileID = 0xC105;
00111 
00112     const TxStatus txStatus = xbee.send_data(RemoteDevice, dstEP, srcEP, clusterID, profileID, (const uint8_t *)data, strlen(data)); 
00113 }
00114 
00115 //Fonction callback invoquée à la réception d'un message
00116 static void receive_cb(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len)
00117 {
00118     const uint64_t remote_addr64 = remote.get_addr64(); //adresse de l'expéditeur du message
00119         
00120     if (data[0]==0x6D){
00121         // baisse le compteur de voiture au feu 1
00122         if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1) && (voituresFeu1!=0)){
00123             voituresFeu1--; 
00124         }
00125         // baisse le compteur de voiture au feu 2
00126         else if ( (UINT64_LO32(remote_addr64)==UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)) && (voituresFeu2!=0)){
00127             voituresFeu2--;
00128         }
00129         log_serial->printf("Nombre de voitures feu 1 : %d\r\n",voituresFeu1);
00130         log_serial->printf("Nombre de voitures feu 2 : %d\r\n",voituresFeu2);
00131         int *a = mail_box.alloc();
00132         *a = voituresFeu1+voituresFeu2;
00133         log_serial->printf("Voiture total : %d\r\n",*a);
00134         mail_box.put(a);
00135     }
00136     else if (data[0]==0x70){
00137         // augmente le compteur de voiture au feu 1
00138         if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1)){
00139             voituresFeu1++; 
00140         }
00141         // augmente le compteur de voiture au feu 2
00142         else if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)){
00143             voituresFeu2++;
00144         }
00145         log_serial->printf("Nombre de voitures feu 1 : %d\r\n",voituresFeu1);
00146         log_serial->printf("Nombre de voitures feu 2 : %d\r\n",voituresFeu2);
00147         int *a = mail_box.alloc();
00148         *a = voituresFeu1+voituresFeu2;
00149         log_serial->printf("Voiture total : %d\r\n",*a);
00150         mail_box.put(a);
00151     }
00152     else if (data[0]==0x72){
00153         // confirmation que r1 est bien rouge, donc peut demander au r2 de passer au vert
00154         if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB1)){
00155             if(vehicule_urgence==0){
00156                 isRed = 1;
00157                 t_setFeu2Vert.signal_set(0x1);
00158             }
00159         }
00160         // confirmation que r2 est bien rouge, donc peut demander au r1 de passer au vert
00161         else if ( UINT64_LO32(remote_addr64) == UINT64_LO32(REMOTE_NODE_ADDR64_LSB2)){
00162             if(vehicule_urgence==0){
00163                 isRed = 2;
00164                 t_setFeu1Vert.signal_set(0x1);
00165             }
00166         }
00167     }
00168     log_serial->printf("\r\n");
00169 }
00170 
00171 void setFeu1Vert(){
00172     while(1){
00173         Thread::signal_wait(0x1);
00174         Thread::wait(temps);
00175         if(vehicule_urgence==0){
00176             send_explicit_data_to_remote_node(xbee, remoteDevice1,set_vert);
00177             log_serial->printf("r1 passe au vert\r\n"); 
00178         }
00179     }
00180 }
00181 
00182 void setFeu2Vert(){
00183     while(1){
00184         Thread::signal_wait(0x1);
00185         Thread::wait(temps);
00186         if(vehicule_urgence==0){
00187             send_explicit_data_to_remote_node(xbee, remoteDevice2,set_vert);  
00188         }
00189         log_serial->printf("r2 passe au vert\r\n");
00190     }
00191 }
00192 
00193 // Connection faite au démarrage du programme lorsqu'on reset le mbed
00194 void connect_Xbee()
00195 {
00196     log_serial = new Serial(DEBUG_TX, DEBUG_RX);
00197     log_serial->baud(9600);
00198     
00199     #if defined(ENABLE_LOGGING)
00200     new DigiLoggerMbedSerial(log_serial, LogLevelInfo);
00201     #endif
00202 
00203     // Register callbacks
00204     xbee.register_receive_cb(&receive_cb);
00205 
00206     RadioStatus const radioStatus = xbee.init();
00207     MBED_ASSERT(radioStatus == Success);
00208 
00209     //Attend que l'appareil rejoigne le réseau
00210     log_serial->printf("En attente de connexion au reseau: ");
00211     while (!xbee.is_joined()) {
00212         wait_ms(1000);
00213         log_serial->printf(".");
00214     }
00215     log_serial->printf("Connection reussie.\r\n");
00216     isRed=1;
00217 }
00218 
00219 void gestion()
00220 {
00221     while(1)
00222     {
00223         /* Si il n'y a pas de voitures à un feu ou si il y a beaucoup plus de voitures à l'autre feu,    */
00224         /* alors l'autre feu passera au vert et le feu avec le moins de voitures passera au rouge.       */
00225         if ( ((voituresFeu1==0) && (voituresFeu2!=0)) || (voituresFeu2-voituresFeu1>=10) ){
00226             if(stay1==0){
00227                 stay2=0;
00228                 stay1=1;
00229                 send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
00230                 Thread::wait(100);
00231             }
00232         }
00233         else if ( ((voituresFeu2==0) && (voituresFeu1!=0)) || (voituresFeu1-voituresFeu2>=10) ){
00234             if(stay2==0){
00235                 stay1=0;
00236                 stay2=1;
00237                 send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
00238                 Thread::wait(100);
00239             }
00240         }
00241         /* Si on est dans aucun de ces deux cas, alors les feux suivront un cycle d'allumage classique.  */
00242         else{
00243             stay1=0;
00244             stay2=0;
00245             if(isRed==1){
00246                 send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
00247             }
00248             else if(isRed==2){
00249                 send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
00250             }
00251             Thread::wait(duree_cycle);
00252         }
00253     }
00254 }
00255 
00256 void rise() {
00257     led3 = !led3;
00258     t_urgence.signal_set(0x1);
00259 }
00260 
00261 void blink(){
00262     while(1){
00263         Thread::signal_wait(0x1);
00264         while(vehicule_urgence){
00265             led4 = !led4;
00266             Thread::wait(200);
00267         }
00268         led4 = 0;
00269     }
00270 }
00271 
00272 void urgence(){
00273     while(1){
00274         Thread::signal_wait(0x1); 
00275         t_blink.signal_set(0x1);
00276         vehicule_urgence = 1;
00277         send_explicit_data_to_remote_node(xbee, remoteDevice1,set_rouge);
00278         send_explicit_data_to_remote_node(xbee, remoteDevice2,set_rouge);
00279         Thread::wait(10000);
00280         stay1=0;
00281         stay2=0;
00282         vehicule_urgence = 0;
00283     }
00284 }
00285 
00286 int main(){
00287     led2=0;
00288     led3=0;
00289     led4=0;
00290     connect_Xbee();
00291     
00292     t_gestion.start(gestion);
00293     t_setFeu1Vert.start(setFeu1Vert);
00294     t_setFeu2Vert.start(setFeu2Vert);
00295     t_urgence.start(urgence);
00296     t_blink.start(blink);
00297     t_Ethernet.start(sendMessage);
00298     
00299     button.rise(&rise);  // attach the address of the flip function to the rising edge
00300     
00301     while (true) {        
00302         uint32_t receive_value = xbee.process_rx_frames();//nécessaire pour lire (constamment) la valeur recue
00303     }
00304 }