The second package to arrive was a Raspberry Pi+ LoRa(TM) Expansion Board populated with HopeRF 434MHz & 915MHz modules. It was in a small cardboard box with bolts+spacers and had a small set of printed instructions.
The shield has four user controlable Light Emitting Diodes(LED) connected to General Purpose Input Output(GPIO) pins which will be useful for providing feedback when trying to debug faults etc..
Some of the pin numbers are also printed on the shield silk screen.
This time the first step was to check the pin assignments of the 4 LEDs
//--------------------------------------------------------------------------------- // Copyright (c) September 2018, devMobile Software // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //--------------------------------------------------------------------------------- namespace devMobile.IoT.Rfm9x.UputronicsRPIPlusLed { using System; using System.Threading; using Windows.ApplicationModel.Background; using Windows.Devices.Gpio; public sealed class StartupTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { GpioController gpioController = GpioController.GetDefault(); GpioPin ce01LedPin = gpioController.OpenPin(5); ce01LedPin.SetDriveMode(GpioPinDriveMode.Output); ce01LedPin.Write(GpioPinValue.Low); GpioPin ceo2LedPin = gpioController.OpenPin(21); ceo2LedPin.SetDriveMode(GpioPinDriveMode.Output); ceo2LedPin.Write(GpioPinValue.High); GpioPin lanLedPin = gpioController.OpenPin(6); lanLedPin.SetDriveMode(GpioPinDriveMode.Output); lanLedPin.Write(GpioPinValue.Low); GpioPin internetLedPin = gpioController.OpenPin(13); internetLedPin.SetDriveMode(GpioPinDriveMode.Output); internetLedPin.Write(GpioPinValue.High); while (true) { if (ce01LedPin.Read() == GpioPinValue.High) { ce01LedPin.Write(GpioPinValue.Low); } else { ce01LedPin.Write(GpioPinValue.High); } if (ceo2LedPin.Read() == GpioPinValue.High) { ceo2LedPin.Write(GpioPinValue.Low); } else { ceo2LedPin.Write(GpioPinValue.High); } if (lanLedPin.Read() == GpioPinValue.High) { lanLedPin.Write(GpioPinValue.Low); } else { lanLedPin.Write(GpioPinValue.High); } if (internetLedPin.Read() == GpioPinValue.High) { internetLedPin.Write(GpioPinValue.Low); } else { internetLedPin.Write(GpioPinValue.High); } Thread.Sleep(500); } } } }
I think there is a small issue with the internet LED it should be GPIO13 (which matches the pin number)
The next step was to get the Serial Peripheral Interface (SPI) interface for both modules working.
//--------------------------------------------------------------------------------- // Copyright (c) September 2018, devMobile Software // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //--------------------------------------------------------------------------------- namespace devMobile.IoT.Rfm9x.UputronicsRPIPlusSPI { using System; using System.Diagnostics; using System.Threading; using Windows.ApplicationModel.Background; using Windows.Devices.Spi; public sealed class StartupTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { #if CS0 const int chipSelectPinNumber = 0; #endif #if CS1 const int chipSelectPinNumber = 1; #endif SpiController spiController = SpiController.GetDefaultAsync().AsTask().GetAwaiter().GetResult(); var settings = new SpiConnectionSettings(chipSelectPinNumber) { ClockFrequency = 500000, Mode = SpiMode.Mode0, // From SemTech docs pg 80 CPOL=0, CPHA=0 }; SpiDevice Device = spiController.GetDevice(settings); while (true) { byte[] writeBuffer = new byte[] { 0x42 }; // RegVersion byte[] readBuffer = new byte[1]; // Read the RegVersion silicon ID to check SPI works Device.TransferSequential(writeBuffer, readBuffer); #if CS0 Debug.WriteLine("CS0 Register RegVer 0x{0:x2} - Value 0X{1:x2} - Bits {2}", writeBuffer[0], readBuffer[0], Convert.ToString(readBuffer[0], 2).PadLeft(8, '0')); #endif #if CS1 Debug.WriteLine("CS1 Register RegVer 0x{0:x2} - Value 0X{1:x2} - Bits {2}", writeBuffer[0], readBuffer[0], Convert.ToString(readBuffer[0], 2).PadLeft(8, '0')); #endif Thread.Sleep(10000); } } } }
Like the other uputronics shield I have tested this appears not to have the reset line of the RFM9X connected.
The output confirmed the code worked with both CS0 and CS1 defined
CS0 Register RegVer 0x42 - Value 0X12 - Bits 00010010 CS0 Register RegVer 0x42 - Value 0X12 - Bits 00010010 CS0 Register RegVer 0x42 - Value 0X12 - Bits 00010010 CS0 Register RegVer 0x42 - Value 0X12 - Bits 00010010
CS1 Register RegVer 0x42 - Value 0X12 - Bits 00010010 CS1 Register RegVer 0x42 - Value 0X12 - Bits 00010010 CS1 Register RegVer 0x42 - Value 0X12 - Bits 00010010
Would have been more useful to read RegFrMsb = 0x06, RegFrMid = 0x7, and RegFrLsb = 0x08 so I could see the different default frequencies of the two HopeRF modules. The next step is to build support for this shield into my RFM9X.IoTCore library.