This is a demo IoTMCU LoRa Radio Node V1.0 868/915MHz client (based on one of the examples from Arduino-LoRa) that uploads telemetry data to my Windows 10 IoT Core on Raspberry PI field gateway proof of concept(PoC).
The devices arrived promptly and the sample code and schematics made adapting my Arduino code easy.
Bill of materials (Prices Sep 2018)
- LoRa Radio Node v1.0 868/915 USD29.80(for 2) NZD72.17
- Seeedstudio Temperature&Humidity Sensor USD11.50 NZD20
- Seeedstudio 4 pin Female Jumper to Grove 4 pin Conversion Cable USD2.90
The code is pretty basic, it shows how to pack the payload and set the necessary RFM9X/SX127X LoRa module configuration, has no power conservation, advanced wireless configuration etc.
/* Adapted from LoRa Duplex communication with Sync Word Sends temperature & humidity data from Seeedstudio https://www.seeedstudio.com/Grove-Temperature-Humidity-Sensor-High-Accuracy-Min-p-1921.html To my Windows 10 IoT Core RFM 9X library https://blog.devmobile.co.nz/2018/09/03/rfm9x-iotcore-payload-addressing/ */ #include // include libraries #include #include const int csPin = 10; // LoRa radio chip select const int resetPin = 9; // LoRa radio reset const int irqPin = 2; // change for your board; must be a hardware interrupt pin // Field gateway configuration const char FieldGatewayAddress[] = "LoRaIoT1"; const float FieldGatewayFrequency = 915000000.0; const byte FieldGatewaySyncWord = 0x12 ; // Payload configuration const int PayloadSizeMaximum = 64 ; byte payload[PayloadSizeMaximum] = ""; const byte SensorReadingSeperator = ',' ; // Manual serial number configuration const char DeviceId[] = {"IoTMCU915"}; const int LoopSleepDelaySeconds = 60 ; void setup() { Serial.begin(9600); while (!Serial); Serial.println("LoRa Setup"); // override the default CS, reset, and IRQ pins (optional) LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin if (!LoRa.begin(FieldGatewayFrequency)) { Serial.println("LoRa init failed. Check your connections."); while (true); } // Need to do this so field gateways pays attention to messages from this device LoRa.enableCrc(); LoRa.setSyncWord(FieldGatewaySyncWord); //LoRa.dumpRegisters(Serial); Serial.println("LoRa Setup done."); // Configure the Seeedstudio TH02 temperature & humidity sensor Serial.println("TH02 setup"); TH02.begin(); delay(100); Serial.println("TH02 Setup done"); Serial.println("Setup done"); } void loop() { int payloadLength = 0 ; float temperature ; float humidity ; Serial.println("Loop called"); memset(payload, 0, sizeof(payload)); // prepare the payload header with "To" Address length (top nibble) and "From" address length (bottom nibble) payload[0] = (strlen(FieldGatewayAddress) << 4) | strlen( DeviceId ) ; payloadLength += 1; // Copy the "To" address into payload memcpy(&payload[payloadLength], FieldGatewayAddress, strlen(FieldGatewayAddress)); payloadLength += strlen(FieldGatewayAddress) ; // Copy the "From" into payload memcpy(&payload[payloadLength], DeviceId, strlen(DeviceId)); payloadLength += strlen(DeviceId) ; // Read the temperature and humidity values then display nicely temperature = TH02.ReadTemperature(); humidity = TH02.ReadHumidity(); Serial.print("T:"); Serial.print( temperature, 1 ) ; Serial.print( "C" ) ; Serial.print(" H:"); Serial.print( humidity, 0 ) ; Serial.println( "%" ) ; // Copy the temperature into the payload payload[ payloadLength] = 't'; payloadLength += 1 ; payload[ payloadLength] = ' '; payloadLength += 1 ; payloadLength += strlen( dtostrf(temperature, -1, 1, &payload[payloadLength])); payload[ payloadLength] = SensorReadingSeperator; payloadLength += sizeof(SensorReadingSeperator) ; // Copy the humidity into the payload payload[ payloadLength] = 'h'; payloadLength += 1 ; payload[ payloadLength] = ' '; payloadLength += 1 ; payloadLength += strlen( dtostrf(humidity, -1, 0, &payload[payloadLength])); // display info about payload then send it (No ACK) with LoRa unlike nRF24L01 Serial.print( "RFM9X/SX127X Payload length:"); Serial.print( payloadLength ); Serial.println( " bytes" ); LoRa.beginPacket(); LoRa.write( payload, payloadLength ); LoRa.endPacket(); Serial.println("Loop done"); delay(LoopSleepDelaySeconds * 1000l); }
In the debug output window the messages from the device looked like this
Register 0x40 – Value 0X00 – Bits 00000000
Register 0x41 – Value 0X00 – Bits 00000000
Register 0x42 – Value 0X12 – Bits 00010010
…
The thread 0x6f8 has exited with code 0 (0x0).
The thread 0x2f0 has exited with code 0 (0x0).
19:35:35-RX From IoTMCU915 PacketSnr 10.0 Packet RSSI -45dBm RSSI -109dBm = 11 byte message "t 19.8,h 88"
Sensor IoTMCU915t Value 19.8
Sensor IoTMCU915h Value 88
AzureIoTHubClient SendEventAsync start
AzureIoTHubClient SendEventAsync finish
The thread 0x9b0 has exited with code 0 (0x0).
The thread 0x9f4 has exited with code 0 (0x0).
The thread 0x9dc has exited with code 0 (0x0).
The thread 0x17fc has exited with code 0 (0x0).
The thread 0x944 has exited with code 0 (0x0).
19:36:35-RX From IoTMCU915 PacketSnr 10.8 Packet RSSI -45dBm RSSI -108dBm = 11 byte message "t 19.7,h 88"
Sensor IoTMCU915t Value 19.7
Sensor IoTMCU915h Value 88
AzureIoTHubClient SendEventAsync start
AzureIoTHubClient SendEventAsync finish
The thread 0xbf0 has exited with code 0 (0x0).
I have some suitable batteries on order from Jaycar a local supplier. There is also a 433MHz version of this device available other regions.
Hello, I need if you can send me a picture of how to connect the USB / TTL cable to LoRa Radio Node v1.0 to upload the scketch the arduino ide.
Thank you.
Hi
I used an FTDI module I had lying around then some Female-Female jumpers to connect pins
@KiwiBryn
Whats the name lf the ftdi module?
I think it came from either iteadstudio or seeedstudio
Is the RFM95W module included in the package or do you have to buy that seperately?
Hi
Mine cam fully assembled from
https://www.tindie.com/stores/IOTMCU/
@KiwiBryn
hello, i wonder the code and lib (lora.h) in this post works with IoTMCU LoRa Radio Node V1.0 or Arduino LoRa which you designed.
Hi
I used the excellent (https://github.com/sandeepmistry/arduino-LoRa) by Sandeep Mistry for all my *duino based clients. I added a simple wrapper to format the payloads to suit my Windows 10 IoT core and .Net Core on RPI field gateways.
I documented the SPI/Reset/Chip select/Interrupt (if used) pins for the RFM9X/Microcontroller for each device and hopefully used the right keywords so that they were easy to for others to find.
@KiwiBryn