Polytech school project. RICM4 students, see http://air.imag.fr/index.php/Projets-2016-2017-Station_de_pompage_connect%C3%A9e for more information

Dependencies:   SX1272Lib mbed WakeUp

Fork of SX1272PingPong by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "main.h"
00003 #include "sx1272-hal.h"
00004 #include "debug.h"
00005 #include "trame.h"
00006 #include "ordre.h"
00007 #include "pompe.h"
00008 #include "WakeUp.h"
00009 #include "niveau.h"
00010 
00011 /* Set this flag to '1' to display debug messages on the console */
00012 #define DEBUG_MESSAGE   1
00013 #define ID_DEVICE 0x24
00014 #define ID_STATION 0x55
00015 #define TEMPS_ECOUTE_ORDRE_SECONDE 20.0
00016 #define TEMPS_ATTENTE_ACK 60.0
00017 #define SLEEP_TIME 30000 //ms
00018 
00019 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
00020 #define USE_MODEM_LORA  1
00021 #define USE_MODEM_FSK   !USE_MODEM_LORA
00022 
00023 #define RF_FREQUENCY                                    865000000 // Hz
00024 #define TX_OUTPUT_POWER                                 14        // 14 dBm
00025 
00026 #if USE_MODEM_LORA == 1
00027 
00028     #define LORA_BANDWIDTH                              2         // [0: 125 kHz,
00029                                                                   //  1: 250 kHz,
00030                                                                   //  2: 500 kHz,
00031                                                                   //  3: Reserved]
00032     #define LORA_SPREADING_FACTOR                       7         // [SF7..SF12]
00033     #define LORA_CODINGRATE                             1         // [1: 4/5,
00034                                                                   //  2: 4/6,
00035                                                                   //  3: 4/7,
00036                                                                   //  4: 4/8]
00037     #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
00038     #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
00039     #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
00040     #define LORA_FHSS_ENABLED                           false  
00041     #define LORA_NB_SYMB_HOP                            4     
00042     #define LORA_IQ_INVERSION_ON                        false
00043     #define LORA_CRC_ENABLED                            true
00044     
00045 #elif USE_MODEM_FSK == 1
00046 
00047     #define FSK_FDEV                                    25000     // Hz
00048     #define FSK_DATARATE                                19200     // bps
00049     #define FSK_BANDWIDTH                               50000     // Hz
00050     #define FSK_AFC_BANDWIDTH                           83333     // Hz
00051     #define FSK_PREAMBLE_LENGTH                         5         // Same for Tx and Rx
00052     #define FSK_FIX_LENGTH_PAYLOAD_ON                   false
00053     #define FSK_CRC_ENABLED                             true
00054     
00055 #else
00056     #error "Please define a modem in the compiler options."
00057 #endif
00058 
00059 #define RX_TIMEOUT_VALUE                                3500000//3500000   // in us
00060 #define BUFFER_SIZE                                     32        // Define the payload size here
00061 
00062 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
00063 DigitalOut led(LED2);
00064 #else
00065 DigitalOut led(LED1);
00066 #endif
00067 
00068 /*
00069  *  Global variables declarations
00070  */
00071 typedef enum
00072 {
00073     LOWPOWER = 0,
00074     IDLE,
00075     
00076     RX,
00077     RX_TIMEOUT,
00078     RX_ERROR,
00079     
00080     TX,
00081     TX_TIMEOUT,
00082     
00083     CAD,
00084     CAD_DONE
00085 }AppStates_t;
00086 
00087 volatile AppStates_t State = LOWPOWER;
00088 
00089 /*!
00090  * Radio events function pointer
00091  */
00092 static RadioEvents_t RadioEvents;
00093 
00094 /*
00095  *  Global variables declarations
00096  */
00097 SX1272MB2xAS Radio( NULL );
00098 
00099 uint16_t BufferSize = BUFFER_SIZE;
00100 uint8_t Buffer[BUFFER_SIZE];
00101 
00102 int16_t RssiValue = 0.0;
00103 int8_t SnrValue = 0.0;
00104 
00105 //Fonction permettant de faire dormir la carte
00106 //LE DEEPSLEEP Ne fonctionne pas !
00107 void dormir(){
00108     debug_if(DEBUG_MESSAGE,"dodo\r\n");
00109     Radio.Sleep();
00110     WakeUp::set_ms(SLEEP_TIME);
00111     sleep();
00112     
00113     wait(5);
00114 }
00115 
00116 Timer ecouterOrdre;
00117 
00118 int main() 
00119 {
00120     uint8_t i;
00121     
00122     debug_if(DEBUG_MESSAGE, "\n\n\r     SX1272 Cuve Demo Application \n\n\r" );
00123 
00124     // Initialize Radio driver
00125     RadioEvents.TxDone = OnTxDone;
00126     RadioEvents.RxDone = OnRxDone;
00127     RadioEvents.RxError = OnRxError;
00128     RadioEvents.TxTimeout = OnTxTimeout;
00129     RadioEvents.RxTimeout = OnRxTimeout;
00130     Radio.Init( &RadioEvents );
00131     
00132     // verify the connection with the board
00133     while( Radio.Read( REG_VERSION ) == 0x00  )
00134     {
00135         debug_if(DEBUG_MESSAGE, "Radio could not be detected!\n\r", NULL );
00136         wait( 1 );
00137     }
00138     
00139     debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1272MB2XAS ) ) , "\n\r > Board Type: SX1272MB2xAS < \n\r" );
00140   
00141     Radio.SetChannel( RF_FREQUENCY ); 
00142 
00143 #if USE_MODEM_LORA == 1
00144     
00145     debug_if( LORA_FHSS_ENABLED, "\n\n\r             > LORA FHSS Mode < \n\n\r");
00146     debug_if( !LORA_FHSS_ENABLED, "\n\n\r             > LORA Mode < \n\n\r");
00147 
00148     Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
00149                          LORA_SPREADING_FACTOR, LORA_CODINGRATE,
00150                          LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
00151                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00152                          LORA_IQ_INVERSION_ON, 2000000 );
00153     
00154     Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
00155                          LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
00156                          LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
00157                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00158                          LORA_IQ_INVERSION_ON, true );
00159                          
00160 #elif USE_MODEM_FSK == 1
00161 
00162     debug_if(DEBUG_MESSAGE,"\n\n\r              > FSK Mode < \n\n\r");
00163     Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
00164                          FSK_DATARATE, 0,
00165                          FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
00166                          FSK_CRC_ENABLED, 0, 0, 0, 2000000 );
00167     
00168     Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
00169                          0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
00170                          0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
00171                          0, 0, false, true );
00172                          
00173 #else
00174 
00175 #error "Please define a modem in the compiler options."
00176 
00177 #endif
00178      
00179     debug_if( DEBUG_MESSAGE, "Starting Cuve loop\r\n" ); 
00180         
00181     led = 0;
00182     
00183     //Initialisation
00184     Pompe pompe(PC_5);
00185     pompe.arreterPompe();
00186     Niveau cuve(PC_8,PC_3,PC_2,PC_6);
00187     TrameData dataPaquet(ID_DEVICE,ID_STATION, 8, pompe.etat(), 0xF, 0xA);
00188     
00189     bool enAttenteOrdre = false;
00190     bool enAttenteAck = false;
00191     
00192     //The low-power oscillator can be quite inaccurate on some targets
00193     //this function calibrates it against the main clock
00194     WakeUp::calibrate();
00195     
00196     
00197     //Debut programme
00198     while( 1 )
00199     {
00200         switch( State )
00201         {
00202         case RX:
00203             if( enAttenteOrdre || enAttenteAck )
00204             {
00205                
00206                 if( BufferSize > 0 )
00207                 {
00208                     debug_if( DEBUG_MESSAGE, "2\r\n");
00209                     debug_if(DEBUG_MESSAGE,(const char* )Buffer);
00210                     debug_if( DEBUG_MESSAGE, " ");
00211                     debug_if(DEBUG_MESSAGE,(const char* ) ID_DEVICE);
00212                     Ordre trameRecue((char*)Buffer);
00213                     //Si message recu alors trouver ordre correspondant et faire traitement
00214                     if( trameRecue.getIdRecepteur() == (char) ID_DEVICE )
00215                     {
00216                         debug_if( DEBUG_MESSAGE, "ID DEVICE OK\r\n");
00217                         if( trameRecue.getIdEmetteur() == (char) ID_STATION ){
00218                             debug_if( DEBUG_MESSAGE, "ID STATION OK\r\n");
00219                             
00220                             if(enAttenteOrdre){
00221                                 //Ordre pour nous
00222                                 led = !led;
00223                                 debug_if( DEBUG_MESSAGE,  "...Ordre recu \r\n" );
00224                                 Ordre o((char *) Buffer);
00225                                 if(trameRecue.getOrdreAFaire()==1)
00226                                     o.executerOrdre(pompe, cuve, o.getNiveauCuve());
00227                                 
00228                                 dormir();
00229                                 enAttenteOrdre = false;
00230                                 Radio.Rx( RX_TIMEOUT_VALUE );
00231                             }
00232                             else if(trameRecue.getOrdreAFaire()==0 && enAttenteAck){
00233                                 debug_if( DEBUG_MESSAGE, "ACK recu\r\n");
00234                                 enAttenteAck = false;
00235                                 ecouterOrdre.reset();
00236                                 enAttenteOrdre = true;
00237                                 Radio.Rx( RX_TIMEOUT_VALUE );
00238                             }
00239                             else{
00240                                 //mauvais ACK on concidère que c'est OK
00241                                 debug_if( DEBUG_MESSAGE, "mauvais ACK recu\r\n");
00242                                 enAttenteAck = false;
00243                                 ecouterOrdre.reset();
00244                                 enAttenteOrdre = true;
00245                                 Radio.Rx( RX_TIMEOUT_VALUE );
00246                             }
00247                         }else{
00248                             debug_if( DEBUG_MESSAGE, "autre station\r\n");
00249                             Radio.Rx( RX_TIMEOUT_VALUE );
00250                         }
00251                     }
00252                     else // valid reception but not for us
00253                     {    // Start again
00254                         debug_if( DEBUG_MESSAGE, "Reception message pour quelqu'un d'autre\r\n");
00255                         Radio.Rx( RX_TIMEOUT_VALUE );
00256                     }    
00257                 }
00258             }
00259             State = LOWPOWER;
00260             break;
00261         case TX:    
00262             led = !led; 
00263             debug_if( DEBUG_MESSAGE && !enAttenteAck,  "Envoi des donnees...\r\n" );
00264             debug_if( DEBUG_MESSAGE && enAttenteAck, "En attente ACK\r\n");
00265             Radio.Rx( RX_TIMEOUT_VALUE );
00266             State = LOWPOWER;
00267             break;
00268         case RX_TIMEOUT:           
00269             Radio.Rx( RX_TIMEOUT_VALUE );  
00270             State = LOWPOWER;
00271             break;
00272         case RX_ERROR:
00273             //Erreur CRC, faire une demande de renvoi
00274             //TODO
00275             debug_if( DEBUG_MESSAGE, "Erreur CRC \r\n");
00276             Radio.Rx( RX_TIMEOUT_VALUE );
00277             State = LOWPOWER;
00278             break;
00279         case TX_TIMEOUT:
00280             Radio.Rx( RX_TIMEOUT_VALUE );
00281             State = LOWPOWER;
00282             break;
00283         case LOWPOWER:
00284             if(!enAttenteOrdre && !enAttenteAck){
00285                 //Corps de l'application
00286                 //On envoie les données
00287                 debug_if( DEBUG_MESSAGE, "envoie3\r\n");
00288                 dataPaquet.mettreAJourEtatPompe((char) pompe.etat());
00289                 dataPaquet.mettreAJourNiveauCuve(cuve.getNiveauCuve());
00290                 dataPaquet.mettreAJourNiveauBatterie((char) 0xA);
00291                 
00292                 // Send the data
00293                 char * trame = dataPaquet.creerTrame();
00294                 strcpy( ( char* ) Buffer, trame);
00295                 for (i = TAILLE_TRAME_DATA; i < BufferSize; i++ )
00296                 {
00297                     Buffer[i] = i - 4;
00298                 }
00299                 wait_ms( 10 );
00300                 
00301                 //Initialisation des variables de controle
00302                 enAttenteAck = true;
00303                 debug_if( DEBUG_MESSAGE,  "Debut timer \r\n");
00304                 ecouterOrdre.start();
00305                 Radio.Send( Buffer, BufferSize );
00306             }else{
00307                 ecouterOrdre.stop();
00308                 if(enAttenteAck && (ecouterOrdre.read() > TEMPS_ATTENTE_ACK)){
00309                     debug_if( DEBUG_MESSAGE, "delaisAttente ack depasse. Reemission.\r\n");
00310                     ecouterOrdre.stop();
00311                     ecouterOrdre.reset();
00312                     enAttenteAck = false;
00313                 }else
00314                 if(enAttenteOrdre && (ecouterOrdre.read() > TEMPS_ECOUTE_ORDRE_SECONDE)){
00315                     debug_if( DEBUG_MESSAGE, "delaisAttente depasse. Dormir.\r\n");
00316                     ecouterOrdre.stop();
00317                     ecouterOrdre.reset();
00318                     dormir();
00319                     debug_if( DEBUG_MESSAGE, "fin dodo\r\n");
00320                     enAttenteOrdre = false;
00321                 }
00322                 else ecouterOrdre.start();
00323             }
00324             break;
00325         default:
00326             State = LOWPOWER;
00327             break;
00328         }    
00329     }
00330 }
00331 
00332 void OnTxDone( void )
00333 {
00334     Radio.Sleep( );
00335     State = TX;
00336     debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
00337 }
00338 
00339 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
00340 {
00341     Radio.Sleep( );
00342     BufferSize = size;
00343     memcpy( Buffer, payload, BufferSize );
00344     RssiValue = rssi;
00345     SnrValue = snr;
00346     State = RX;
00347     debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
00348 }
00349 
00350 void OnTxTimeout( void )
00351 {
00352     Radio.Sleep( );
00353     State = TX_TIMEOUT;
00354     debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
00355 }
00356 
00357 void OnRxTimeout( void )
00358 {
00359     Radio.Sleep( );
00360     Buffer[ BufferSize ] = 0;
00361     State = RX_TIMEOUT;
00362     debug_if( DEBUG_MESSAGE, "." );
00363 }
00364 
00365 void OnRxError( void )
00366 {
00367     Radio.Sleep( );
00368     State = RX_ERROR;
00369     debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
00370 }
00371