├── ESP12-Gateway.jpg ├── Readme.md ├── EspComLora_Wifi_Gateway └── EspComLora_Wifi_Gateway.ino ├── EspComLora_Simple_temp_deepsleep └── EspComLora_Simple_temp_deepsleep.ino └── libraries └── SX1272 └── SX1272.h /ESP12-Gateway.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciolm/EspComLoRa/HEAD/ESP12-Gateway.jpg -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | #Ultra Low Cost LoRa Gateway with ESP8266 module 2 | ================================================= 3 | 4 | This project was based on the work of professor Congduc Pham's "Low Cost LoRa Gateway" project, available in https://github.com/CongducPham/LowCostLoRaGw 5 | 6 | It uses low cost (US$2) ESP8266 ESP-12 and LoRa modules with the chip Semtech SX1276 or HOPERF's RFM95W modules (about US$8). The same modules are used for both sensor nodes and the gateway, but in the sensor nodes the WiFi support is disabled to lower the power consumption to less than 250 microamperes. 7 | 8 | Arduino modules, like Pros (3.3V), can still be used on sensor nodes. 9 | 10 | The original gateway project (based on RPI) was very simplified in this version to adapt to ESP8266 modules, with only Thingspeak support for while. In the example, the gateway transmits to Thingspeak site three fields, with RSSI, SNR and the ADC voltage each 10 minutes. After the transmition, the nodes enters in "deeepsleep" mode. 11 | 12 | An example channel with two sensors in Thingspeak is https://thingspeak.com/channels/181180 13 | 14 | The original SX1272 library was changed to include "yield()" statements in the receive process loop. This statement free the processor to do other tasks, avoiding crashes. 15 | 16 | The connection to the HopeRF RFM95W LoRa Module is made using the standard SPI pins on ESP8266 (12(MISO),13(MOSI),14(SCK) and 15(CS)), but the CS pin can be changed in sx1272.h file. 17 | 18 | ESP-12 ---------- LoRa RFM95W 19 | 20 | GND ----------------- GND 21 | 22 | D13 ----------------- SCK 23 | 24 | D12 ----------------- MISO 25 | 26 | D11 ----------------- MOSI 27 | 28 | D15 ----------------- MSS 29 | 30 | VCC (3.3V)----------- VCC 31 | 32 | The ESP12 CH_PD pin must have to be pull-up to VCC with a 4K7 resistor, D0 and D15 to GND with 10K resistors. 33 | Also there a need to jump D16 and Reset and pull-up with a single 10K resistor to VCC to enable the "deepsleep" function on the sensor nodes (not the Gateway). 34 | 35 | The support for compiling the ESP8266 code on the Arduino IDE is documented in https://github.com/esp8266/Arduino 36 | 37 | -------------------------------------------------------------------------------- /EspComLora_Wifi_Gateway/EspComLora_Wifi_Gateway.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * LoRa 868 / 915MHz SX1272 LoRa module 3 | * 4 | * Copyright (C) Libelium Comunicaciones Distribuidas S.L. 5 | * http://www.libelium.com 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see http://www.gnu.org/licenses/. 19 | * 20 | * Version: 1.1 21 | * Design: David Gascón 22 | * Implementation: Covadonga Albiñana & Victor Boria 23 | * **************************************************************************** 24 | * Adapted for ESP8266 modules by Marcio Miguel - marcio.miguel@gmail.com 25 | * **************************************************************************** 26 | */ 27 | 28 | // Include the SX1272 and SPI library: 29 | #include "SX1272.h" 30 | #include 31 | #include 32 | #define SX1272_debug_mode 2 33 | #define RADIO_RFM92_95 34 | #define BAND900 35 | String apiKey = "thingspeak_api_key"; 36 | const char* ssid = "ssid"; 37 | const char* password = "password"; 38 | const char* server = "api.thingspeak.com"; 39 | int e; 40 | char my_packet[100]; 41 | int led = 2 ; 42 | boolean led_state = LOW; 43 | WiFiClient client; 44 | String my_packet_str; 45 | void setup() 46 | { 47 | int nCnt = 0; 48 | // Open serial communications and wait for port to open: 49 | Serial.begin(9600); 50 | 51 | WiFi.begin(ssid, password); 52 | Serial.println(); 53 | Serial.println(); 54 | Serial.print("Connecting to "); 55 | Serial.println(ssid); 56 | 57 | while (WiFi.status() != WL_CONNECTED) { 58 | delay(1000); 59 | Serial.print("."); 60 | nCnt ++; 61 | if(nCnt > 20) break; 62 | 63 | } 64 | Serial.println(""); 65 | Serial.println("WiFi connected"); 66 | 67 | pinMode(led, OUTPUT); 68 | 69 | // Print a start message 70 | Serial.println(F("SX1272 module and Arduino: receive packets without ACK")); 71 | 72 | // Power ON the module 73 | e = sx1272.ON(); 74 | Serial.print(F("Setting power ON: state ")); 75 | Serial.println(e, DEC); 76 | 77 | // Set transmission mode and print the result 78 | e = sx1272.setMode(1); 79 | Serial.print(F("Setting Mode: state ")); 80 | Serial.println(e, DEC); 81 | 82 | // Set header 83 | e = sx1272.setHeaderON(); 84 | Serial.print(F("Setting Header ON: state ")); 85 | Serial.println(e, DEC); 86 | 87 | // Select frequency channel 88 | e = sx1272.setChannel(CH_05_900); 89 | Serial.print(F("Setting Channel: state ")); 90 | Serial.println(e, DEC); 91 | 92 | 93 | // Select output power (Max, High or Low) 94 | e = sx1272.setPower('x'); 95 | Serial.print(F("Setting Power: state ")); 96 | Serial.println(e, DEC); 97 | 98 | // Set the node address and print the result 99 | e = sx1272.setNodeAddress(1); 100 | Serial.print(F("Setting node address: state ")); 101 | Serial.println(e, DEC); 102 | 103 | // Print a success message 104 | Serial.println(F("SX1272 successfully configured")); 105 | Serial.println(); 106 | } 107 | 108 | void loop(void) 109 | { 110 | 111 | // Receive message 112 | e = sx1272.receivePacketTimeout(10000); 113 | if ( e == 0 ) 114 | { 115 | Serial.print(F("Receive packet, state ")); 116 | Serial.println(e, DEC); 117 | 118 | for (unsigned int i = 0; i < sx1272.packet_received.length; i++) 119 | { 120 | my_packet[i] = (char)sx1272.packet_received.data[i]; 121 | } 122 | my_packet_str = String(my_packet); 123 | int Index1 = my_packet_str.indexOf('#'); 124 | int Index2 = my_packet_str.indexOf('#', Index1+1); 125 | int Index3 = my_packet_str.indexOf('#', Index2+1); 126 | 127 | String secondValue = my_packet_str.substring(Index1+1, Index2); 128 | String thirdValue = my_packet_str.substring(Index2+1, Index3); 129 | 130 | Serial.println(secondValue); 131 | Serial.println(thirdValue); 132 | Serial.print(F("Message: ")); 133 | Serial.println(my_packet); 134 | led_state = !led_state ; 135 | digitalWrite(led, led_state); // toggle the led state 136 | 137 | sx1272.getRSSIpacket(); 138 | sx1272.getSNR(); 139 | 140 | if (client.connect(server,80)) { // "184.106.153.149" or api.thingspeak.com 141 | String postStr = apiKey; 142 | if (secondValue == "2") { 143 | postStr +="&field1="; 144 | postStr += String(sx1272._RSSIpacket); 145 | postStr +="&field2="; 146 | postStr += String(sx1272._SNR); 147 | postStr +="&field3="; 148 | postStr += thirdValue; 149 | postStr += "\r\n\r\n"; 150 | } 151 | if (secondValue == "4") { 152 | postStr +="&field4="; 153 | postStr += String(sx1272._RSSIpacket); 154 | postStr +="&field5="; 155 | postStr += String(sx1272._SNR); 156 | postStr +="&field6="; 157 | postStr += thirdValue; 158 | postStr += "\r\n\r\n"; 159 | } 160 | client.print("POST /update HTTP/1.1\n"); 161 | client.print("Host: api.thingspeak.com\n"); 162 | client.print("Connection: close\n"); 163 | client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n"); 164 | client.print("Content-Type: application/x-www-form-urlencoded\n"); 165 | client.print("Content-Length: "); 166 | client.print(postStr.length()); 167 | client.print("\n\n"); 168 | client.print(postStr); 169 | Serial.println("Message sent to Thingspeak"); 170 | client.stop(); 171 | } 172 | 173 | Serial.print("Console: RSSI is "); 174 | Serial.print(sx1272._RSSIpacket,DEC); 175 | Serial.print(" dBm"); 176 | Serial.println(" "); 177 | Serial.print("Console: SNR is "); 178 | Serial.print(sx1272._SNR,DEC); 179 | Serial.println(" dBm"); 180 | } 181 | else { 182 | Serial.print(F("Receive packet, state ")); 183 | Serial.println(e, DEC); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /EspComLora_Simple_temp_deepsleep/EspComLora_Simple_temp_deepsleep.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * temperature sensor on analog 8 to test the LoRa gateway 3 | * 4 | * Copyright (C) 2016 Congduc Pham, University of Pau, France 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the program. If not, see . 18 | * 19 | ***************************************************************************** 20 | * Adapted for ESP8266 modules by Marcio Miguel - marcio.miguel@gmail.com 21 | ***************************************************************************** 22 | */ 23 | #include 24 | // Include the SX1272 25 | #include "SX1272.h" 26 | #include 27 | 28 | // IMPORTANT 29 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 30 | // please uncomment only 1 choice 31 | // 32 | // uncomment if your radio is an HopeRF RFM92W or RFM95W 33 | #define RADIO_RFM92_95 34 | // uncomment if your radio is a Modtronix inAirB (the one with +20dBm features), if inAir9, leave commented 35 | //#define RADIO_INAIR9B 36 | // uncomment if you only know that it has 20dBm feature 37 | //#define RADIO_20DBM 38 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 39 | 40 | // IMPORTANT 41 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 42 | // please uncomment only 1 choice 43 | //#define BAND868 44 | #define BAND900 45 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 46 | 47 | /////////////////////////////////////////////////////////////////// 48 | // COMMENT OR UNCOMMENT TO CHANGE FEATURES. 49 | // ONLY IF YOU KNOW WHAT YOU ARE DOING!!! OTHERWISE LEAVE AS IT IS 50 | #define WITH_EEPROM 51 | #define WITH_APPKEY 52 | #define FLOAT_TEMP 53 | #define NEW_DATA_FIELD 54 | #define LOW_POWER 55 | //#define LOW_POWER_HIBERNATE 56 | //#define WITH_ACK 57 | /////////////////////////////////////////////////////////////////// 58 | 59 | /////////////////////////////////////////////////////////////////// 60 | // CHANGE HERE THE LORA MODE, NODE ADDRESS 61 | #define LORAMODE 1 62 | #define node_addr 5 63 | ////////////////////////////////////////////////////////////////// 64 | 65 | /////////////////////////////////////////////////////////////////// 66 | // CHANGE HERE THE THINGSPEAK FIELD BETWEEN 1 AND 4 67 | #define field_index 2 68 | /////////////////////////////////////////////////////////////////// 69 | 70 | /////////////////////////////////////////////////////////////////// 71 | // CHANGE HERE THE READ PIN AND THE POWER PIN FOR THE TEMP. SENSOR 72 | #define TEMP_PIN_READ A0 73 | // use digital 8 to power the temperature sensor if needed 74 | #define TEMP_PIN_POWER 2 75 | /////////////////////////////////////////////////////////////////// 76 | 77 | /////////////////////////////////////////////////////////////////// 78 | // CHANGE HERE THE TIME IN MINUTES BETWEEN 2 READING & TRANSMISSION 79 | unsigned int idlePeriodInMin = 10; 80 | /////////////////////////////////////////////////////////////////// 81 | 82 | #ifdef WITH_APPKEY 83 | /////////////////////////////////////////////////////////////////// 84 | // CHANGE HERE THE APPKEY, BUT IF GW CHECKS FOR APPKEY, MUST BE 85 | // IN THE APPKEY LIST MAINTAINED BY GW. 86 | uint8_t my_appKey[4]={5, 6, 7, 8}; 87 | /////////////////////////////////////////////////////////////////// 88 | #endif 89 | 90 | #define PRINTLN Serial.println("") 91 | #define PRINT_CSTSTR(fmt,param) Serial.print(F(param)) 92 | #define PRINT_STR(fmt,param) Serial.print(param) 93 | #define PRINT_VALUE(fmt,param) Serial.print(param) 94 | #define FLUSHOUTPUT Serial.flush(); 95 | 96 | #define DEFAULT_DEST_ADDR 1 97 | 98 | #ifdef WITH_ACK 99 | #define NB_RETRIES 2 100 | #endif 101 | 102 | #define TEMP_SCALE 3300.0 103 | 104 | 105 | double temp; 106 | unsigned long lastTransmissionTime=0; 107 | unsigned long delayBeforeTransmit=0; 108 | char float_str[20]; 109 | uint8_t message[100]; 110 | int loraMode=LORAMODE; 111 | 112 | 113 | struct sx1272config { 114 | 115 | uint8_t flag1; 116 | uint8_t flag2; 117 | uint8_t seq; 118 | // can add other fields such as LoRa mode,... 119 | }; 120 | 121 | sx1272config my_sx1272config; 122 | 123 | 124 | void setup() 125 | { 126 | int e; 127 | 128 | // for the temperature sensor 129 | pinMode(TEMP_PIN_READ, INPUT); 130 | // and to power the temperature sensor 131 | pinMode(TEMP_PIN_POWER,OUTPUT); 132 | 133 | #ifdef LOW_POWER 134 | digitalWrite(TEMP_PIN_POWER,HIGH); 135 | #endif 136 | 137 | delay(3000); 138 | // Open serial communications and wait for port to open: 139 | Serial.begin(9600); 140 | 141 | // Print a start message 142 | PRINT_CSTSTR("%s","Simple LoRa temperature sensor\n"); 143 | 144 | 145 | // Power ON the module 146 | sx1272.ON(); 147 | 148 | EEPROM.begin(512); // needed for ESP8266 149 | EEPROM.get(0, my_sx1272config); 150 | 151 | // found a valid config? 152 | if (my_sx1272config.flag1==0x12 && my_sx1272config.flag2==0x34) { 153 | PRINT_CSTSTR("%s","Get back previous sx1272 config\n"); 154 | 155 | // set sequence number for SX1272 library 156 | sx1272._packetNumber=my_sx1272config.seq; 157 | PRINT_CSTSTR("%s","Using packet sequence number of "); 158 | PRINT_VALUE("%d", sx1272._packetNumber); 159 | PRINTLN; 160 | } 161 | else { 162 | // otherwise, write config and start over 163 | my_sx1272config.flag1=0x12; 164 | my_sx1272config.flag2=0x34; 165 | my_sx1272config.seq=sx1272._packetNumber; 166 | PRINT_CSTSTR("%s","New packet sequence"); 167 | PRINTLN; 168 | } 169 | 170 | 171 | // Set transmission mode and print the result 172 | e = sx1272.setMode(loraMode); 173 | PRINT_CSTSTR("%s","Setting Mode: state "); 174 | PRINT_VALUE("%d", e); 175 | PRINTLN; 176 | 177 | // enable carrier sense 178 | sx1272._enableCarrierSense=true; 179 | #ifdef LOW_POWER 180 | // TODO: with low power, when setting the radio module in sleep mode 181 | // there seem to be some issue with RSSI reading 182 | sx1272._RSSIonSend=false; 183 | #endif 184 | 185 | #ifdef BAND868 186 | // Select frequency channel 187 | e = sx1272.setChannel(CH_10_868); 188 | #else // assuming #defined BAND900 189 | // Select frequency channel 190 | e = sx1272.setChannel(CH_05_900); 191 | #endif 192 | PRINT_CSTSTR("%s","Setting Channel: state "); 193 | PRINT_VALUE("%d", e); 194 | PRINTLN; 195 | 196 | // Select output power (Max, High or Low) 197 | #if defined RADIO_RFM92_95 || defined RADIO_INAIR9B 198 | e = sx1272.setPower('x'); 199 | #else 200 | e = sx1272.setPower('M'); 201 | #endif 202 | 203 | PRINT_CSTSTR("%s","Setting Power: state "); 204 | PRINT_VALUE("%d", e); 205 | PRINTLN; 206 | 207 | // Set the node address and print the result 208 | e = sx1272.setNodeAddress(node_addr); 209 | PRINT_CSTSTR("%s","Setting node addr: state "); 210 | PRINT_VALUE("%d", e); 211 | PRINTLN; 212 | 213 | // Print a success message 214 | PRINT_CSTSTR("%s","SX1272 successfully configured\n"); 215 | 216 | delay(500); 217 | } 218 | 219 | char *ftoa(char *a, double f, int precision) 220 | { 221 | long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000}; 222 | 223 | char *ret = a; 224 | long heiltal = (long)f; 225 | itoa(heiltal, a, 10); 226 | while (*a != '\0') a++; 227 | *a++ = '.'; 228 | long desimal = abs((long)((f - heiltal) * p[precision])); 229 | itoa(desimal, a, 10); 230 | return ret; 231 | } 232 | 233 | 234 | void loop(void) 235 | { 236 | long startSend; 237 | long endSend; 238 | uint8_t app_key_offset=0; 239 | int e; 240 | 241 | #ifndef LOW_POWER 242 | // 600000+random(15,60)*1000 243 | if (millis()-lastTransmissionTime > delayBeforeTransmit) { 244 | #endif 245 | #ifdef LOW_POWER 246 | digitalWrite(TEMP_PIN_POWER,HIGH); 247 | // security? 248 | delay(200); 249 | int value = analogRead(TEMP_PIN_READ); 250 | digitalWrite(TEMP_PIN_POWER,LOW); 251 | #else 252 | int value = analogRead(TEMP_PIN_READ); 253 | #endif 254 | 255 | // change here how the temperature should be computed depending on your sensor type 256 | // 257 | temp = value*TEMP_SCALE/1024.0; 258 | 259 | PRINT_CSTSTR("%s","Reading "); 260 | PRINT_VALUE("%d", value); 261 | PRINTLN; 262 | 263 | //temp = temp - 0.5; 264 | temp = temp / 10.0; 265 | 266 | PRINT_CSTSTR("%s","Temp is "); 267 | PRINT_VALUE("%f", temp); 268 | PRINTLN; 269 | 270 | #ifdef WITH_APPKEY 271 | app_key_offset = sizeof(my_appKey); 272 | // set the app key in the payload 273 | memcpy(message,my_appKey,app_key_offset); 274 | #endif 275 | 276 | uint8_t r_size; 277 | 278 | // then use app_key_offset to skip the app key 279 | 280 | #ifdef FLOAT_TEMP 281 | ftoa(float_str,temp,2); 282 | 283 | #ifdef NEW_DATA_FIELD 284 | // this is for testing, uncomment if you just want to test, without a real temp sensor plugged 285 | //strcpy(float_str, "21.55567"); 286 | r_size=sprintf((char*)message+app_key_offset,"\\!#%d#%s",field_index,float_str); 287 | #else 288 | // this is for testing, uncomment if you just want to test, without a real temp sensor plugged 289 | //strcpy(float_str, "21.55567"); 290 | r_size=sprintf((char*)message+app_key_offset,"\\!#%d#%s",field_index,float_str); 291 | #endif 292 | 293 | #else 294 | 295 | #ifdef NEW_DATA_FIELD 296 | r_size=sprintf((char*)message+app_key_offset, "\\!#%d#%d", field_index, (int)temp); 297 | #else 298 | r_size=sprintf((char*)message+app_key_offset, "\\!#%d#%d", field_index, (int)temp); 299 | #endif 300 | #endif 301 | 302 | PRINT_CSTSTR("%s","Sending "); 303 | PRINT_STR("%s",(char*)(message+app_key_offset)); 304 | PRINTLN; 305 | 306 | PRINT_CSTSTR("%s","Real payload size is "); 307 | PRINT_VALUE("%d", r_size); 308 | PRINTLN; 309 | 310 | int pl=r_size+app_key_offset; 311 | 312 | sx1272.CarrierSense(); 313 | 314 | startSend=millis(); 315 | 316 | #ifdef WITH_APPKEY 317 | // indicate that we have an appkey 318 | sx1272.setPacketType(PKT_TYPE_DATA | PKT_FLAG_DATA_WAPPKEY); 319 | #else 320 | // just a simple data packet 321 | sx1272.setPacketType(PKT_TYPE_DATA); 322 | #endif 323 | 324 | // Send message to the gateway and print the result 325 | // with the app key if this feature is enabled 326 | #ifdef WITH_ACK 327 | int n_retry=NB_RETRIES; 328 | 329 | do { 330 | e = sx1272.sendPacketTimeoutACK(DEFAULT_DEST_ADDR, message, pl); 331 | 332 | if (e==3) 333 | PRINT_CSTSTR("%s","No ACK"); 334 | 335 | n_retry--; 336 | 337 | if (n_retry) 338 | PRINT_CSTSTR("%s","Retry"); 339 | else 340 | PRINT_CSTSTR("%s","Abort"); 341 | 342 | } while (e && n_retry); 343 | #else 344 | e = sx1272.sendPacketTimeout(DEFAULT_DEST_ADDR, message, pl); 345 | #endif 346 | endSend=millis(); 347 | 348 | 349 | // save packet number for next packet in case of reboot 350 | my_sx1272config.seq=sx1272._packetNumber; 351 | EEPROM.put(0, my_sx1272config); 352 | EEPROM.commit(); 353 | 354 | PRINT_CSTSTR("%s","LoRa pkt size "); 355 | PRINT_VALUE("%d", pl); 356 | PRINTLN; 357 | 358 | PRINT_CSTSTR("%s","LoRa pkt seq "); 359 | PRINT_VALUE("%d", sx1272.packet_sent.packnum); 360 | PRINTLN; 361 | 362 | PRINT_CSTSTR("%s","LoRa Sent in "); 363 | PRINT_VALUE("%ld", endSend-startSend); 364 | PRINTLN; 365 | 366 | PRINT_CSTSTR("%s","LoRa Sent w/CAD in "); 367 | PRINT_VALUE("%ld", endSend-sx1272._startDoCad); 368 | PRINTLN; 369 | 370 | PRINT_CSTSTR("%s","Packet sent, state "); 371 | PRINT_VALUE("%d", e); 372 | PRINTLN; 373 | 374 | #ifdef LOW_POWER 375 | PRINT_CSTSTR("%s","Switch to power saving mode\n"); 376 | 377 | e = sx1272.setSleepMode(); 378 | 379 | if (!e) 380 | PRINT_CSTSTR("%s","Successfully switch LoRa module in sleep mode\n"); 381 | else 382 | PRINT_CSTSTR("%s","Could not switch LoRa module in sleep mode\n"); 383 | 384 | FLUSHOUTPUT 385 | delay(50); 386 | 387 | PRINT_CSTSTR("%s","Entering ESP Deep Sleep"); 388 | PRINTLN; 389 | ESP.deepSleep(600000000); // 600 seconds 390 | 391 | #else 392 | // use a random part also to avoid collision 393 | PRINT_VALUE("%ld", lastTransmissionTime); 394 | PRINTLN; 395 | PRINT_CSTSTR("%s","Will send next value in\n"); 396 | lastTransmissionTime=millis(); 397 | delayBeforeTransmit=idlePeriodInMin*60*1000+random(15,60)*1000; 398 | PRINT_VALUE("%ld", delayBeforeTransmit); 399 | PRINTLN; 400 | 401 | #endif 402 | 403 | delay(50); 404 | } 405 | 406 | -------------------------------------------------------------------------------- /libraries/SX1272/SX1272.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Library for LoRa 868 / 915MHz SX1272 LoRa module 3 | * 4 | * Copyright (C) Libelium Comunicaciones Distribuidas S.L. 5 | * http://www.libelium.com 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see http://www.gnu.org/licenses/. 19 | * 20 | * Version: 1.1 21 | * Design: David Gascón 22 | * Implementation: Covadonga Albiñana & Victor Boria 23 | */ 24 | 25 | #ifndef SX1272_h 26 | #define SX1272_h 27 | 28 | /****************************************************************************** 29 | * Includes 30 | ******************************************************************************/ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #ifndef inttypes_h 38 | #include 39 | #endif 40 | 41 | /****************************************************************************** 42 | * Definitions & Declarations 43 | *****************************************************************************/ 44 | 45 | // added by C. Pham 46 | #define W_REQUESTED_ACK 47 | //#define W_NET_KEY 48 | //#define W_INITIALIZATION 49 | #define SX1272_RST 3 50 | 51 | 52 | #if defined ARDUINO_AVR_PRO || defined ARDUINO_AVR_NANO || defined ARDUINO_AVR_MINI || defined __MK20DX256__ 53 | #define SX1272_SS 10 54 | #else 55 | #define SX1272_SS 15 //original 2, for esp8266 15 56 | #endif 57 | 58 | 59 | #define SX1272Chip 0 60 | #define SX1276Chip 1 61 | // end 62 | 63 | #define SX1272_debug_mode 0 64 | 65 | //! MACROS // 66 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) // read a bit 67 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) // set bit to '1' 68 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) // set bit to '0' 69 | 70 | //! REGISTERS // 71 | 72 | #define REG_FIFO 0x00 73 | #define REG_OP_MODE 0x01 74 | #define REG_BITRATE_MSB 0x02 75 | #define REG_BITRATE_LSB 0x03 76 | #define REG_FDEV_MSB 0x04 77 | #define REG_FDEV_LSB 0x05 78 | #define REG_FRF_MSB 0x06 79 | #define REG_FRF_MID 0x07 80 | #define REG_FRF_LSB 0x08 81 | #define REG_PA_CONFIG 0x09 82 | #define REG_PA_RAMP 0x0A 83 | #define REG_OCP 0x0B 84 | #define REG_LNA 0x0C 85 | #define REG_RX_CONFIG 0x0D 86 | #define REG_FIFO_ADDR_PTR 0x0D 87 | #define REG_RSSI_CONFIG 0x0E 88 | #define REG_FIFO_TX_BASE_ADDR 0x0E 89 | #define REG_RSSI_COLLISION 0x0F 90 | #define REG_FIFO_RX_BASE_ADDR 0x0F 91 | #define REG_RSSI_THRESH 0x10 92 | #define REG_FIFO_RX_CURRENT_ADDR 0x10 93 | #define REG_RSSI_VALUE_FSK 0x11 94 | #define REG_IRQ_FLAGS_MASK 0x11 95 | #define REG_RX_BW 0x12 96 | #define REG_IRQ_FLAGS 0x12 97 | #define REG_AFC_BW 0x13 98 | #define REG_RX_NB_BYTES 0x13 99 | #define REG_OOK_PEAK 0x14 100 | #define REG_RX_HEADER_CNT_VALUE_MSB 0x14 101 | #define REG_OOK_FIX 0x15 102 | #define REG_RX_HEADER_CNT_VALUE_LSB 0x15 103 | #define REG_OOK_AVG 0x16 104 | #define REG_RX_PACKET_CNT_VALUE_MSB 0x16 105 | #define REG_RX_PACKET_CNT_VALUE_LSB 0x17 106 | #define REG_MODEM_STAT 0x18 107 | #define REG_PKT_SNR_VALUE 0x19 108 | #define REG_AFC_FEI 0x1A 109 | #define REG_PKT_RSSI_VALUE 0x1A 110 | #define REG_AFC_MSB 0x1B 111 | #define REG_RSSI_VALUE_LORA 0x1B 112 | #define REG_AFC_LSB 0x1C 113 | #define REG_HOP_CHANNEL 0x1C 114 | #define REG_FEI_MSB 0x1D 115 | #define REG_MODEM_CONFIG1 0x1D 116 | #define REG_FEI_LSB 0x1E 117 | #define REG_MODEM_CONFIG2 0x1E 118 | #define REG_PREAMBLE_DETECT 0x1F 119 | #define REG_SYMB_TIMEOUT_LSB 0x1F 120 | #define REG_RX_TIMEOUT1 0x20 121 | #define REG_PREAMBLE_MSB_LORA 0x20 122 | #define REG_RX_TIMEOUT2 0x21 123 | #define REG_PREAMBLE_LSB_LORA 0x21 124 | #define REG_RX_TIMEOUT3 0x22 125 | #define REG_PAYLOAD_LENGTH_LORA 0x22 126 | #define REG_RX_DELAY 0x23 127 | #define REG_MAX_PAYLOAD_LENGTH 0x23 128 | #define REG_OSC 0x24 129 | #define REG_HOP_PERIOD 0x24 130 | #define REG_PREAMBLE_MSB_FSK 0x25 131 | #define REG_FIFO_RX_BYTE_ADDR 0x25 132 | #define REG_PREAMBLE_LSB_FSK 0x26 133 | // added by C. Pham 134 | #define REG_MODEM_CONFIG3 0x26 135 | // end 136 | #define REG_SYNC_CONFIG 0x27 137 | #define REG_SYNC_VALUE1 0x28 138 | #define REG_SYNC_VALUE2 0x29 139 | #define REG_SYNC_VALUE3 0x2A 140 | #define REG_SYNC_VALUE4 0x2B 141 | #define REG_SYNC_VALUE5 0x2C 142 | #define REG_SYNC_VALUE6 0x2D 143 | #define REG_SYNC_VALUE7 0x2E 144 | #define REG_SYNC_VALUE8 0x2F 145 | #define REG_PACKET_CONFIG1 0x30 146 | #define REG_PACKET_CONFIG2 0x31 147 | #define REG_DETECT_OPTIMIZE 0x31 148 | #define REG_PAYLOAD_LENGTH_FSK 0x32 149 | #define REG_NODE_ADRS 0x33 150 | #define REG_BROADCAST_ADRS 0x34 151 | #define REG_FIFO_THRESH 0x35 152 | #define REG_SEQ_CONFIG1 0x36 153 | #define REG_SEQ_CONFIG2 0x37 154 | #define REG_DETECTION_THRESHOLD 0x37 155 | #define REG_TIMER_RESOL 0x38 156 | // added by C. Pham 157 | #define REG_SYNC_WORD 0x39 158 | //end 159 | #define REG_TIMER1_COEF 0x39 160 | #define REG_TIMER2_COEF 0x3A 161 | #define REG_IMAGE_CAL 0x3B 162 | #define REG_TEMP 0x3C 163 | #define REG_LOW_BAT 0x3D 164 | #define REG_IRQ_FLAGS1 0x3E 165 | #define REG_IRQ_FLAGS2 0x3F 166 | #define REG_DIO_MAPPING1 0x40 167 | #define REG_DIO_MAPPING2 0x41 168 | #define REG_VERSION 0x42 169 | #define REG_AGC_REF 0x43 170 | #define REG_AGC_THRESH1 0x44 171 | #define REG_AGC_THRESH2 0x45 172 | #define REG_AGC_THRESH3 0x46 173 | #define REG_PLL_HOP 0x4B 174 | #define REG_TCXO 0x58 175 | #define REG_PA_DAC 0x5A 176 | #define REG_PLL 0x5C 177 | #define REG_PLL_LOW_PN 0x5E 178 | #define REG_FORMER_TEMP 0x6C 179 | #define REG_BIT_RATE_FRAC 0x70 180 | 181 | // added by C. Pham 182 | // copied from LoRaMAC-Node 183 | /*! 184 | * RegImageCal 185 | */ 186 | #define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F 187 | #define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 188 | #define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default 189 | 190 | #define RF_IMAGECAL_IMAGECAL_MASK 0xBF 191 | #define RF_IMAGECAL_IMAGECAL_START 0x40 192 | 193 | #define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 194 | #define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default 195 | 196 | #define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 197 | #define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 198 | 199 | #define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 200 | #define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 201 | #define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default 202 | #define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 203 | #define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 204 | 205 | #define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE 206 | #define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default 207 | #define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 208 | 209 | // added by C. Pham 210 | // The crystal oscillator frequency of the module 211 | #define RH_LORA_FXOSC 32000000.0 212 | 213 | // The Frequency Synthesizer step = RH_LORA_FXOSC / 2^^19 214 | #define RH_LORA_FCONVERT (524288 / RH_LORA_FXOSC) 215 | 216 | // Frf = frf(Hz)*2^19/RH_LORA_FXOSC 217 | 218 | ///// 219 | 220 | //FREQUENCY CHANNELS: 221 | const uint32_t CH_10_868 = 0xD84CCC; // channel 10, central freq = 865.20MHz 222 | // = 865200000*RH_LORA_FCONVERT 223 | const uint32_t CH_11_868 = 0xD86000; // channel 11, central freq = 865.50MHz 224 | const uint32_t CH_12_868 = 0xD87333; // channel 12, central freq = 865.80MHz 225 | const uint32_t CH_13_868 = 0xD88666; // channel 13, central freq = 866.10MHz 226 | const uint32_t CH_14_868 = 0xD89999; // channel 14, central freq = 866.40MHz 227 | const uint32_t CH_15_868 = 0xD8ACCC; // channel 15, central freq = 866.70MHz 228 | const uint32_t CH_16_868 = 0xD8C000; // channel 16, central freq = 867.00MHz 229 | const uint32_t CH_17_868 = 0xD90000; // channel 17, central freq = 868.00MHz 230 | 231 | // added by C. Pham 232 | const uint32_t CH_18_868 = 0xD90666; // 868.1MHz for LoRaWAN test 233 | // end 234 | const uint32_t CH_00_900 = 0xE1C51E; // channel 00, central freq = 903.08MHz 235 | const uint32_t CH_01_900 = 0xE24F5C; // channel 01, central freq = 905.24MHz 236 | const uint32_t CH_02_900 = 0xE2D999; // channel 02, central freq = 907.40MHz 237 | const uint32_t CH_03_900 = 0xE363D7; // channel 03, central freq = 909.56MHz 238 | const uint32_t CH_04_900 = 0xE3EE14; // channel 04, central freq = 911.72MHz 239 | const uint32_t CH_05_900 = 0xE47851; // channel 05, central freq = 913.88MHz 240 | const uint32_t CH_06_900 = 0xE5028F; // channel 06, central freq = 916.04MHz 241 | const uint32_t CH_07_900 = 0xE58CCC; // channel 07, central freq = 918.20MHz 242 | const uint32_t CH_08_900 = 0xE6170A; // channel 08, central freq = 920.36MHz 243 | const uint32_t CH_09_900 = 0xE6A147; // channel 09, central freq = 922.52MHz 244 | const uint32_t CH_10_900 = 0xE72B85; // channel 10, central freq = 924.68MHz 245 | const uint32_t CH_11_900 = 0xE7B5C2; // channel 11, central freq = 926.84MHz 246 | const uint32_t CH_12_900 = 0xE4C000; // default channel 915MHz, the module is configured with it 247 | 248 | //LORA BANDWIDTH: 249 | // modified by C. Pham 250 | const uint8_t SX1272_BW_125 = 0x00; 251 | const uint8_t SX1272_BW_250 = 0x01; 252 | const uint8_t SX1272_BW_500 = 0x02; 253 | 254 | // use the following constants with setBW() 255 | const uint8_t BW_7_8 = 0x00; 256 | const uint8_t BW_10_4 = 0x01; 257 | const uint8_t BW_15_6 = 0x02; 258 | const uint8_t BW_20_8 = 0x03; 259 | const uint8_t BW_31_25 = 0x04; 260 | const uint8_t BW_41_7 = 0x05; 261 | const uint8_t BW_62_5 = 0x06; 262 | const uint8_t BW_125 = 0x07; 263 | const uint8_t BW_250 = 0x08; 264 | const uint8_t BW_500 = 0x09; 265 | // end 266 | 267 | const double SignalBwLog[] = 268 | { 269 | 5.0969100130080564143587833158265, 270 | 5.397940008672037609572522210551, 271 | 5.6989700043360188047862611052755 272 | }; 273 | 274 | //LORA CODING RATE: 275 | const uint8_t CR_5 = 0x01; 276 | const uint8_t CR_6 = 0x02; 277 | const uint8_t CR_7 = 0x03; 278 | const uint8_t CR_8 = 0x04; 279 | 280 | //LORA SPREADING FACTOR: 281 | const uint8_t SF_6 = 0x06; 282 | const uint8_t SF_7 = 0x07; 283 | const uint8_t SF_8 = 0x08; 284 | const uint8_t SF_9 = 0x09; 285 | const uint8_t SF_10 = 0x0A; 286 | const uint8_t SF_11 = 0x0B; 287 | const uint8_t SF_12 = 0x0C; 288 | 289 | //LORA MODES: 290 | const uint8_t LORA_SLEEP_MODE = 0x80; 291 | const uint8_t LORA_STANDBY_MODE = 0x81; 292 | const uint8_t LORA_TX_MODE = 0x83; 293 | const uint8_t LORA_RX_MODE = 0x85; 294 | 295 | // added by C. Pham 296 | const uint8_t LORA_CAD_MODE = 0x87; 297 | #define LNA_MAX_GAIN 0x23 298 | #define LNA_OFF_GAIN 0x00 299 | #define LNA_LOW_GAIN 0x20 300 | // end 301 | 302 | const uint8_t LORA_STANDBY_FSK_REGS_MODE = 0xC1; 303 | 304 | //FSK MODES: 305 | const uint8_t FSK_SLEEP_MODE = 0x00; 306 | const uint8_t FSK_STANDBY_MODE = 0x01; 307 | const uint8_t FSK_TX_MODE = 0x03; 308 | const uint8_t FSK_RX_MODE = 0x05; 309 | 310 | //OTHER CONSTANTS: 311 | 312 | const uint8_t HEADER_ON = 0; 313 | const uint8_t HEADER_OFF = 1; 314 | const uint8_t CRC_ON = 1; 315 | const uint8_t CRC_OFF = 0; 316 | const uint8_t LORA = 1; 317 | const uint8_t FSK = 0; 318 | const uint8_t BROADCAST_0 = 0x00; 319 | const uint8_t MAX_LENGTH = 255; 320 | const uint8_t MAX_PAYLOAD = 251; 321 | const uint8_t MAX_LENGTH_FSK = 64; 322 | const uint8_t MAX_PAYLOAD_FSK = 60; 323 | //modified by C. Pham, 7 instead of 5 because we added a type field which should be PKT_TYPE_ACK and the SNR 324 | const uint8_t ACK_LENGTH = 7; 325 | // added by C. Pham 326 | #ifdef W_NET_KEY 327 | const uint8_t NET_KEY_LENGTH=2; 328 | const uint8_t OFFSET_PAYLOADLENGTH = 4+NET_KEY_LENGTH; 329 | const uint8_t net_key_0 = 0x12; 330 | const uint8_t net_key_1 = 0x34; 331 | #else 332 | // modified by C. Pham to remove the retry field and the length field 333 | // which will be replaced by packet type field 334 | const uint8_t OFFSET_PAYLOADLENGTH = 4; 335 | #endif 336 | const uint8_t OFFSET_RSSI = 137; 337 | const uint8_t NOISE_FIGURE = 6.0; 338 | const uint8_t NOISE_ABSOLUTE_ZERO = 174.0; 339 | const uint16_t MAX_TIMEOUT = 8000; //8000 msec = 8.0 sec 340 | const uint16_t MAX_WAIT = 12000; //12000 msec = 12.0 sec 341 | const uint8_t MAX_RETRIES = 5; 342 | const uint8_t CORRECT_PACKET = 0; 343 | const uint8_t INCORRECT_PACKET = 1; 344 | 345 | // added by C. Pham 346 | // Packet type definition 347 | 348 | #define PKT_TYPE_MASK 0xF0 349 | #define PKT_FLAG_MASK 0x0F 350 | 351 | #define PKT_TYPE_DATA 0x10 352 | #define PKT_TYPE_ACK 0x20 353 | 354 | #define PKT_FLAG_ACK_REQ 0x08 355 | #define PKT_FLAG_DATA_ENCRYPTED 0x04 356 | #define PKT_FLAG_DATA_WAPPKEY 0x02 357 | #define PKT_FLAG_DATA_ISBINARY 0x01 358 | 359 | //! Structure : 360 | /*! 361 | */ 362 | struct pack 363 | { 364 | // added by C. Pham 365 | #ifdef W_NET_KEY 366 | uint8_t netkey[NET_KEY_LENGTH]; 367 | #endif 368 | //! Structure Variable : Packet destination 369 | /*! 370 | */ 371 | uint8_t dst; 372 | 373 | // added by C. Pham 374 | //! Structure Variable : Packet type 375 | /*! 376 | */ 377 | uint8_t type; 378 | 379 | //! Structure Variable : Packet source 380 | /*! 381 | */ 382 | uint8_t src; 383 | 384 | //! Structure Variable : Packet number 385 | /*! 386 | */ 387 | uint8_t packnum; 388 | 389 | // modified by C. Pham 390 | // will not be used in the transmitted packet 391 | //! Structure Variable : Packet length 392 | /*! 393 | */ 394 | uint8_t length; 395 | 396 | //! Structure Variable : Packet payload 397 | /*! 398 | */ 399 | uint8_t data[MAX_PAYLOAD]; 400 | 401 | // modified by C. Pham 402 | // will not be used in the transmitted packet 403 | //! Structure Variable : Retry number 404 | /*! 405 | */ 406 | uint8_t retry; 407 | }; 408 | 409 | /****************************************************************************** 410 | * Class 411 | ******************************************************************************/ 412 | 413 | //! SX1272 Class 414 | /*! 415 | SX1272 Class defines all the variables and functions used to manage 416 | SX1272 modules. 417 | */ 418 | class SX1272 419 | { 420 | 421 | public: 422 | 423 | //! class constructor 424 | /*! 425 | It does nothing 426 | \param void 427 | \return void 428 | */ 429 | SX1272(); 430 | 431 | //! It puts the module ON 432 | /*! 433 | \param void 434 | \return uint8_t setLORA state 435 | */ 436 | uint8_t ON(); 437 | 438 | //! It puts the module OFF 439 | /*! 440 | \param void 441 | \return void 442 | */ 443 | void OFF(); 444 | 445 | //! It reads an internal module register. 446 | /*! 447 | \param byte address : address register to read from. 448 | \return the content of the register. 449 | */ 450 | byte readRegister(byte address); 451 | 452 | //! It writes in an internal module register. 453 | /*! 454 | \param byte address : address register to write in. 455 | \param byte data : value to write in the register. 456 | */ 457 | void writeRegister(byte address, byte data); 458 | 459 | //! It clears the interruption flags. 460 | /*! 461 | \param void 462 | \return void 463 | */ 464 | void clearFlags(); 465 | 466 | //! It sets the LoRa mode on. 467 | /*! 468 | It stores in global '_LORA' variable '1' when success 469 | \return '0' on success, '1' otherwise 470 | */ 471 | uint8_t setLORA(); 472 | 473 | //! It sets the FSK mode on. 474 | /*! 475 | It stores in global '_FSK' variable '1' when success 476 | \return '0' on success, '1' otherwise 477 | */ 478 | uint8_t setFSK(); 479 | 480 | //! It gets the BW, SF and CR of the module. 481 | /*! 482 | It stores in global '_bandwidth' variable the BW 483 | It stores in global '_codingRate' variable the CR 484 | It stores in global '_spreadingFactor' variable the SF 485 | \return '0' on success, '1' otherwise 486 | */ 487 | uint8_t getMode(); 488 | 489 | //! It sets the BW, SF and CR of the module. 490 | /*! 491 | It stores in global '_bandwidth' variable the BW 492 | It stores in global '_codingRate' variable the CR 493 | It stores in global '_spreadingFactor' variable the SF 494 | \param uint8_t mode : there is a mode number to different values of 495 | the configured parameters with this function. 496 | \return '0' on success, '1' otherwise 497 | */ 498 | int8_t setMode(uint8_t mode); 499 | 500 | //! It gets the header mode configured. 501 | /*! 502 | It stores in global '_header' variable '0' when header is sent 503 | (explicit header mode) or '1' when is not sent (implicit header 504 | mode). 505 | \return '0' on success, '1' otherwise 506 | */ 507 | uint8_t getHeader(); 508 | 509 | //! It sets explicit header mode. 510 | /*! 511 | It stores in global '_header' variable '1' when success 512 | \return '0' on success, '1' otherwise 513 | */ 514 | int8_t setHeaderON(); 515 | 516 | //! It sets implicit header mode. 517 | /*! 518 | It stores in global '_header' variable '0' when success 519 | \return '0' on success, '1' otherwise 520 | */ 521 | int8_t setHeaderOFF(); 522 | 523 | //! It gets the CRC configured. 524 | /*! 525 | It stores in global '_CRC' variable '1' enabling CRC generation on 526 | payload, or '0' disabling the CRC. 527 | \return '0' on success, '1' otherwise 528 | */ 529 | uint8_t getCRC(); 530 | 531 | //! It sets CRC on. 532 | /*! 533 | It stores in global '_CRC' variable '1' when success 534 | \return '0' on success, '1' otherwise 535 | */ 536 | uint8_t setCRC_ON(); 537 | 538 | //! It sets CRC off. 539 | /*! 540 | It stores in global '_CRC' variable '0' when success 541 | \return '0' on success, '1' otherwise 542 | */ 543 | uint8_t setCRC_OFF(); 544 | 545 | //! It is true if the SF selected exists. 546 | /*! 547 | \param uint8_t spr : spreading factor value to check. 548 | \return 'true' on success, 'false' otherwise 549 | */ 550 | boolean isSF(uint8_t spr); 551 | 552 | //! It gets the SF configured. 553 | /*! 554 | It stores in global '_spreadingFactor' variable the current value of SF 555 | \return '0' on success, '1' otherwise 556 | */ 557 | int8_t getSF(); 558 | 559 | //! It sets the SF. 560 | /*! 561 | It stores in global '_spreadingFactor' variable the current value of SF 562 | \param uint8_t spr : spreading factor value to set in the configuration. 563 | \return '0' on success, '1' otherwise 564 | */ 565 | uint8_t setSF(uint8_t spr); 566 | 567 | //! It is true if the BW selected exists. 568 | /*! 569 | \param uint16_t band : bandwidth value to check. 570 | \return 'true' on success, 'false' otherwise 571 | */ 572 | boolean isBW(uint16_t band); 573 | 574 | //! It gets the BW configured. 575 | /*! 576 | It stores in global '_bandwidth' variable the BW selected 577 | in the configuration 578 | \return '0' on success, '1' otherwise 579 | */ 580 | int8_t getBW(); 581 | 582 | //! It sets the BW. 583 | /*! 584 | It stores in global '_bandwidth' variable the BW selected 585 | in the configuration 586 | \param uint16_t band : bandwidth value to set in the configuration. 587 | \return '0' on success, '1' otherwise 588 | */ 589 | int8_t setBW(uint16_t band); 590 | 591 | //! It is true if the CR selected exists. 592 | /*! 593 | \param uint8_t cod : the coding rate value to check. 594 | \return 'true' on success, 'false' otherwise 595 | */ 596 | boolean isCR(uint8_t cod); 597 | 598 | //! It gets the CR configured. 599 | /*! 600 | It stores in global '_codingRate' variable the CR selected 601 | in the configuration 602 | \return '0' on success, '1' otherwise 603 | */ 604 | int8_t getCR(); 605 | 606 | //! It sets the CR. 607 | /*! 608 | It stores in global '_codingRate' variable the CR selected 609 | in the configuration 610 | \param uint8_t cod : coding rate value to set in the configuration. 611 | \return '0' on success, '1' otherwise 612 | */ 613 | int8_t setCR(uint8_t cod); 614 | 615 | 616 | //! It is true if the channel selected exists. 617 | /*! 618 | \param uint32_t ch : frequency channel value to check. 619 | \return 'true' on success, 'false' otherwise 620 | */ 621 | boolean isChannel(uint32_t ch); 622 | 623 | //! It gets frequency channel the module is using. 624 | /*! 625 | It stores in global '_channel' variable the frequency channel 626 | \return '0' on success, '1' otherwise 627 | */ 628 | uint8_t getChannel(); 629 | 630 | //! It sets frequency channel the module is using. 631 | /*! 632 | It stores in global '_channel' variable the frequency channel 633 | \param uint32_t ch : frequency channel value to set in the configuration. 634 | \return '0' on success, '1' otherwise 635 | */ 636 | int8_t setChannel(uint32_t ch); 637 | 638 | //! It gets the output power of the signal. 639 | /*! 640 | It stores in global '_power' variable the output power of the signal 641 | \return '0' on success, '1' otherwise 642 | */ 643 | uint8_t getPower(); 644 | 645 | //! It sets the output power of the signal. 646 | /*! 647 | It stores in global '_power' variable the output power of the signal 648 | \param char p : 'M', 'H' or 'L' if you want Maximum, High or Low 649 | output power signal. 650 | \return '0' on success, '1' otherwise 651 | */ 652 | int8_t setPower(char p); 653 | 654 | //! It sets the output power of the signal. 655 | /*! 656 | It stores in global '_power' variable the output power of the signal 657 | \param uint8_t pow : value to set as output power. 658 | \return '0' on success, '1' otherwise 659 | */ 660 | int8_t setPowerNum(uint8_t pow); 661 | 662 | //! It gets the preamble length configured. 663 | /*! 664 | It stores in global '_preamblelength' variable the preamble length 665 | \return '0' on success, '1' otherwise 666 | */ 667 | uint8_t getPreambleLength(); 668 | 669 | //! It sets the preamble length. 670 | /*! 671 | It stores in global '_preamblelength' variable the preamble length 672 | \param uint16_t l : preamble length to set in the configuration. 673 | \return '0' on success, '1' otherwise 674 | */ 675 | uint8_t setPreambleLength(uint16_t l); 676 | 677 | //! It gets the payload length of the last packet to send/receive. 678 | /*! 679 | It stores in global '_payloadlength' variable the payload length of 680 | the last packet to send/receive. 681 | \return '0' on success, '1' otherwise 682 | */ 683 | uint8_t getPayloadLength(); 684 | 685 | //! It sets the packet length to send/receive. 686 | /*! 687 | It stores in global '_payloadlength' variable the payload length of 688 | the last packet to send/receive. 689 | \return '0' on success, '1' otherwise 690 | */ 691 | int8_t setPacketLength(); 692 | 693 | //! It sets the packet length to send/receive. 694 | /*! 695 | It stores in global '_payloadlength' variable the payload length of 696 | the last packet to send/receive. 697 | \param uint8_t l : payload length to set in the configuration. 698 | \return '0' on success, '1' otherwise 699 | */ 700 | int8_t setPacketLength(uint8_t l); 701 | 702 | //! It gets the node address of the mote. 703 | /*! 704 | It stores in global '_nodeAddress' variable the node address 705 | \return '0' on success, '1' otherwise 706 | */ 707 | uint8_t getNodeAddress(); 708 | 709 | //! It sets the node address of the mote. 710 | /*! 711 | It stores in global '_nodeAddress' variable the node address 712 | \param uint8_t addr : address value to set as node address. 713 | \return '0' on success, '1' otherwise 714 | */ 715 | int8_t setNodeAddress(uint8_t addr); 716 | 717 | //! It gets the SNR of the latest received packet. 718 | /*! 719 | It stores in global '_SNR' variable the SNR 720 | \return '0' on success, '1' otherwise 721 | */ 722 | int8_t getSNR(); 723 | 724 | //! It gets the current value of RSSI. 725 | /*! 726 | It stores in global '_RSSI' variable the current value of RSSI 727 | \return '0' on success, '1' otherwise 728 | */ 729 | uint8_t getRSSI(); 730 | 731 | //! It gets the RSSI of the latest received packet. 732 | /*! 733 | It stores in global '_RSSIpacket' variable the RSSI of the latest 734 | packet received. 735 | \return '0' on success, '1' otherwise 736 | */ 737 | int16_t getRSSIpacket(); 738 | 739 | //! It sets the total of retries when a packet is not correctly received. 740 | /*! 741 | It stores in global '_maxRetries' variable the number of retries. 742 | \param uint8_t ret : number of retries. 743 | \return '0' on success, '1' otherwise 744 | */ 745 | uint8_t setRetries(uint8_t ret); 746 | 747 | //! It gets the maximum current supply by the module. 748 | /*! 749 | * 750 | \return '0' on success, '1' otherwise 751 | */ 752 | uint8_t getMaxCurrent(); 753 | 754 | //! It sets the maximum current supply by the module. 755 | /*! 756 | It stores in global '_maxCurrent' variable the maximum current supply. 757 | \param uint8_t rate : maximum current supply. 758 | \return '0' on success, '1' otherwise 759 | */ 760 | int8_t setMaxCurrent(uint8_t rate); 761 | 762 | //! It gets the content of the main configuration registers. 763 | /*! 764 | It stores in global '_bandwidth' variable the BW. 765 | It stores in global '_codingRate' variable the CR. 766 | It stores in global '_spreadingFactor' variable the SF. 767 | It stores in global '_power' variable the output power of the signal. 768 | It stores in global '_channel' variable the frequency channel. 769 | It stores in global '_CRC' variable '1' enabling CRC generation on 770 | payload, or '0' disabling the CRC. 771 | It stores in global '_header' variable '0' when header is sent 772 | (explicit header mode) or '1' when is not sent (implicit header 773 | mode). 774 | It stores in global '_preamblelength' variable the preamble length. 775 | It stores in global '_payloadlength' variable the payload length of 776 | the last packet to send/receive. 777 | It stores in global '_nodeAddress' variable the node address. 778 | It stores in global '_temp' variable the module temperature. 779 | \return '0' on success, '1' otherwise 780 | */ 781 | uint8_t getRegs(); 782 | 783 | //! It sets the maximum number of bytes from a frame that fit in a packet structure. 784 | /*! 785 | It stores in global '_payloadlength' variable the maximum number of bytes. 786 | \param uint16_t length16 : total frame length. 787 | \return '0' on success, '1' otherwise 788 | */ 789 | uint8_t truncPayload(uint16_t length16); 790 | 791 | //! It writes an ACK in FIFO to send it. 792 | /*! 793 | * 794 | \return '0' on success, '1' otherwise 795 | */ 796 | uint8_t setACK(); 797 | 798 | //! It puts the module in reception mode. 799 | /*! 800 | * 801 | \return '0' on success, '1' otherwise 802 | */ 803 | uint8_t receive(); 804 | 805 | //! It receives a packet before MAX_TIMEOUT. 806 | /*! 807 | * 808 | \return '0' on success, '1' otherwise 809 | */ 810 | uint8_t receivePacketMAXTimeout(); 811 | 812 | //! It receives a packet before a timeout. 813 | /*! 814 | * 815 | \return '0' on success, '1' otherwise 816 | */ 817 | uint8_t receivePacketTimeout(); 818 | 819 | //! It receives a packet before a timeout. 820 | /*! 821 | \param uint16_t wait : time to wait to receive something. 822 | \return '0' on success, '1' otherwise 823 | */ 824 | uint8_t receivePacketTimeout(uint16_t wait); 825 | 826 | //! It receives a packet before MAX_TIMEOUT and reply with an ACK. 827 | /*! 828 | * 829 | \return '0' on success, '1' otherwise 830 | */ 831 | uint8_t receivePacketMAXTimeoutACK(); 832 | 833 | //! It receives a packet before a timeout and reply with an ACK. 834 | /*! 835 | * 836 | \return '0' on success, '1' otherwise 837 | */ 838 | uint8_t receivePacketTimeoutACK(); 839 | 840 | //! It receives a packet before a timeout and reply with an ACK. 841 | /*! 842 | \param uint16_t wait : time to wait to receive something. 843 | \return '0' on success, '1' otherwise 844 | */ 845 | uint8_t receivePacketTimeoutACK(uint16_t wait); 846 | 847 | //! It puts the module in 'promiscuous' reception mode. 848 | /*! 849 | * 850 | \return '0' on success, '1' otherwise 851 | */ 852 | uint8_t receiveAll(); 853 | 854 | //! It puts the module in 'promiscuous' reception mode with a timeout. 855 | /*! 856 | \param uint16_t wait : time to wait to receive something. 857 | \return '0' on success, '1' otherwise 858 | */ 859 | uint8_t receiveAll(uint16_t wait); 860 | 861 | //! It checks if there is an available packet and its destination. 862 | /*! 863 | * 864 | \return 'true' on success, 'false' otherwise 865 | */ 866 | boolean availableData(); 867 | 868 | //! It checks if there is an available packet and its destination before a timeout. 869 | /*! 870 | * 871 | \param uint16_t wait : time to wait while there is no a valid header received. 872 | \return 'true' on success, 'false' otherwise 873 | */ 874 | boolean availableData(uint16_t wait); 875 | 876 | //! It writes a packet in FIFO in order to send it. 877 | /*! 878 | \param uint8_t dest : packet destination. 879 | \param char *payload : packet payload. 880 | \return '0' on success, '1' otherwise 881 | */ 882 | uint8_t setPacket(uint8_t dest, char *payload); 883 | 884 | //! It writes a packet in FIFO in order to send it. 885 | /*! 886 | \param uint8_t dest : packet destination. 887 | \param uint8_t *payload: packet payload. 888 | \return '0' on success, '1' otherwise 889 | */ 890 | uint8_t setPacket(uint8_t dest, uint8_t *payload); 891 | 892 | //! It reads a received packet from the FIFO, if it arrives before ending MAX_TIMEOUT time. 893 | /*! 894 | * 895 | \return '0' on success, '1' otherwise 896 | */ 897 | uint8_t getPacketMAXTimeout(); 898 | 899 | //! It reads a received packet from the FIFO, if it arrives before ending '_sendTime' time. 900 | /*! 901 | * 902 | \return '0' on success, '1' otherwise 903 | */ 904 | int8_t getPacket(); 905 | 906 | //! It receives and gets a packet from FIFO, if it arrives before ending 'wait' time. 907 | /*! 908 | * 909 | \param uint16_t wait : time to wait while there is no a complete packet received. 910 | \return '0' on success, '1' otherwise 911 | */ 912 | int8_t getPacket(uint16_t wait); 913 | 914 | //! It sends the packet stored in FIFO before ending MAX_TIMEOUT. 915 | /*! 916 | * 917 | \return '0' on success, '1' otherwise 918 | */ 919 | uint8_t sendWithMAXTimeout(); 920 | 921 | //! It sends the packet stored in FIFO before ending _sendTime time. 922 | /*! 923 | * 924 | \return '0' on success, '1' otherwise 925 | */ 926 | uint8_t sendWithTimeout(); 927 | 928 | //! It tries to send the packet stored in FIFO before ending 'wait' time. 929 | /*! 930 | \param uint16_t wait : time to wait to send the packet. 931 | \return '0' on success, '1' otherwise 932 | */ 933 | uint8_t sendWithTimeout(uint16_t wait); 934 | 935 | //! It tries to send the packet wich payload is a parameter before ending MAX_TIMEOUT. 936 | /*! 937 | \param uint8_t dest : packet destination. 938 | \param char *payload : packet payload. 939 | \return '0' on success, '1' otherwise 940 | */ 941 | uint8_t sendPacketMAXTimeout(uint8_t dest, char *payload); 942 | 943 | //! It tries to send the packet wich payload is a parameter before ending MAX_TIMEOUT. 944 | /*! 945 | \param uint8_t dest : packet destination. 946 | \param uint8_t *payload : packet payload. 947 | \param uint16_t length : payload buffer length. 948 | \return '0' on success, '1' otherwise 949 | */ 950 | uint8_t sendPacketMAXTimeout(uint8_t dest, uint8_t *payload, uint16_t length); 951 | 952 | 953 | //! It sends the packet wich payload is a parameter before ending MAX_TIMEOUT. 954 | /*! 955 | \param uint8_t dest : packet destination. 956 | \param char *payload : packet payload. 957 | \return '0' on success, '1' otherwise 958 | */ 959 | uint8_t sendPacketTimeout(uint8_t dest, char *payload); 960 | 961 | //! It sends the packet wich payload is a parameter before ending MAX_TIMEOUT. 962 | /*! 963 | \param uint8_t dest : packet destination. 964 | \param uint8_t *payload: packet payload. 965 | \param uint16_t length : payload buffer length. 966 | \return '0' on success, '1' otherwise 967 | */ 968 | uint8_t sendPacketTimeout(uint8_t dest, uint8_t *payload, uint16_t length); 969 | 970 | //! It sends the packet wich payload is a parameter before ending 'wait' time. 971 | /*! 972 | \param uint8_t dest : packet destination. 973 | \param char *payload : packet payload. 974 | \param uint16_t wait : time to wait. 975 | \return '0' on success, '1' otherwise 976 | */ 977 | uint8_t sendPacketTimeout(uint8_t dest, char *payload, uint16_t wait); 978 | 979 | //! It sends the packet wich payload is a parameter before ending 'wait' time. 980 | /*! 981 | \param uint8_t dest : packet destination. 982 | \param uint8_t *payload : packet payload. 983 | \param uint16_t length : payload buffer length. 984 | \param uint16_t wait : time to wait. 985 | \return '0' on success, '1' otherwise 986 | */ 987 | uint8_t sendPacketTimeout(uint8_t dest, uint8_t *payload, uint16_t length, uint16_t wait); 988 | 989 | //! It sends the packet wich payload is a parameter before MAX_TIMEOUT, and replies with ACK. 990 | /*! 991 | \param uint8_t dest : packet destination. 992 | \param char *payload : packet payload. 993 | \return '0' on success, '1' otherwise 994 | */ 995 | uint8_t sendPacketMAXTimeoutACK(uint8_t dest, char *payload); 996 | 997 | //! It sends the packet wich payload is a parameter before MAX_TIMEOUT, and replies with ACK. 998 | /*! 999 | \param uint8_t dest : packet destination. 1000 | \param uint8_t payload: packet payload. 1001 | \param uint16_t length : payload buffer length. 1002 | \return '0' on success, '1' otherwise 1003 | */ 1004 | uint8_t sendPacketMAXTimeoutACK(uint8_t dest, uint8_t *payload, uint16_t length); 1005 | 1006 | //! It sends the packet wich payload is a parameter before a timeout, and replies with ACK. 1007 | /*! 1008 | \param uint8_t dest : packet destination. 1009 | \param char *payload : packet payload. 1010 | \return '0' on success, '1' otherwise 1011 | */ 1012 | uint8_t sendPacketTimeoutACK(uint8_t dest, char *payload); 1013 | 1014 | //! It sends the packet wich payload is a parameter before a timeout, and replies with ACK. 1015 | /*! 1016 | \param uint8_t dest : packet destination. 1017 | \param uint8_t payload: packet payload. 1018 | \param uint16_t length : payload buffer length. 1019 | \return '0' on success, '1' otherwise 1020 | */ 1021 | uint8_t sendPacketTimeoutACK(uint8_t dest, uint8_t *payload, uint16_t length); 1022 | 1023 | //! It sends the packet wich payload is a parameter before 'wait' time, and replies with ACK. 1024 | /*! 1025 | \param uint8_t dest : packet destination. 1026 | \param char *payload : packet payload. 1027 | \param uint16_t wait : time to wait to send the packet. 1028 | \return '0' on success, '1' otherwise 1029 | */ 1030 | uint8_t sendPacketTimeoutACK(uint8_t dest, char *payload, uint16_t wait); 1031 | 1032 | //! It sends the packet wich payload is a parameter before 'wait' time, and replies with ACK. 1033 | /*! 1034 | \param uint8_t dest : packet destination. 1035 | \param uint8_t payload: packet payload. 1036 | \param uint16_t length : payload buffer length. 1037 | \param uint16_t wait : time to wait to send the packet. 1038 | \return '0' on success, '1' otherwise 1039 | */ 1040 | uint8_t sendPacketTimeoutACK(uint8_t dest, uint8_t *payload, uint16_t length, uint16_t wait); 1041 | 1042 | //! It sets the destination of a packet. 1043 | /*! 1044 | \param uint8_t dest : value to set as destination address. 1045 | \return '0' on success, '1' otherwise 1046 | */ 1047 | int8_t setDestination(uint8_t dest); 1048 | 1049 | //! It sets the waiting time to send a packet. 1050 | /*! 1051 | It stores in global '_sendTime' variable the time for each mode. 1052 | \return '0' on success, '1' otherwise 1053 | */ 1054 | uint8_t setTimeout(); 1055 | 1056 | //! It sets the payload of the packet that is going to be sent. 1057 | /*! 1058 | \param char *payload : packet payload. 1059 | \return '0' on success, '1' otherwise 1060 | */ 1061 | uint8_t setPayload(char *payload); 1062 | 1063 | //! It sets the payload of the packet that is going to be sent. 1064 | /*! 1065 | \param uint8_t payload: packet payload. 1066 | \return '0' on success, '1' otherwise 1067 | */ 1068 | uint8_t setPayload(uint8_t *payload); 1069 | 1070 | //! If an ACK is received, it gets it and checks its content. 1071 | /*! 1072 | * 1073 | \return '0' on success, '1' otherwise 1074 | */ 1075 | uint8_t getACK(); 1076 | 1077 | //! It receives and gets an ACK from FIFO, if it arrives before ending 'wait' time. 1078 | /*! 1079 | * 1080 | \param uint16_t wait : time to wait while there is no an ACK received. 1081 | \return '0' on success, '1' otherwise 1082 | */ 1083 | uint8_t getACK(uint16_t wait); 1084 | 1085 | //! It sends a packet, waits to receive an ACK and updates the _retries value, before ending MAX_TIMEOUT time. 1086 | /*! 1087 | \param uint8_t dest : packet destination. 1088 | \param char *payload : packet payload. 1089 | \return '0' on success, '1' otherwise 1090 | */ 1091 | uint8_t sendPacketMAXTimeoutACKRetries(uint8_t dest, char *payload); 1092 | 1093 | //! It sends a packet, waits to receive an ACK and updates the _retries value, before ending MAX_TIMEOUT time. 1094 | /*! 1095 | \param uint8_t dest : packet destination. 1096 | \param uint8_t *payload : packet payload. 1097 | \param uint16_t length : payload buffer length. 1098 | \return '0' on success, '1' otherwise 1099 | */ 1100 | uint8_t sendPacketMAXTimeoutACKRetries(uint8_t dest, uint8_t *payload, uint16_t length); 1101 | 1102 | //! It sends a packet, waits to receive an ACK and updates the _retries value. 1103 | /*! 1104 | \param uint8_t dest : packet destination. 1105 | \param char *payload : packet payload. 1106 | \return '0' on success, '1' otherwise 1107 | */ 1108 | uint8_t sendPacketTimeoutACKRetries(uint8_t dest, char *payload); 1109 | 1110 | //! It sends a packet, waits to receive an ACK and updates the _retries value. 1111 | /*! 1112 | \param uint8_t dest : packet destination. 1113 | \param uint8_t *payload : packet payload. 1114 | \param uint16_t length : payload buffer length. 1115 | \return '0' on success, '1' otherwise 1116 | */ 1117 | uint8_t sendPacketTimeoutACKRetries(uint8_t dest, uint8_t *payload, uint16_t length); 1118 | 1119 | //! It sends a packet, waits to receive an ACK and updates the _retries value, before ending 'wait' time. 1120 | /*! 1121 | \param uint8_t dest : packet destination. 1122 | \param char *payload : packet payload. 1123 | \param uint16_t wait : time to wait while trying to send the packet. 1124 | \return '0' on success, '1' otherwise 1125 | */ 1126 | uint8_t sendPacketTimeoutACKRetries(uint8_t dest, char *payload, uint16_t wait); 1127 | 1128 | //! It sends a packet, waits to receive an ACK and updates the _retries value, before ending 'wait' time. 1129 | /*! 1130 | \param uint8_t dest : packet destination. 1131 | \param uint8_t *payload : packet payload. 1132 | \param uint16_t length : payload buffer length. 1133 | \param uint16_t wait : time to wait while trying to send the packet. 1134 | \return '0' on success, '1' otherwise 1135 | */ 1136 | uint8_t sendPacketTimeoutACKRetries(uint8_t dest, uint8_t *payload, uint16_t length, uint16_t wait); 1137 | 1138 | //! It gets the internal temperature of the module. 1139 | /*! 1140 | It stores in global '_temp' variable the module temperature. 1141 | \return '0' on success, '1' otherwise 1142 | */ 1143 | uint8_t getTemp(); 1144 | 1145 | // added by C. Pham 1146 | void setPacketType(uint8_t type); 1147 | void RxChainCalibration(); 1148 | uint8_t doCAD(uint8_t counter); 1149 | uint16_t getToA(uint8_t pl); 1150 | void CarrierSense(); 1151 | int8_t setSyncWord(uint8_t sw); 1152 | int8_t getSyncWord(); 1153 | int8_t setSleepMode(); 1154 | 1155 | // SX1272 or SX1276? 1156 | uint8_t _board; 1157 | uint8_t _syncWord; 1158 | uint8_t _defaultSyncWord; 1159 | unsigned long _starttime; 1160 | unsigned long _stoptime; 1161 | unsigned long _startDoCad; 1162 | unsigned long _endDoCad; 1163 | uint8_t _loraMode; 1164 | uint8_t _send_cad_number; 1165 | bool _extendedIFS; 1166 | bool _RSSIonSend; 1167 | bool _enableCarrierSense; 1168 | bool _rawFormat; 1169 | int8_t _rcv_snr_in_ack; 1170 | 1171 | #ifdef W_REQUESTED_ACK 1172 | uint8_t _requestACK; 1173 | uint8_t _requestACK_indicator; 1174 | #endif 1175 | 1176 | #ifdef W_NET_KEY 1177 | uint8_t _my_netkey[NET_KEY_LENGTH]; 1178 | uint8_t _the_net_key_0; 1179 | uint8_t _the_net_key_1; 1180 | #endif 1181 | // end 1182 | 1183 | /// Variables ///////////////////////////////////////////////////////////// 1184 | 1185 | //! Variable : bandwidth configured in LoRa mode. 1186 | //! bandwidth = 00 --> BW = 125KHz 1187 | //! bandwidth = 01 --> BW = 250KHz 1188 | //! bandwidth = 10 --> BW = 500KHz 1189 | /*! 1190 | */ 1191 | uint8_t _bandwidth; 1192 | 1193 | //! Variable : coding rate configured in LoRa mode. 1194 | //! codingRate = 001 --> CR = 4/5 1195 | //! codingRate = 010 --> CR = 4/6 1196 | //! codingRate = 011 --> CR = 4/7 1197 | //! codingRate = 100 --> CR = 4/8 1198 | /*! 1199 | */ 1200 | uint8_t _codingRate; 1201 | 1202 | //! Variable : spreading factor configured in LoRa mode. 1203 | //! spreadingFactor = 6 --> SF = 6, 64 chips/symbol 1204 | //! spreadingFactor = 7 --> SF = 7, 128 chips/symbol 1205 | //! spreadingFactor = 8 --> SF = 8, 256 chips/symbol 1206 | //! spreadingFactor = 9 --> SF = 9, 512 chips/symbol 1207 | //! spreadingFactor = 10 --> SF = 10, 1024 chips/symbol 1208 | //! spreadingFactor = 11 --> SF = 11, 2048 chips/symbol 1209 | //! spreadingFactor = 12 --> SF = 12, 4096 chips/symbol 1210 | /*! 1211 | */ 1212 | uint8_t _spreadingFactor; 1213 | 1214 | //! Variable : frequency channel. 1215 | //! channel = 0xD84CCC --> CH = 10_868, 865.20MHz 1216 | //! channel = 0xD86000 --> CH = 11_868, 865.50MHz 1217 | //! channel = 0xD87333 --> CH = 12_868, 865.80MHz 1218 | //! channel = 0xD88666 --> CH = 13_868, 866.10MHz 1219 | //! channel = 0xD89999 --> CH = 14_868, 866.40MHz 1220 | //! channel = 0xD8ACCC --> CH = 15_868, 866.70MHz 1221 | //! channel = 0xD8C000 --> CH = 16_868, 867.00MHz 1222 | //! channel = 0xE1C51E --> CH = 00_900, 903.08MHz 1223 | //! channel = 0xE24F5C --> CH = 01_900, 905.24MHz 1224 | //! channel = 0xE2D999 --> CH = 02_900, 907.40MHz 1225 | //! channel = 0xE363D7 --> CH = 03_900, 909.56MHz 1226 | //! channel = 0xE3EE14 --> CH = 04_900, 911.72MHz 1227 | //! channel = 0xE47851 --> CH = 05_900, 913.88MHz 1228 | //! channel = 0xE5028F --> CH = 06_900, 916.04MHz 1229 | //! channel = 0xE58CCC --> CH = 07_900, 918.20MHz 1230 | //! channel = 0xE6170A --> CH = 08_900, 920.36MHz 1231 | //! channel = 0xE6A147 --> CH = 09_900, 922.52MHz 1232 | //! channel = 0xE72B85 --> CH = 10_900, 924.68MHz 1233 | //! channel = 0xE7B5C2 --> CH = 11_900, 926.84MHz 1234 | /*! 1235 | */ 1236 | uint32_t _channel; 1237 | 1238 | //! Variable : output power. 1239 | //! 1240 | /*! 1241 | */ 1242 | uint8_t _power; 1243 | 1244 | //! Variable : SNR from the last packet received in LoRa mode. 1245 | //! 1246 | /*! 1247 | */ 1248 | int8_t _SNR; 1249 | 1250 | //! Variable : RSSI current value. 1251 | //! 1252 | /*! 1253 | */ 1254 | int8_t _RSSI; 1255 | 1256 | //! Variable : RSSI from the last packet received in LoRa mode. 1257 | //! 1258 | /*! 1259 | */ 1260 | int16_t _RSSIpacket; 1261 | 1262 | //! Variable : preamble length sent/received. 1263 | //! 1264 | /*! 1265 | */ 1266 | uint16_t _preamblelength; 1267 | 1268 | //! Variable : payload length sent/received. 1269 | //! 1270 | /*! 1271 | */ 1272 | uint16_t _payloadlength; 1273 | 1274 | //! Variable : node address. 1275 | //! 1276 | /*! 1277 | */ 1278 | uint8_t _nodeAddress; 1279 | 1280 | //! Variable : implicit or explicit header in LoRa mode. 1281 | //! 1282 | /*! 1283 | */ 1284 | uint8_t _header; 1285 | 1286 | //! Variable : header received while waiting a packet to arrive. 1287 | //! 1288 | /*! 1289 | */ 1290 | uint8_t _hreceived; 1291 | 1292 | //! Variable : presence or absence of CRC calculation. 1293 | //! 1294 | /*! 1295 | */ 1296 | uint8_t _CRC; 1297 | 1298 | //! Variable : packet destination. 1299 | //! 1300 | /*! 1301 | */ 1302 | uint8_t _destination; 1303 | 1304 | //! Variable : packet number. 1305 | //! 1306 | /*! 1307 | */ 1308 | uint8_t _packetNumber; 1309 | 1310 | //! Variable : indicates if received packet is correct or incorrect. 1311 | //! 1312 | /*! 1313 | */ 1314 | uint8_t _reception; 1315 | 1316 | //! Variable : number of current retry. 1317 | //! 1318 | /*! 1319 | */ 1320 | uint8_t _retries; 1321 | 1322 | //! Variable : maximum number of retries. 1323 | //! 1324 | /*! 1325 | */ 1326 | uint8_t _maxRetries; 1327 | 1328 | //! Variable : maximum current supply. 1329 | //! 1330 | /*! 1331 | */ 1332 | uint8_t _maxCurrent; 1333 | 1334 | //! Variable : indicates FSK or LoRa 'modem'. 1335 | //! 1336 | /*! 1337 | */ 1338 | uint8_t _modem; 1339 | 1340 | //! Variable : array with all the information about a sent packet. 1341 | //! 1342 | /*! 1343 | */ 1344 | pack packet_sent; 1345 | 1346 | //! Variable : array with all the information about a received packet. 1347 | //! 1348 | /*! 1349 | */ 1350 | pack packet_received; 1351 | 1352 | //! Variable : array with all the information about a sent/received ack. 1353 | //! 1354 | /*! 1355 | */ 1356 | pack ACK; 1357 | 1358 | //! Variable : temperature module. 1359 | //! 1360 | /*! 1361 | */ 1362 | int _temp; 1363 | 1364 | //! Variable : current timeout to send a packet. 1365 | //! 1366 | /*! 1367 | */ 1368 | uint16_t _sendTime; 1369 | 1370 | }; 1371 | 1372 | extern SX1272 sx1272; 1373 | 1374 | #endif 1375 | --------------------------------------------------------------------------------