This is a demo Ingenuity Micro Nexus client (based on the Netduino example for my RFM9XLoRaNetMF library) that uploads temperature and humidity data to my Azure IoT Hubs/Central or AdaFruit.IO on Raspberry PI field gateways
Bill of materials (Prices June 2019).
- Nexus USD24.95
- Seeedstudio Temperature&Humidity Sensor USD11.50 NZD20
- 5CM 4 Pin buckled cable USD1.90 NZD34.75
// <copyright file="client.cs" company="devMobile Software"> // Copyright ® 2019 Feb devMobile Software, All Rights Reserved // // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE" // // </copyright> namespace devMobile.IoT.Nexus.FieldGateway { using System; using System.Text; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using devMobile.IoT.NetMF.ISM; using devMobile.NetMF.Sensor; using IngenuityMicro.Nexus; class NexusClient { private Rfm9XDevice rfm9XDevice; private readonly TimeSpan dueTime = new TimeSpan(0, 0, 15); private readonly TimeSpan periodTime = new TimeSpan(0, 0, 60); private readonly SiliconLabsSI7005 sensor = new SiliconLabsSI7005(); private readonly Led _led = new Led(); private readonly byte[] fieldGatewayAddress = Encoding.UTF8.GetBytes("LoRaIoT1"); private readonly byte[] deviceAddress = Encoding.UTF8.GetBytes("Nexus915"); public NexusClient() { rfm9XDevice = new Rfm9XDevice(SPI.SPI_module.SPI3, (Cpu.Pin)28, (Cpu.Pin)15, (Cpu.Pin)26); _led.Set(0, 0, 0); } public void Run() { rfm9XDevice.Initialise(frequency: 915000000, paBoost: true, rxPayloadCrcOn: true); rfm9XDevice.Receive(deviceAddress); rfm9XDevice.OnDataReceived += rfm9XDevice_OnDataReceived; rfm9XDevice.OnTransmit += rfm9XDevice_OnTransmit; Timer humidityAndtemperatureUpdates = new Timer(HumidityAndTemperatureTimerProc, null, dueTime, periodTime); Thread.Sleep(Timeout.Infinite); } private void HumidityAndTemperatureTimerProc(object state) { _led.Set(0, 128, 0); double humidity = sensor.Humidity(); double temperature = sensor.Temperature(); Debug.Print(DateTime.UtcNow.ToString("hh:mm:ss") + " H:" + humidity.ToString("F1") + " T:" + temperature.ToString("F1")); rfm9XDevice.Send(fieldGatewayAddress, Encoding.UTF8.GetBytes("t " + temperature.ToString("F1") + ",H " + humidity.ToString("F0"))); } void rfm9XDevice_OnTransmit() { _led.Set(0, 0, 0); Debug.Print("Transmit-Done"); } void rfm9XDevice_OnDataReceived(byte[] address, float packetSnr, int packetRssi, int rssi, byte[] data) { try { string messageText = new string(UTF8Encoding.UTF8.GetChars(data)); string addressText = new string(UTF8Encoding.UTF8.GetChars(address)); Debug.Print(DateTime.UtcNow.ToString("HH:MM:ss") + "-Rfm9X PacketSnr " + packetSnr.ToString("F1") + " Packet RSSI " + packetRssi + "dBm RSSI " + rssi + "dBm = " + data.Length + " byte message " + @"""" + messageText + @""""); } catch (Exception ex) { Debug.Print(ex.Message); } } } }
Overall the development process was good with no modifications to my RFM9X.NetMF library or SI7005 library (bar removing a Netduino I2C work around) required


