Hello,
Im using a RFM9x LoRa Radio module from Adafruit (product 3073) and I cannot get it to work with my Arduino Micro using the RadioHead library, which is recommended on the AdaFruit product page.
I get the "LoRa radio init failed" error.
Looking in the source code of the library I saw that the code errors out in the RH_RF95::init() function, where it attempts to set a mode and read it back to verify the write:
if (spiRead(RH_RF95_REG_01_OP_MODE) != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE))
{
Serial.println(spiRead(RH_RF95_REG_01_OP_MODE), HEX);
return false; // No device present?
}
I triple checked the wiring and it looks fine to me, so I wrote a small test sketch to read the first 6 registers of the lora module, and all of them come back as 0, despite all of them having non-zero reset values:
void setup() {
pinMode(7, OUTPUT); // set the SS pin as an output
SPI.begin(); // initialize the SPI library
Serial.begin(115200);
}
void loop() {
digitalWrite(7, LOW); // set the SS pin to LOW
for(byte reg = 0; reg <= 6; reg++) {
Serial.print(reg);
Serial.print("\t");
Serial.println(SPI.transfer(reg));
delay(100);
}
digitalWrite(7, HIGH); // set the SS pin HIGH
Serial.println("--------------------");
delay(1000);
}
Output of above sketch is:
0 0
1 0
2 0
3 0
4 0
5 0
6 0
Below I attach a picture of my setup, the LoRa module is attached to the default SPI interface:
where did you get the SPI pin connections from?
maybe worth doing a web search for Arduino Micro pinout?
I also find the following program useful
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-spi-communication-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
//Find the default SPI pins for your board
//Make sure you have the right board selected in Tools > Boards
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(3000);
Serial.print("MOSI: ");
Serial.println(MOSI);
Serial.print("MISO: ");
Serial.println(MISO);
Serial.print("SCK: ");
Serial.println(SCK);
Serial.print("SS: ");
Serial.println(SS);
Serial.print("SDA: ");
Serial.println(SDA);
Serial.print("SCL: ");
Serial.println(SCL);
}
void loop() {
// put your main code here, to run repeatedly:
}
I don't have a Arduino micro but the Arduino Pro Micro reports
connected a RFM95W to a Arduino Pro Micro using the following
// Pro Micro with RPi HAT RFM95W
// Pro Micro SCK pin 15 to RFM95_pin SCK
// Pro Micro MISO pin 14 to RFM95_pin MISO
// Pro Micro MOSI pin 16 to RFM95_pin MOSI
// Pro Micro pin 7 to RFM95 SS
// Pro Micro pin 6 to RFM95 Reset
// Pro Micro pin 5 to RFM95 DIO0
// Pro Micro pin 4 to RFM95 DIO1
And here is a program that prints all the registers, you do need to set the;
#define NSS 10 //lora device select
To match your own setup.
/*******************************************************************************************************
Program Operation - This program is stand alone, it is not necessary to install a LoRa library to use
it. This test program is for the SX127X LoRa devices.
The program checks that a lora device can be accessed by doing a test register write and read.
If there is no device found a message is printed on the serial monitor. The contents of the registers
from 0x00 to 0x7F are printed.
The Arduino pin number that NSS on the LoRa device is connected to must be specified in #define NSS
line below. Leave the NRESET and DIOx pins not connected.
Typical printout;
2_Register_Test Starting
LoRa Device found
Device version 0x12
Frequency at Start 434000000
Registers at Start
Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 00 09 1A 0B 00 52 6C 80 00 4F 09 2B 20 08 02 0A
0x10 FF 70 15 0B 28 0C 12 47 32 3E 00 00 00 00 00 40
0x20 00 00 00 00 05 00 03 93 55 55 55 55 55 55 55 55
0x30 90 40 40 00 00 0F 00 00 00 F5 20 82 FD 02 80 40
0x40 00 00 12 24 2D 00 03 00 04 23 00 09 05 84 32 2B
0x50 14 00 00 10 00 00 00 0F E0 00 0C FD 06 00 5C 78
0x60 00 19 0C 4B CC 0D FD 20 04 47 AF 3F F6 3F DB 0B
0x70 D0 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00
Note: An SX1272 will report as version 0x22 and the frequency at power up is 915000000hz.
Serial monitor baud rate is set at 115200.
*******************************************************************************************************/
const uint8_t REG_FRMSB = 0x06; //register number for setting and reading frequency, high byte
const uint8_t REG_FRMID = 0x07; //register number for setting and reading frequency, mid byte
const uint8_t REG_FRLSB = 0x08; //register number for setting and reading frequency, low byte
const uint8_t REG_VERSION = 0x42; //register containg version number of device
//********* Setup hardware pin definition here ! **************
#define NSS 10 //lora device select
//**************************************************************/
#include <SPI.h>
uint32_t frequency;
void setup()
{
Serial.begin(115200);
Serial.println(F("2_Register_Test Starting"));
SPI.begin();
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
//The begin function setups the hardware pins used by device and then checks if device is found
if (begin(NSS))
{
Serial.println(F("LoRa Device found"));
}
else
{
Serial.println(F("No device responding"));
}
Serial.print(F("Device version 0x"));
uint8_t deviceversion = readRegister(REG_VERSION);
if (deviceversion < 0x10)
{
Serial.print(F("0"));
}
Serial.println(deviceversion, HEX);
frequency = getFreqInt(); //read the set frequency following a reset
Serial.print(F("Frequency at Start "));
Serial.println(frequency);
Serial.println(F("Registers at Start ")); //show the all registers following a power up
printRegisters(0x00, 0x7F);
}
void loop()
{
}
uint8_t readRegister(uint8_t address)
{
uint8_t regdata;
digitalWrite(NSS, LOW); //set NSS low
SPI.transfer(address & 0x7F); //mask address for read
regdata = SPI.transfer(0); //read the byte
digitalWrite(NSS, HIGH); //set NSS high
return regdata;
}
void writeRegister(uint8_t address, uint8_t value)
{
digitalWrite(NSS, LOW); //set NSS low
SPI.transfer(address | 0x80); //mask address for write
SPI.transfer(value); //write the byte
digitalWrite(NSS, HIGH); //set NSS high
}
uint32_t getFreqInt()
{
//get the current set LoRa device frequency, return as long integer
uint8_t Msb, Mid, Lsb;
uint32_t uinttemp;
float floattemp;
Msb = readRegister(REG_FRMSB);
Mid = readRegister(REG_FRMID);
Lsb = readRegister(REG_FRLSB);
floattemp = ((Msb * 0x10000ul) + (Mid * 0x100ul) + Lsb);
floattemp = ((floattemp * 61.03515625) / 1000000ul);
uinttemp = (uint32_t)(floattemp * 1000000);
return uinttemp;
}
void printRegisters(uint16_t Start, uint16_t End)
{
//prints the contents of lora device registers to serial monitor
uint16_t Loopv1, Loopv2, RegData;
Serial.print(F("Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F"));
Serial.println();
for (Loopv1 = Start; Loopv1 <= End;)
{
Serial.print(F("0x"));
if (Loopv1 < 0x10)
{
Serial.print(F("0"));
}
Serial.print((Loopv1), HEX);
Serial.print(F(" "));
for (Loopv2 = 0; Loopv2 <= 15; Loopv2++)
{
RegData = readRegister(Loopv1);
if (RegData < 0x10)
{
Serial.print(F("0"));
}
Serial.print(RegData, HEX);
Serial.print(F(" "));
Loopv1++;
}
Serial.println();
}
}
bool begin(int8_t pinNSS)
{
pinMode(pinNSS, OUTPUT);
digitalWrite(pinNSS, HIGH);
if (checkDevice())
{
return true;
}
return false;
}
bool checkDevice()
{
//check there is a device out there, writes a register and reads back
uint8_t Regdata1, Regdata2;
Regdata1 = readRegister(REG_FRMID); //low byte of frequency setting
writeRegister(REG_FRMID, (Regdata1 + 1));
Regdata2 = readRegister(REG_FRMID); //read changed value back
writeRegister(REG_FRMID, Regdata1); //restore register to original value
if (Regdata2 == (Regdata1 + 1))
{
return true;
}
else
{
return false;
}
}
There is a longer version that changes the frequency registers as a check to be sure the device can be written to, but the begin() function does as an initial check write then read back a change to REG_FRMID (0x07) as a check to see if there is a read\write device there.
although the pin settings of post 5 worked with the lmic library to communicate with LoRaWAN they did not work with the Arduino LoRa library using callbacks or the Radiohead RH_RF95 library
I switched to using the same pins as the Adafruit Feather 32u4 LoRa (which uses same processor as the Pro micro) for SS, reset and DIO0, e.g.
// Pro Micro with RPi HAT RFM95W
// Pro Micro pin 8 to RFM95 SS // same pins as Feather 32u4 LoRa
// Pro Micro pin 4 to RFM95 Reset
// Pro Micro pin 7 to RFM95 DIO0
// Pro Micro pin 6 to RFM95 DIO1
both LoRa.h and Radiohead examples then worked OK, e.g. radiohead settings for RH_RF95
// for feather32u4 and Pro Micro
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7