Last week a package arrived from NiceGear with a SparkFun Pro RF – LoRa, 915MHz and some cables. With this gear I have built yet another client for my Azure IoT Hub and AdaFruit.IOLoRa Field Gateways.

Now that the device is running well, I’ll look at reducing power consumption and splitting the the payload packing code into a library. Also noticed an extra “,” on the end of a message so need to come up with a better way of doing the payload packing.
/* Copyright ® 2018 December devMobile Software, All Rights Reserved THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. You can do what you want with this code, acknowledgment would be nice. http://www.devmobile.co.nz */ #include <stdlib.h> #include <LoRa.h> #include <avr/dtostrf.h> #include "DHT.h" #define DEBUG //#define DEBUG_TELEMETRY //#define DEBUG_LORA // LoRa field gateway configuration (these settings must match your field gateway) const char FieldGatewayAddress[] = {"LoRaIoT1"}; const char DeviceAddress[] = {"SparkFunX1"}; const float FieldGatewayFrequency = 915000000.0; const byte FieldGatewaySyncWord = 0x12 ; // Payload configuration const int InterruptPin = 12; const int ChipSelectPin = 6; // LoRa radio payload configuration const byte SensorIdValueSeperator = ' ' ; const byte SensorReadingSeperator = ',' ; const int LoopSleepDelaySeconds = 10 ; const byte PayloadSizeMaximum = 64 ; byte payload[PayloadSizeMaximum]; byte payloadLength = 0 ; #define DHTPIN 4 // what digital pin we're connected to // Uncomment whatever type you're using! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 //#define DHTTYPE DHT21 // DHT 21 (AM2301) DHT dht(DHTPIN, DHTTYPE); void setup() { SerialUSB.begin(9600); #ifdef DEBUG while (!SerialUSB); #endif SerialUSB.println("Setup called"); SerialUSB.println("LoRa setup start"); // override the default chip select and reset pins LoRa.setPins(InterruptPin, ChipSelectPin); if (!LoRa.begin(FieldGatewayFrequency)) { SerialUSB.println("LoRa begin failed"); while (true); // Drop into endless loop requiring restart } // Need to do this so field gateways pays attention to messsages from this device LoRa.enableCrc(); LoRa.setSyncWord(FieldGatewaySyncWord); #ifdef DEBUG_LORA LoRa.dumpRegisters(SerialUSB); #endif SerialUSB.println("LoRa Setup done."); // Configure the Seeedstudio TH02 temperature & humidity sensor SerialUSB.println("DHT setup start"); dht.begin(); delay(100); SerialUSB.println("DHT setup done"); PayloadHeader((byte*)FieldGatewayAddress,strlen(FieldGatewayAddress), (byte*)DeviceAddress, strlen(DeviceAddress)); SerialUSB.println("Setup done"); SerialUSB.println(); } void loop() { float temperature = 17.2; float humidity = 75.0; SerialUSB.println("Loop called"); PayloadReset(); // Read the temperature & humidity & battery voltage values then display nicely temperature = dht.readTemperature(); humidity = dht.readHumidity(); if (isnan(humidity) || isnan(temperature)) { SerialUSB.println("Failed to read from DHT sensor!"); return; } SerialUSB.print("T:"); SerialUSB.print( temperature, 1 ) ; SerialUSB.println( "C " ) ; PayloadAdd( "T", temperature, 1); SerialUSB.print("H:"); SerialUSB.print( humidity, 0 ) ; SerialUSB.println( "% " ) ; PayloadAdd( "H", humidity, 0) ; #ifdef DEBUG_TELEMETRY SerialUSB.println(); SerialUSB.print( "RFM9X/SX127X Payload length:"); SerialUSB.print( payloadLength ); SerialUSB.println( " bytes" ); #endif LoRa.beginPacket(); LoRa.write( payload, payloadLength ); LoRa.endPacket(); SerialUSB.println("Loop done"); SerialUSB.println(); delay(LoopSleepDelaySeconds * 1000l); } void PayloadHeader( byte *to, byte toAddressLength, byte *from, byte fromAddressLength) { byte addressesLength = toAddressLength + fromAddressLength ; #ifdef DEBUG_TELEMETRY SerialUSB.println("PayloadHeader- "); SerialUSB.print( "To Address len:"); SerialUSB.print( toAddressLength ); SerialUSB.print( " From Address len:"); SerialUSB.print( fromAddressLength ); SerialUSB.print( " Addresses length:"); SerialUSB.print( addressesLength ); SerialUSB.println( ); #endif payloadLength = 0 ; // prepare the payload header with "To" Address length (top nibble) and "From" address length (bottom nibble) payload[payloadLength] = (toAddressLength << 4) | fromAddressLength ; payloadLength += 1; // Copy the "To" address into payload memcpy(&payload[payloadLength], to, toAddressLength); payloadLength += toAddressLength ; // Copy the "From" into payload memcpy(&payload[payloadLength], from, fromAddressLength); payloadLength += fromAddressLength ; } void PayloadAdd( char *sensorId, float value, byte decimalPlaces) { byte sensorIdLength = strlen( sensorId ) ; #ifdef DEBUG_TELEMETRY SerialUSB.println("PayloadAdd-float "); SerialUSB.print( "SensorId:"); SerialUSB.print( sensorId ); SerialUSB.print( " sensorIdLen:"); SerialUSB.print( sensorIdLength ); SerialUSB.print( " Value:"); SerialUSB.print( value, decimalPlaces ); SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); #endif memcpy( &payload[payloadLength], sensorId, sensorIdLength) ; payloadLength += sensorIdLength ; payload[ payloadLength] = SensorIdValueSeperator; payloadLength += 1 ; payloadLength += strlen( dtostrf(value, -1, decimalPlaces, (char *)&payload[payloadLength])); payload[ payloadLength] = SensorReadingSeperator; payloadLength += 1 ; #ifdef DEBUG_TELEMETRY SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); SerialUSB.println( ); #endif } void PayloadAdd( char *sensorId, int value ) { byte sensorIdLength = strlen( sensorId ) ; #ifdef DEBUG_TELEMETRY SerialUSB.println("PayloadAdd-int "); SerialUSB.print( "SensorId:"); SerialUSB.print( sensorId ); SerialUSB.print( " sensorIdLen:"); SerialUSB.print( sensorIdLength ); SerialUSB.print( " Value:"); SerialUSB.print( value ); SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); #endif memcpy( &payload[payloadLength], sensorId, sensorIdLength) ; payloadLength += sensorIdLength ; payload[ payloadLength] = SensorIdValueSeperator; payloadLength += 1 ; payloadLength += strlen( itoa( value,(char *)&payload[payloadLength],10)); payload[ payloadLength] = SensorReadingSeperator; payloadLength += 1 ; #ifdef DEBUG_TELEMETRY SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); SerialUSB.println( ); #endif } void PayloadAdd( char *sensorId, unsigned int value ) { byte sensorIdLength = strlen( sensorId ) ; #ifdef DEBUG_TELEMETRY SerialUSB.println("PayloadAdd-unsigned int "); SerialUSB.print( "SensorId:"); SerialUSB.print( sensorId ); SerialUSB.print( " sensorIdLen:"); SerialUSB.print( sensorIdLength ); SerialUSB.print( " Value:"); SerialUSB.print( value ); SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); #endif memcpy( &payload[payloadLength], sensorId, sensorIdLength) ; payloadLength += sensorIdLength ; payload[ payloadLength] = SensorIdValueSeperator; payloadLength += 1 ; payloadLength += strlen( utoa( value,(char *)&payload[payloadLength],10)); payload[ payloadLength] = SensorReadingSeperator; payloadLength += 1 ; #ifdef DEBUG_TELEMETRY SerialUSB.print( " payloadLength:"); SerialUSB.print( payloadLength); SerialUSB.println( ); #endif } void PayloadReset() { byte fromAddressLength = payload[0] & 0xf ; byte toAddressLength = payload[0] >> 4 ; byte addressesLength = toAddressLength + fromAddressLength ; payloadLength = addressesLength + 1; #ifdef DEBUG_TELEMETRY SerialUSB.println("PayloadReset- "); SerialUSB.print( "To Address len:"); SerialUSB.print( toAddressLength ); SerialUSB.print( " From Address len:"); SerialUSB.print( fromAddressLength ); SerialUSB.print( " Addresses length:"); SerialUSB.print( addressesLength ); SerialUSB.println( ); #endif }
