Scenario
There are two Arduinos with a SemTech LoRa shieldSemTech LoRa shield connected.
One Arduino will be the transmitter, the second one the receiver.
When the transmitter receives a request to send (in my example it gets that request via the USB serial port), it creates a package and beams it out as a LoRa radio signal.
The other Arduino ( the receiver, has to be a MKR 1040 GSMMKR 1040 GSM or another Arduino with a GSM shield) is continuously polling for LoRa traffic.
When it picks up a payload, it sends that data to a predefined telephone number (my mobile phone).
You can see the result in the screen captures below.
The right upper monitor shows the transmitter. I typed "from SemTech LoRa: Hello, world!"
The lower monitor shows that the receiver got the message and forwarded it as an SMS.
My mobile phone on the left has received that payload as a text message.
I've used 434 MHz, antennas need to be matched and mounted on the LF connector of the shields.
If you prefer to use the 868 or 915 band, you just need to change a few parameters in the sketches and mount a matching antenna on the HF connectors.
Connections
The connections you make are identical for sender and receiver.
The table below shows the required links to be made.
The sender does not have to be a specific Arduino type, as long as it's 3V3 version. Don't use an Arduino UNO.
If you choose a non-MKR Arduino, take care that you pass the pins that nSS (nCS), DIO0 and DIO1 are connected to, as parameters to the constructor.
GSM Antenna is Required
Put antennas on the radios and the GSM board, please. Without antenna, the Arduino will behave badly.
Measurements with different antennas from the Molex evaluation kit - all on a scale from 0 no reception to 31 best reception:
- Without antenna (don't do this at home - bad behaviour): 1
- With Molex 146185 Cellular Band antenna; 22
- With Molex 105263 Cellular 6 Band antenna: 23
- With Molex 146220 GPS + WIFI combo 23
- With Molex 146186 GPS + WIFI combo 14
Transmitter sketch
/* LoRaLib Transmit Example This example transmits LoRa packets with one second delays between them. Each packet contains up to 256 bytes of data, in the form of: - Arduino String - null-terminated char array (C-string) - arbitrary binary data (byte array) For more detailed information, see the LoRaLib Wiki https://github.com/jgromes/LoRaLib/wiki For full API reference, see the GitHub Pages https://jgromes.github.io/LoRaLib/ */ // include the library #include <LoRaLib.h> // create instance of LoRa class using SX1278 module // this pinout corresponds to RadioShield // https://github.com/jgromes/RadioShield // NSS pin: 10 (4 on ESP32/ESP8266 boards) // DIO0 pin: 2 // DIO1 pin: 3 SX1276 lora = new LoRa(7, 2, 3); void setup() { Serial.begin(9600); // initialize SX1278 with default settings Serial.println(F("Initializing ... \n")); // carrier frequency: 434.0 MHz // bandwidth: 125.0 kHz // spreading factor: 9 // coding rate: 7 // sync word: 0x12 // output power: 17 dBm // current limit: 100 mA // preamble length: 8 symbols // amplifier gain: 0 (automatic gain control) int state = lora.begin(); if (state == ERR_NONE) { Serial.println(F("success!")); } else { Serial.print(F("failed, code ")); Serial.println(state); while (true); } } void loop() { // sms text Serial.println("Enter SMS content: "); char txtMsg[200]; readSerial(txtMsg); Serial.println("SENDING"); Serial.println(); Serial.println("Message:"); Serial.println(txtMsg); Serial.print(F("Sending packet ... ")); // you can transmit C-string or Arduino string up to // 256 characters long // NOTE: transmit() is a blocking method! // See example TransmitInterrupt for details // on non-blocking transmission method. int state = lora.transmit(txtMsg); if (state == ERR_NONE) { // the packet was successfully transmitted Serial.println(F(" success!")); // print measured data rate Serial.print(F("Datarate:\t")); Serial.print(lora.getDataRate()); Serial.println(F(" bps")); } else if (state == ERR_PACKET_TOO_LONG) { // the supplied packet was longer than 256 bytes Serial.println(F(" too long!")); } else if (state == ERR_TX_TIMEOUT) { // timeout occurred while transmitting packet Serial.println(F(" timeout!")); } // wait a second before transmitting again delay(1000); } /* Read input serial */ int readSerial(char result[]) { int i = 0; while (1) { while (Serial.available() > 0) { char inChar = Serial.read(); if (inChar == '\n') { result[i] = '\0'; Serial.flush(); return 0; } if (inChar != '\r') { result[i] = inChar; i++; } } } }
Receiver sketch
/* SMS sender This sketch, for the MKR GSM 1400 board,sends an SMS message you enter in the serial monitor. Connect your Arduino with the GSM shield and SIM card, open the serial monitor, and wait for the "READY" message to appear in the monitor. Next, type a message to send and press "return". Make sure the serial monitor is set to send a newline when you press return. Circuit: * MKR GSM 1400 board * Antenna * SIM card that can send SMS created 25 Feb 2012 by Tom Igoe */ /* LoRaLib Receive Example This example listens for LoRa transmissions and tries to receive them. To successfully receive data, the following settings have to be the same on both transmitter and receiver: - carrier frequency - bandwidth - spreading factor - coding rate - sync word - preamble length For more detailed information, see the LoRaLib Wiki https://github.com/jgromes/LoRaLib/wiki For full API reference, see the GitHub Pages https://jgromes.github.io/LoRaLib/ */ // Include the GSM library #include <MKRGSM.h> // include the LoRa library #include <LoRaLib.h> #include "arduino_secrets.h" // Please enter your sensitive data in the Secret tab or arduino_secrets.h // PIN Number const char PINNUMBER[] = SECRET_PINNUMBER; // initialize the library instance GSM gsmAccess; GSM_SMS sms; // create instance of LoRa class using SX1278 module // this pinout corresponds to RadioShield // https://github.com/jgromes/RadioShield // NSS pin: 10 (4 on ESP32/ESP8266 boards) // DIO0 pin: 2 // DIO1 pin: 3 SX1278 lora = new LoRa(7, 2, 3); char remoteNum[20]; // telephone number to send sms void setup() { // initialize serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } // initialize SX1278 with default settings Serial.print(F("Initializing ... ")); // carrier frequency: 434.0 MHz // bandwidth: 125.0 kHz // spreading factor: 9 // coding rate: 7 // sync word: 0x12 // output power: 17 dBm // current limit: 100 mA // preamble length: 8 symbols // amplifier gain: 0 (automatic gain control) int state = lora.begin(); if (state == ERR_NONE) { Serial.println(F("success!")); } else { Serial.print(F("failed, code ")); Serial.println(state); while (true); } Serial.println("SMS Messages Sender"); // connection state bool connected = false; // Start GSM shield // If your SIM has PIN, pass it as a parameter of begin() in quotes while (!connected) { if (gsmAccess.begin(PINNUMBER) == GSM_READY) { connected = true; } else { Serial.println("Not connected"); delay(1000); } } Serial.println("GSM initialized"); Serial.print("Enter a mobile number: "); readSerial(remoteNum); Serial.println(remoteNum); } void loop() { Serial.print(F("Waiting for incoming transmission ... ")); String str; int state = lora.receive(str); if (state == ERR_NONE) { // packet was successfully received Serial.println(F("success!")); // print data of the packet Serial.print(F("Data:\t\t\t")); Serial.println(str); Serial.println("SENDING"); Serial.println(); Serial.println("Message:"); Serial.println(str); // send the message sms.beginSMS(remoteNum); sms.print(str); sms.endSMS(); Serial.println("\nCOMPLETE!\n"); // print RSSI (Received Signal Strength Indicator) // of the last received packet Serial.print(F("RSSI:\t\t\t")); Serial.print(lora.getRSSI()); Serial.println(F(" dBm")); // print SNR (Signal-to-Noise Ratio) // of the last received packet Serial.print(F("SNR:\t\t\t")); Serial.print(lora.getSNR()); Serial.println(F(" dB")); // print frequency error // of the last received packet Serial.print(F("Frequency error:\t")); Serial.print(lora.getFrequencyError()); Serial.println(F(" Hz")); } else if (state == ERR_RX_TIMEOUT) { // timeout occurred while waiting for a packet Serial.println(F("timeout!")); } else if (state == ERR_CRC_MISMATCH) { // packet was received, but is malformed Serial.println(F("CRC error!")); } } /* Read input serial */ int readSerial(char result[]) { int i = 0; while (1) { while (Serial.available() > 0) { char inChar = Serial.read(); if (inChar == '\n') { result[i] = '\0'; Serial.flush(); return 0; } if (inChar != '\r') { result[i] = inChar; i++; } } } }
Both sketches are based on examples from the MKRGSM (SendSMS) and LoRaLib (Transmit and Receive) libraries.
I did only mix, move and match to get the desired functionality.
real world scenario:
The transmitter has sensors and sends measurements to the receiver over LoRa. The receiver sends an SMS if the measurements are out of range
A panic button in a basement where there is no mobile phone reception. |
Top Comments