![](/media/cache/group/drone_pigeon.jpg.50x50_q85.jpg)
Test LORA NODE with Library SX1272, initially created by C.Pham, University of Pau, France for Arduino. Suitable for MBED / NUCLEO / STM32
main.cpp
00001 /* 00002 * temperature sensor on analog 8 to test the LoRa gateway 00003 * 00004 * Copyright (C) 2016 Congduc Pham, University of Pau, France 00005 * 00006 * This program is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the program. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 ***************************************************************************** 00020 * last update: Sep. 29th, 2017 by C. Pham 00021 * last update: oct 30th , 2017 by C.Dupaty 00022 * ADAPTATION FOR NUCLEO STM32, TESTED ON NUCLEO-L073RZ WITH 00023 * SX1272MB2xAS SHIELD 00024 * DRAGINO SHIELD V95 WITH GPS http://wiki.dragino.com/index.php?title=Lora/GPS_Shield 00025 * For DRAGINO move LORA_CLK LORA_DI LORA_DO straps to the right (arduino 11 12 13) 00026 * ALL CONFIGURATIONS FOR ARDUINO HAVE BEEN REMOVED 00027 * WORK ONLY IN EUROPE 00028 * please visit http://cpham.perso.univ-pau.fr/LORA/LoRaDevices.html 00029 * for original version for ARDUINO 00030 */ 00031 00032 #include "mbed.h" 00033 #include "SX1272.h" 00034 #define BAND868 00035 #define MAX_DBM 14 00036 00037 const uint32_t DEFAULT_CHANNEL=CH_10_868; // for BAND868 00038 00039 //#define WITH_EEPROM // TO DO ON STM32 00040 #define WITH_APPKEY 00041 #define NEW_DATA_FIELD 00042 #define WITH_ACK 00043 00044 /////////////////////////////////////////////////////////////////// 00045 // CHANGE HERE THE LORA MODE, NODE ADDRESS 00046 #define LORAMODE 1 00047 #define node_addr 6 00048 ////////////////////////////////////////////////////////////////// 00049 00050 /////////////////////////////////////////////////////////////////// 00051 // CHANGE HERE THE THINGSPEAK FIELD BETWEEN 1 AND 4 00052 #define field_index 1 00053 /////////////////////////////////////////////////////////////////// 00054 00055 /////////////////////////////////////////////////////////////////// 00056 // CHANGE HERE THE READ PIN AND THE POWER PIN FOR THE TEMP. SENSOR 00057 #define TEMP_PIN_READ PA_4 00058 // use digital 9 to power the temperature sensor if needed 00059 #define TEMP_PIN_POWER PB_0 00060 /////////////////////////////////////////////////////////////////// 00061 00062 /////////////////////////////////////////////////////////////////// 00063 // CHANGE HERE THE TIME IN SECONDS BETWEEN 2 READING & TRANSMISSION 00064 #define minTime 120 // 2 minutes 00065 #define maxTime 600 // 10 minutes 00066 /////////////////////////////////////////////////////////////////// 00067 00068 #ifdef WITH_APPKEY 00069 /////////////////////////////////////////////////////////////////// 00070 // CHANGE HERE THE APPKEY, BUT IF GW CHECKS FOR APPKEY, MUST BE 00071 // IN THE APPKEY LIST MAINTAINED BY GW. 00072 uint8_t my_appKey[4]={5, 6, 7, 8}; 00073 /////////////////////////////////////////////////////////////////// 00074 #endif 00075 00076 #ifdef WITH_EEPROM 00077 #include <EEPROM.h> 00078 #endif 00079 00080 #define DEFAULT_DEST_ADDR 1 00081 00082 #ifdef WITH_ACK 00083 #define NB_RETRIES 2 00084 #endif 00085 00086 #ifdef WITH_EEPROM 00087 struct sx1272config { 00088 00089 uint8_t flag1; 00090 uint8_t flag2; 00091 uint8_t seq; 00092 // can add other fields such as LoRa mode,... 00093 }; 00094 00095 sx1272config my_sx1272config; 00096 #endif 00097 00098 /////////////////////////////////////// 00099 // Globals variables 00100 /////////////////////////////////////// 00101 int loraMode=LORAMODE; 00102 // added by C.Dupaty 00103 // For test with LM35DZ temperature captor 00104 DigitalOut temp_pin_power(TEMP_PIN_POWER); 00105 AnalogIn temp_pin_read(TEMP_PIN_READ); 00106 00107 ///////////////////////////////////////// 00108 // SETUP SX1272 initialisation 00109 //////////////////////////////////////// 00110 void setup() 00111 { 00112 int e; 00113 // Print welcome message 00114 printf("-------------------------------------------------\n"); 00115 printf("------Simple LoRa temperature sensor-------------\n"); 00116 printf("--P.Pharm, adaptation NUCELO STM32 C.Dupaty------\n"); 00117 printf("-------------------------------------------------\n\n"); 00118 printf("!!!!!!!!! During configuration, all states numbers must read at 0\n"); 00119 00120 #ifdef TARGET_NUCLEO_L073RZ 00121 printf("NUCLEO L073RZ detected\n"); 00122 #else 00123 printf("WARNING, this software has been tested on NUCLEO L073RZ only !!!\n"); 00124 #endif 00125 00126 // Power ON the module 00127 sx1272.ON(); 00128 00129 #ifdef WITH_EEPROM 00130 // get config from EEPROM 00131 EEPROM.get(0, my_sx1272config); 00132 00133 // found a valid config? 00134 if (my_sx1272config.flag1==0x12 && my_sx1272config.flag2==0x34) { 00135 printf("Get back previous sx1272 config\n"); 00136 00137 // set sequence number for SX1272 library 00138 sx1272._packetNumber=my_sx1272config.seq; 00139 printf("Using packet sequence number of %d\n",sx1272._packetNumber); 00140 } 00141 else { 00142 // otherwise, write config and start over 00143 my_sx1272config.flag1=0x12; 00144 my_sx1272config.flag2=0x34; 00145 my_sx1272config.seq=sx1272._packetNumber; 00146 } 00147 #endif 00148 00149 int error_config_sx1272=0; 00150 00151 // Set transmission mode and print the result 00152 e = sx1272.setMode(loraMode); 00153 if (e) error_config_sx1272=1; 00154 printf("Setting Mode: state %d\n",e); 00155 00156 // enable carrier sense 00157 sx1272._enableCarrierSense=true; 00158 00159 // for LOW POWER 00160 sx1272._RSSIonSend=false; 00161 00162 00163 // Select frequency channel 00164 e = sx1272.setChannel(DEFAULT_CHANNEL); 00165 if (e) error_config_sx1272=1; 00166 printf("Setting Channel: state %d\n",e); 00167 00168 // Select amplifier line; PABOOST or RFO 00169 #ifdef PABOOST 00170 sx1272._needPABOOST=true; 00171 // previous way for setting output power 00172 // powerLevel='x'; 00173 #else 00174 // previous way for setting output power 00175 // powerLevel='M'; 00176 #endif 00177 00178 // previous way for setting output power 00179 // e = sx1272.setPower(powerLevel); 00180 00181 e = sx1272.setPowerDBM((uint8_t)MAX_DBM); 00182 if (e) error_config_sx1272=1; 00183 printf("Setting Power: state %d\n",e); 00184 00185 // Set the node address and print the result 00186 e = sx1272.setNodeAddress(node_addr); 00187 if (e) error_config_sx1272=1; 00188 printf("Setting node addr: state %d\n",e); 00189 00190 // Print a success message 00191 if (!error_config_sx1272) printf("SX1272 successfully configured\n"); 00192 else printf("ERREUR DE CONFIGURATION DU SX1272\n"); 00193 00194 wait_ms(500); 00195 } 00196 00197 ////////////////////////////////////////////////////////////// 00198 // main was named loop on Arduino 00199 ////////////////////////////////////////////////////////////// 00200 int main(void) // return int for cpp compatibility but never ending the program 00201 { 00202 long startSend; 00203 long endSend; 00204 uint8_t app_key_offset=0; 00205 int e; 00206 double temp; // variable temperature in this demo 00207 char float_str[20]; 00208 uint8_t message[100]; // the message that will be send to the gateway 00209 00210 setup(); 00211 00212 // main loop start here 00213 while(1) { 00214 00215 // this demo use a LM35DZ temerature captor 00216 temp_pin_power=1; // LM35DZ is powering by a simple GPIO 00217 wait_ms(200); 00218 temp = 0; 00219 int value; 00220 for (int i=0; i<10; i++) { 00221 // compute temperature for LM35DZ captor 00222 value = temp_pin_read.read_u16(); 00223 temp += ((double)value*50.0/8192.0)/10; 00224 printf("Reading ADC temperature %d/10 -> %d\n",i,value); 00225 wait_ms(100); 00226 } 00227 temp_pin_power=0; // LM35DZ power off 00228 printf("Mean temp is %f Cent\n",temp); 00229 // we have now temperature in the variable temp 00230 00231 #ifdef WITH_APPKEY 00232 app_key_offset = sizeof(my_appKey); 00233 // set the app key in the payload 00234 memcpy(message,my_appKey,app_key_offset); 00235 #endif 00236 00237 uint8_t r_size; 00238 00239 // convert float temp to string ASCII 00240 sprintf(float_str,"%2.2f",temp); 00241 #ifdef NEW_DATA_FIELD 00242 // this is for testing, uncomment if you just want to test, without a real temp sensor plugged 00243 //strcpy(float_str, "21.55567"); 00244 r_size=sprintf((char*)message+app_key_offset,"\\!#%d#TC/%s",field_index,float_str); 00245 #else 00246 // this is for testing, uncomment if you just want to test, without a real temp sensor plugged 00247 //strcpy(float_str, "21.55567"); 00248 r_size=sprintf((char*)message+app_key_offset,"\\!#%d#%s",field_index,float_str); 00249 #endif 00250 00251 printf("Sending %s\n",message+app_key_offset); 00252 printf("Real payload size is %d\n",r_size); 00253 00254 int pl=r_size+app_key_offset; 00255 sx1272.CarrierSense(); 00256 startSend=millis(); 00257 00258 #ifdef WITH_APPKEY 00259 // indicate that we have an appkey 00260 sx1272.setPacketType(PKT_TYPE_DATA | PKT_FLAG_DATA_WAPPKEY); 00261 #else 00262 // just a simple data packet 00263 sx1272.setPacketType(PKT_TYPE_DATA); 00264 #endif 00265 00266 // Send message to the gateway and print the result 00267 // with the app key if this feature is enabled 00268 #ifdef WITH_ACK 00269 int n_retry=NB_RETRIES; 00270 do { 00271 e = sx1272.sendPacketTimeoutACK(DEFAULT_DEST_ADDR, message, pl); 00272 if (e==3) printf("No ACK"); 00273 n_retry--; 00274 if (n_retry) printf("Retry"); 00275 else printf("Abort"); 00276 } while (e && n_retry); 00277 #else 00278 e = sx1272.sendPacketTimeout(DEFAULT_DEST_ADDR, message, pl); 00279 #endif 00280 endSend=millis(); 00281 #ifdef WITH_EEPROM 00282 // save packet number for next packet in case of reboot 00283 my_sx1272config.seq=sx1272._packetNumber; 00284 EEPROM.put(0, my_sx1272config); 00285 #endif 00286 00287 printf("LoRa pkt size %d\n",pl); 00288 printf("LoRa pkt seq %d\n",sx1272.packet_sent.packnum); 00289 printf("LoRa Sent in %ld\n",endSend-startSend); 00290 printf("LoRa Sent w/CAD in %ld\n", endSend-sx1272._startDoCad); 00291 printf("Packet sent, state %d\n",e); 00292 printf("Remaining ToA is %d\n",sx1272.getRemainingToA()); 00293 00294 // compute next time transmission in seconds 00295 int waitting = rand()%maxTime+minTime; // waitting in Sec 00296 printf("Switch to power saving mode\n"); 00297 e = sx1272.setSleepMode(); 00298 if (!e) 00299 printf("Successfully switch LoRa module in sleep mode\n"); 00300 else 00301 printf("Could not switch LoRa module in sleep mode\n"); 00302 // Deep sleep 00303 printf("Deep sleep allowed: %i for %d seconds\n", sleep_manager_can_deep_sleep(), waitting); 00304 wait(waitting); 00305 }// end loop 00306 00307 //return (0); useless here, the program never ends 00308 00309 }
Generated on Thu Jul 14 2022 04:46:34 by
![doxygen](doxygen.png)