Last active
September 19, 2024 14:43
-
-
Save SyncChannel/06f1918742e4943e5692 to your computer and use it in GitHub Desktop.
LoRa_FeatherWing_DevBreakout_TransceiverMode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* LoRa FeatherWing Tranceiver Mode Example Program | |
* By: Dan Watson | syncchannel.blogspot.com | |
* Date: 2-23-2016 | |
* Version: 0.2 | |
* | |
* Example Tranceiver Mode Program for the LoRa FeatherWing for Adafruit Feather | |
* Tested with Feather M0, Feather 32U4 and Feather HUZZAH | |
* | |
* This program configures the Feather as a LoRa receiver. It is intended as a companion | |
* to the LoRA FeatherWing Beacon Example Program, and can receive the beacon messages. | |
* It can also be modified to relay serial communications between Feather nodes, amongst | |
* other things. | |
* | |
* This program is adapted from the RFM95W_Nexus library created by Gerben den Hartog | |
* It has been adapted from his code to work specifically on Adafruit Feather with | |
* the LoRa FeatherWing. Credit is given to Gerben for is useful library and work! | |
* Check out his full github repo if you are interested in LoRaWAN. | |
* | |
* Based on a library by Gerben den Hartog | |
* https://github.com/Ideetron/RFM95W_Nexus | |
* http://www.ideetron.nl/LoRa | |
* | |
*/ | |
// Only the Arduino SPI library is needed to compile this program | |
#include <SPI.h> | |
//Define pin descriptions (Adafruit Feather M0 and 32U4) | |
#define DIO0 5 | |
#define DIO5 6 | |
#define CS 10 | |
#define LED 13 | |
//Use these pin definitions instead for Feather HUZZAH | |
//#define DIO0 4 | |
//#define DIO5 5 | |
//#define CS 2 | |
//#define LED 0 | |
// Set frequency of RFM module | |
// Available frequencies depend on which RFM module you have | |
#define RFM_FREQ_MHZ 915000000 | |
// Define the length of the user message payload in bytes | |
#define PACKAGE_LENGTH 10 | |
// Holder for the received data bytes | |
unsigned char RFM_Package[PACKAGE_LENGTH]; | |
void setup() | |
{ | |
Serial.begin(9600); | |
//Initialize SPI | |
SPI.begin(); | |
SPI.beginTransaction(SPISettings(4000000,MSBFIRST,SPI_MODE0)); | |
//Initialize I/O pins | |
pinMode(DIO0,INPUT); | |
pinMode(DIO5,INPUT); | |
pinMode(CS,OUTPUT); | |
pinMode(LED,OUTPUT); | |
// Pull chip select high for now | |
digitalWrite(CS,HIGH); | |
// Minimum of 100ms recommended to allow RFM module to start up | |
delay(200); | |
//Initialize the RFM module | |
RFM_Init(); | |
// Flash D13 LED on Feather to notify user that setup is complete | |
for (int i = 0; i <= 3; i++) | |
{ | |
digitalWrite(LED, HIGH); | |
delay(100); | |
digitalWrite(LED, LOW); | |
delay(200); | |
} | |
} | |
void loop() | |
{ | |
//Check if the RFM has received a package | |
if(digitalRead(DIO0) == HIGH) | |
{ | |
digitalWrite(LED, HIGH); | |
//Get package from RFM | |
RFM_ReadPackage(RFM_Package); | |
//Send package over Serial | |
for(int i = 0; i < PACKAGE_LENGTH; i++) | |
{ | |
Serial.print(RFM_Package[i], HEX); | |
Serial.print(" "); | |
} | |
Serial.println(""); | |
delay(50); | |
digitalWrite(LED, LOW); | |
} | |
} | |
/* | |
* Function to initialize the RFM module. | |
* It is highly recommended that you read the datasheet for the module, there are lots of | |
* settings you can adjust to improve the wireless link parameters for your specific usage | |
* http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf | |
*/ | |
void RFM_Init() | |
{ | |
//Set RFM module in sleep mode to change to LoRa mode | |
RFM_Write(0x01,0x00); | |
//Set LoRa mode | |
RFM_Write(0x01,0x80); | |
//Set RFM module in standby mode to change more settings | |
RFM_Write(0x01,0x81); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
// Set carrier frequency | |
// RFM_FREQ_MHZ / 61.035 Hz = 3 byte value to load | |
unsigned long freqHolder = RFM_FREQ_MHZ / 61.035; // round down | |
uint8_t freqLSB = freqHolder; | |
uint8_t freq2B = (freqHolder >> 8); | |
uint8_t freqMSB = (freqHolder >> 16); | |
RFM_Write(0x06,freqMSB); | |
RFM_Write(0x07,freq2B); | |
RFM_Write(0x08,freqLSB); | |
//Set maximum transmit power settings | |
RFM_Write(0x09,0xFF); | |
//Set bandwith 250 kHz, Coding rate = 4/8, Implicit header mode | |
RFM_Write(0x1D,0x89); | |
//Spreading factor 11, PayloadCRC on | |
RFM_Write(0x1E,0xB4); | |
//*NOTE: If you decide to change to Spreading Factor 6, you also need to set the following | |
//*two registers by uncommenting these lines | |
//RFM_Write(0x31,0xC5); | |
//RFM_Write(0x37,0x0C); | |
//Preamble length 0x0018 + 4 = 28 | |
RFM_Write(0x20,0x00); | |
RFM_Write(0x21,0x18); | |
//Payload length | |
RFM_Write(0x22,PACKAGE_LENGTH); | |
//Set RFM in continues receive | |
RFM_Write(0x01,0x85); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
} | |
/* This function is used to read a value from a specific register of the RFM module | |
* Arguments: RFM_Adress Adress of the register to read | |
* Return: The value of the register is returned | |
*/ | |
unsigned char RFM_Read(unsigned char RFM_Address) | |
{ | |
unsigned char RFM_Data; | |
//Set CS pin low to start SPI communication | |
digitalWrite(CS,LOW); | |
//Send Address | |
SPI.transfer(RFM_Address); | |
//Send 0x00 to receive the answer from the RFM | |
RFM_Data = SPI.transfer(0x00); | |
//Set CS high to end communication | |
digitalWrite(CS,HIGH); | |
//Return received data | |
return RFM_Data; | |
} | |
/* This function is used to write a value to a specific register of the RFM module | |
* Arguments: RFM_Adress Adress of the register to be written | |
* RFM_Data Data that will be written | |
*/ | |
void RFM_Write(unsigned char RFM_Address, unsigned char RFM_Data) | |
{ | |
//Set CS pin low to start communication | |
digitalWrite(CS,LOW); | |
//Send Addres with MSB 1 to make it a write command | |
SPI.transfer(RFM_Address | 0x80); | |
//Send Data | |
SPI.transfer(RFM_Data); | |
//Set CS pin high to end communication | |
digitalWrite(CS,HIGH); | |
} | |
/* This function is used to send a message payload | |
* Arguments: *RFM_Package Pointer to the array with the data to send | |
*/ | |
void RFM_SendPackage(unsigned char *RFM_Package) | |
{ | |
//Switch RFM to standby | |
RFM_Write(0x01,0x81); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
//Set SPI pointer to Tx base address | |
RFM_Write(0x0D,0x80); | |
//Switch DIO to TxDone | |
RFM_Write(0x40,0x40); | |
//Write payload in to the FIFO | |
for(int i = 0; i < PACKAGE_LENGTH; i++) | |
{ | |
RFM_Write(0x00,*RFM_Package); | |
RFM_Package++; | |
} | |
//Switch RFM to TX | |
RFM_Write(0x01,0x83); | |
while(digitalRead(DIO0) == LOW) | |
{ | |
//Wait for Tx Done | |
} | |
//Clear interrupt | |
RFM_Write(0x12,0x08); | |
//Set DIO0 to RxDone | |
RFM_Write(0x40,0x00); | |
//Set RFM in continues receive | |
RFM_Write(0x01,0x85); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
} | |
/* This function is used to receive a message/payload from the RFM module | |
* Arguments: *RFM_Package Pointer to the array with the data to send | |
*/ | |
void RFM_ReadPackage(unsigned char *RFM_Package) | |
{ | |
unsigned char RFM_Interrupt; | |
unsigned char RFM_PackageLocation; | |
//Get interrupt register | |
RFM_Interrupt = RFM_Read(0x12); | |
//Switch RFM to Standby | |
RFM_Write(0x01,0x81); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
//Clear interrupt register | |
RFM_Write(0x12,0x60); | |
//Get package location | |
RFM_PackageLocation = RFM_Read(0x10); | |
//Set SPI pointer to Packagelocation | |
RFM_Write(0x0D,RFM_PackageLocation); | |
//Get message | |
for(int i = 0; i < PACKAGE_LENGTH; i++) | |
{ | |
*RFM_Package = RFM_Read(0x00); | |
RFM_Package++; | |
} | |
//Switch RFM to receive | |
RFM_Write(0x01,0x85); | |
while(digitalRead(DIO5) == LOW) | |
{ | |
//Wait for mode ready | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment