├── .vscode └── settings.json ├── LORA_CLIENT.ino ├── LORA_CLIENT_encrypted.ino ├── LORA_CLIENT_encrypted.png ├── LORA_SERVER.ino ├── LORA_SERVER_encrypted.ino ├── LORA_SERVER_encrypted.png ├── README.md └── wiring.png /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.enabled": false 3 | } -------------------------------------------------------------------------------- /LORA_CLIENT.ino: -------------------------------------------------------------------------------- 1 | // This program sends a response whenever it receives the "INF" mens 2 | // 3 | // Copyright 2018 Rui Silva. 4 | // This file is part of rpsreal/LoRa_Ra-02_Arduino 5 | // Based on example Arduino9x_RX RADIOHEAD library 6 | // It is designed to work with LORA_SERVER 7 | 8 | #include 9 | #include 10 | 11 | #define RFM95_CS 10 12 | #define RFM95_RST 9 13 | #define RFM95_INT 2 14 | 15 | // Change to 434.0 or other frequency, must match RX's freq! 16 | #define RF95_FREQ 434.0 17 | 18 | // Singleton instance of the radio driver 19 | RH_RF95 rf95(RFM95_CS, RFM95_INT); 20 | 21 | // Blinky on receipt 22 | #define LED 13 23 | 24 | void setup() 25 | { 26 | pinMode(LED, OUTPUT); 27 | pinMode(RFM95_RST, OUTPUT); 28 | digitalWrite(RFM95_RST, HIGH); 29 | 30 | while (!Serial); 31 | Serial.begin(9600); 32 | delay(100); 33 | 34 | // manual reset 35 | digitalWrite(RFM95_RST, LOW); 36 | delay(10); 37 | digitalWrite(RFM95_RST, HIGH); 38 | delay(10); 39 | 40 | while (!rf95.init()) { 41 | Serial.println("LoRa radio init failed"); 42 | while (1); 43 | } 44 | 45 | // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM 46 | if (!rf95.setFrequency(RF95_FREQ)) { 47 | Serial.println("setFrequency failed"); 48 | while (1); 49 | } 50 | 51 | // The default transmitter power is 13dBm, using PA_BOOST. 52 | // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 53 | // you can set transmitter powers from 5 to 23 dBm: 54 | 55 | 56 | // Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. 57 | // Slow+long range. 58 | //rf95.setModemConfig(RH_RF95::Bw125Cr48Sf4096); 59 | 60 | 61 | // Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on 62 | // Medium Range 63 | 64 | rf95.setTxPower(18); 65 | 66 | 67 | 68 | Serial.println("START"); 69 | } 70 | 71 | uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 72 | uint8_t len = sizeof(buf); 73 | 74 | void loop() 75 | { 76 | if (rf95.available()){ 77 | 78 | if (rf95.recv(buf, &len)){ 79 | digitalWrite(LED, HIGH); 80 | //RH_RF95::printBuffer("Got: ", buf, len); 81 | Serial.print("Received: "); 82 | Serial.println((char*)buf); 83 | Serial.print("RSSI: "); 84 | Serial.println(rf95.lastRssi(), DEC); 85 | if (strcmp("INF",((char*)buf)) == 0){ 86 | Serial.println("Received data request INF"); 87 | delay(2000); 88 | Serial.println("Send mens: DATA ARDUINO"); 89 | uint8_t data[] = "DATA ARDUINO"; 90 | rf95.send(data, 13); //sizeof(data) 91 | rf95.waitPacketSent(); 92 | } 93 | digitalWrite(LED, LOW); 94 | } 95 | else 96 | { 97 | Serial.println("Receive failed"); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /LORA_CLIENT_encrypted.ino: -------------------------------------------------------------------------------- 1 | // This program sends a response whenever it receives the "INF" mens 2 | // 3 | // Copyright 2018 Rui Silva. 4 | // This file is part of rpsreal/LoRa_Ra-02_Arduino 5 | // Based on example LoRa 9x_RX RADIOHEAD library 6 | // It is designed to work with LORA_SERVER_encrypted in Arduino or Raspberry Pi 7 | 8 | #include // SPI 9 | #include //HadioHead http://www.airspayce.com/mikem/arduino/RadioHead/ 10 | #include // https://github.com/adamvr/arduino-base64 11 | #include // https://github.com/DavyLandman/AESLib 12 | 13 | #define RFM95_CS 10 14 | #define RFM95_RST 9 15 | #define RFM95_INT 2 16 | 17 | // Change to 434.0 or other frequency, must match RX's freq! 18 | #define RF95_FREQ 434.0 19 | 20 | // Singleton instance of the radio driver 21 | RH_RF95 rf95(RFM95_CS, RFM95_INT); 22 | 23 | // Blinky on receipt 24 | #define LED 13 25 | 26 | void setup() 27 | { 28 | pinMode(LED, OUTPUT); 29 | pinMode(RFM95_RST, OUTPUT); 30 | digitalWrite(RFM95_RST, HIGH); 31 | 32 | while (!Serial); 33 | Serial.begin(9600); 34 | delay(100); 35 | 36 | // manual reset 37 | digitalWrite(RFM95_RST, LOW); 38 | delay(10); 39 | digitalWrite(RFM95_RST, HIGH); 40 | delay(10); 41 | 42 | while (!rf95.init()) { 43 | Serial.println("LoRa radio init failed"); 44 | while (1); 45 | } 46 | 47 | // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM 48 | if (!rf95.setFrequency(RF95_FREQ)) { 49 | Serial.println("setFrequency failed"); 50 | while (1); 51 | } 52 | 53 | // The default transmitter power is 13dBm, using PA_BOOST. 54 | // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 55 | // you can set transmitter powers from 5 to 23 dBm: 56 | 57 | 58 | // Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. 59 | // Slow+long range. 60 | rf95.setModemConfig(RH_RF95::Bw125Cr48Sf4096); 61 | 62 | 63 | // Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on 64 | // Medium Range 65 | 66 | rf95.setTxPower(18); 67 | Serial.println("START"); 68 | } 69 | 70 | uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 71 | uint8_t len = sizeof(buf); 72 | uint8_t key[] = "1234567890123456"; 73 | 74 | void loop() 75 | { 76 | if (rf95.available()){ 77 | 78 | if (rf95.recv(buf, &len)){ 79 | digitalWrite(LED, HIGH); 80 | //RH_RF95::printBuffer("Got: ", buf, len); 81 | //Serial.print("RSSI: "); 82 | //Serial.println(rf95.lastRssi(), DEC); 83 | Serial.print("== RECEIVED: "); 84 | Serial.print((char*)buf); 85 | 86 | uint8_t bufLen = sizeof(buf); 87 | uint8_t decodedLen = base64_dec_len((char*)buf, bufLen); 88 | uint8_t data_de[decodedLen]; 89 | base64_decode((char*)data_de, (char*)buf, bufLen); 90 | 91 | aes128_dec_single(key, data_de); 92 | Serial.print(" | Decoded: "); 93 | Serial.println((char*)data_de); 94 | 95 | 96 | if (strcmp("INF ",((char*)data_de)) == 0){ 97 | Serial.println("Received data request INF - going to send mens:DATA ARDUINO "); 98 | delay(2000); 99 | 100 | uint8_t input[] = "DATA ARDUINO "; // 16 char 101 | aes128_enc_single(key, input); 102 | uint8_t inputLen = sizeof(input)-1; 103 | uint8_t encodedLen = base64_enc_len(inputLen); 104 | uint8_t encoded[encodedLen+1]; 105 | base64_encode((char*)encoded, (char*)input, inputLen); 106 | 107 | rf95.send(encoded, sizeof(encoded)); 108 | rf95.waitPacketSent(); 109 | Serial.print("== SEND: "); 110 | Serial.print("DATA ARDUINO "); 111 | Serial.print(" | Encoded: "); 112 | Serial.println((char*)encoded); 113 | }else if (strcmp("ACK ",((char*)data_de)) == 0){ 114 | Serial.println("\n"); 115 | } 116 | digitalWrite(LED, LOW); 117 | }else{ 118 | Serial.println("Receive failed"); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /LORA_CLIENT_encrypted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpsreal/LoRa_Ra-02_Arduino/e314ce5efda4818d592c37f33315b1d7b55ebb4f/LORA_CLIENT_encrypted.png -------------------------------------------------------------------------------- /LORA_SERVER.ino: -------------------------------------------------------------------------------- 1 | // This program asks a client for data and waits for the response, then sends an ACK. 2 | // 3 | // Copyright 2018 Rui Silva. 4 | // This file is part of rpsreal/LoRa_Ra-02_Arduino 5 | // Based on example LoRa 9x_TX RADIOHEAD library 6 | // It is designed to work with LORA_CLIENT 7 | 8 | #include 9 | #include 10 | 11 | #define RFM95_CS 10 12 | #define RFM95_RST 9 13 | #define RFM95_INT 2 14 | 15 | // Blinky on receipt 16 | #define LED 13 17 | // Change to 434.0 or other frequency, must match RX's freq! 18 | #define RF95_FREQ 434.0 19 | 20 | // Singleton instance of the radio driver 21 | RH_RF95 rf95(RFM95_CS, RFM95_INT); 22 | 23 | void setup() 24 | { 25 | pinMode(RFM95_RST, OUTPUT); 26 | digitalWrite(RFM95_RST, HIGH); 27 | 28 | while (!Serial); 29 | Serial.begin(9600); 30 | delay(100); 31 | 32 | // manual reset 33 | digitalWrite(RFM95_RST, LOW); 34 | delay(10); 35 | digitalWrite(RFM95_RST, HIGH); 36 | delay(10); 37 | 38 | while (!rf95.init()) { 39 | Serial.println("LoRa radio init failed"); 40 | while (1); 41 | } 42 | 43 | // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM 44 | if (!rf95.setFrequency(RF95_FREQ)) { 45 | Serial.println("setFrequency failed"); 46 | while (1); 47 | } 48 | 49 | // The default transmitter power is 13dBm, using PA_BOOST. 50 | // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 51 | // you can set transmitter powers from 5 to 23 dBm: 52 | 53 | 54 | // Slow+long range. Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. 55 | //rf95.setModemConfig(RH_RF95::Bw125Cr48Sf4096); 56 | 57 | // Defaults medium Range after init are 434.0MHz, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on 58 | 59 | rf95.setTxPower(18); 60 | 61 | 62 | Serial.println("START"); 63 | } 64 | 65 | int8_t send_ack=0; // flag var 66 | 67 | void loop() 68 | { 69 | 70 | while (send_ack==0){ 71 | digitalWrite(LED, HIGH); 72 | Serial.println("Send: INF"); 73 | char radiopacket[4] = "INF"; 74 | rf95.send((uint8_t *)radiopacket, 4); 75 | delay(10); 76 | rf95.waitPacketSent(); 77 | 78 | uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 79 | uint8_t len = sizeof(buf); 80 | if (rf95.waitAvailableTimeout(20000)){ 81 | if (rf95.recv(buf, &len)){ 82 | Serial.print("Receive: "); 83 | Serial.println((char*)buf); 84 | send_ack=1; 85 | Serial.print("RSSI: "); 86 | Serial.println(rf95.lastRssi(), DEC); 87 | delay(2000); 88 | }else{ 89 | Serial.println("Receive failed"); 90 | } 91 | }else{ 92 | Serial.println("Send INF again"); 93 | } 94 | } 95 | 96 | if(send_ack==1){ //Send: ACK 97 | delay(1000); 98 | Serial.println("Send: ACK"); 99 | char radiopacket[4] = "ACK"; 100 | rf95.send((uint8_t *)radiopacket,4); 101 | delay(10); 102 | rf95.waitPacketSent(); 103 | send_ack=0; 104 | } 105 | digitalWrite(LED, LOW); 106 | delay(10000); 107 | } 108 | -------------------------------------------------------------------------------- /LORA_SERVER_encrypted.ino: -------------------------------------------------------------------------------- 1 | // This program asks a client for data and waits for the response, then sends an ACK. 2 | // 3 | // Copyright 2018 Rui Silva. 4 | // This file is part of rpsreal/LoRa_Ra-02_Arduino 5 | // Based on example LoRa 9x_TX RADIOHEAD library 6 | // It is designed to work with LORA_CLIENT_encrypted in Arduino or Raspberry Pi 7 | 8 | #include // SPI 9 | #include // HadioHead http://www.airspayce.com/mikem/arduino/RadioHead/ 10 | #include // https://github.com/adamvr/arduino-base64 11 | #include // https://github.com/DavyLandman/AESLib 12 | 13 | #define RFM95_CS 10 14 | #define RFM95_RST 9 15 | #define RFM95_INT 2 16 | 17 | // Blinky on receipt 18 | #define LED 13 19 | // Change to 434.0 or other frequency, must match RX's freq! 20 | #define RF95_FREQ 434.0 21 | 22 | // Singleton instance of the radio driver 23 | RH_RF95 rf95(RFM95_CS, RFM95_INT); 24 | 25 | void setup() 26 | { 27 | pinMode(RFM95_RST, OUTPUT); 28 | digitalWrite(RFM95_RST, HIGH); 29 | 30 | while (!Serial); 31 | Serial.begin(9600); 32 | delay(100); 33 | 34 | // manual reset 35 | digitalWrite(RFM95_RST, LOW); 36 | delay(10); 37 | digitalWrite(RFM95_RST, HIGH); 38 | delay(10); 39 | 40 | while (!rf95.init()) { 41 | Serial.println("LoRa radio init failed"); 42 | while (1); 43 | } 44 | 45 | // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM 46 | if (!rf95.setFrequency(RF95_FREQ)) { 47 | Serial.println("setFrequency failed"); 48 | while (1); 49 | } 50 | 51 | // The default transmitter power is 13dBm, using PA_BOOST. 52 | // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 53 | // you can set transmitter powers from 5 to 23 dBm: 54 | 55 | 56 | // Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. 57 | // Slow+long range. 58 | rf95.setModemConfig(RH_RF95::Bw125Cr48Sf4096); 59 | 60 | 61 | // Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on 62 | // Medium Range 63 | 64 | rf95.setTxPower(18); 65 | Serial.println("START"); 66 | } 67 | 68 | int8_t send_ack=0; // flag var 69 | uint8_t key[] = "1234567890123456"; 70 | 71 | void loop() 72 | { 73 | 74 | while (send_ack==0){ 75 | digitalWrite(LED, HIGH); 76 | 77 | uint8_t input[] = "INF "; // 16 char 78 | 79 | aes128_enc_single(key, input); 80 | 81 | uint8_t inputLen = sizeof(input)-1; 82 | uint8_t encodedLen = base64_enc_len(inputLen); 83 | uint8_t encoded[encodedLen+1]; 84 | base64_encode((char*)encoded, (char*)input, inputLen); 85 | 86 | rf95.send(encoded, sizeof(encoded)); 87 | rf95.waitPacketSent(); 88 | Serial.print("== SEND: "); 89 | Serial.print("INF "); 90 | Serial.print(" | Encoded: "); 91 | Serial.println((char*)encoded); 92 | 93 | uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 94 | uint8_t len = sizeof(buf); 95 | if (rf95.waitAvailableTimeout(10000)){ 96 | if (rf95.recv(buf, &len)){ 97 | 98 | //RH_RF95::printBuffer("Got: ", buf, len); 99 | //Serial.print("RSSI: "); 100 | //Serial.println(rf95.lastRssi(), DEC); 101 | Serial.print("== RECEIVED: "); 102 | Serial.print((char*)buf); 103 | 104 | uint8_t bufLen = sizeof(buf); 105 | uint8_t decodedLen = base64_dec_len((char*)buf, bufLen); 106 | uint8_t data_de[decodedLen]; 107 | base64_decode((char*)data_de, (char*)buf, bufLen); 108 | 109 | aes128_dec_single(key, data_de); 110 | Serial.print(" | Decoded: "); 111 | Serial.println((char*)data_de); 112 | 113 | send_ack=1; 114 | 115 | }else{ 116 | Serial.println("Receive failed"); 117 | } 118 | }else{ 119 | Serial.println("Send INF again"); 120 | } 121 | } 122 | 123 | if(send_ack==1){ //Send: ACK 124 | delay(2000); 125 | 126 | uint8_t input[] = "ACK "; // 16 char 127 | 128 | aes128_enc_single(key, input); 129 | 130 | uint8_t inputLen = sizeof(input)-1; 131 | uint8_t encodedLen = base64_enc_len(inputLen); 132 | uint8_t encoded[encodedLen+1]; 133 | base64_encode((char*)encoded, (char*)input, inputLen); 134 | 135 | rf95.send(encoded, sizeof(encoded)); 136 | rf95.waitPacketSent(); 137 | Serial.print("== SEND: "); 138 | Serial.print("ACK "); 139 | Serial.print(" | Encoded: "); 140 | Serial.println((char*)encoded); 141 | Serial.println("\n"); 142 | 143 | send_ack=0; 144 | } 145 | digitalWrite(LED, LOW); 146 | delay(10000); // send new packet every 10 seconds 147 | } 148 | -------------------------------------------------------------------------------- /LORA_SERVER_encrypted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpsreal/LoRa_Ra-02_Arduino/e314ce5efda4818d592c37f33315b1d7b55ebb4f/LORA_SERVER_encrypted.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LoRa_Ra-02_Arduino 2 | These are sample codes for LORA communication for the Arduino. It works with Semtech SX127x, HopeRF RFM9x, Microchip RN2483 long range, low power transceiver families. 3 | 4 | These examples code is based on RadioHead library so you will need to download the RadioHead library. 5 | You can do that by visiting the [AirSpayce's Radiohead site](http://www.airspayce.com/mikem/arduino/RadioHead/) 6 | For security reasons it is advisable to use the encrypted versions that use Advanced Encryption Standard (AES). 7 | These examples can be used to communicate with Raspberry Pi through python using examples from this library [rpsreal/pySX127x](https://github.com/rpsreal/pySX127x) 8 | 9 | 10 | **Note:** These examples can be used with different modules that do not use the 434MHz frequency but it is necessary to change the frequency in the files (#define RF95_FREQ). 11 | 12 | # Setup 13 | 14 | Wiring example with Arduino Pro Mini 3,3V 8MHz and AI-Thinker module Ra-02 (Semtech SX1278 433MHz frequency) 15 | 16 | ![wiring_img](./wiring.png) 17 | 18 | 19 | * 1º Install the [RadioHead library](http://www.airspayce.com/mikem/arduino/RadioHead/) in the Arduino IDE 20 | * * For the encrypted versions: 21 | * * 1.1º Install the [Base64 library](https://github.com/adamvr/arduino-base64) 22 | * * 1.2º Install the [AESLib library](https://github.com/DavyLandman/AESLib) 23 | * 2º Download and run the LORA_CLIENT to the Arduino IDE or [Raspberry Pi](https://github.com/rpsreal/pySX127x). 24 | * 3º Download and run the LORA_SERVER to the Arduino IDE or [Raspberry Pi](https://github.com/rpsreal/pySX127x). 25 | 26 | 27 | LORA_SERVER_encrypted 28 | ![serial_server_img](./LORA_SERVER_encrypted.png) 29 | LORA_CLIENT_encrypted 30 | ![serial_client_img](./LORA_CLIENT_encrypted.png) 31 | 32 | 33 | Developed by Rui Silva, Porto, Portugal 34 | -------------------------------------------------------------------------------- /wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rpsreal/LoRa_Ra-02_Arduino/e314ce5efda4818d592c37f33315b1d7b55ebb4f/wiring.png --------------------------------------------------------------------------------