Created
March 10, 2024 20:04
-
-
Save mrcodetastic/7deb4724d89c1f0c882c53ff64e9c05e to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
RadioLib SX127x Ping-Pong Example | |
For default module settings, see the wiki page | |
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem | |
For full API reference, see the GitHub Pages | |
https://jgromes.github.io/RadioLib/ | |
Customised for a ESP32 S3 'hat' that uses the following PIN mappings: | |
// SX127x | |
GPIO 3 for SX127x 'NSS' (Slave Select) PIN | |
GPIO 11 for SX127x 'DII00' PIN | |
GPIO 12 for SX127x 'Reset' PIN | |
GPIO 9 for SX127x SPI Clock Pin | |
GPIO 7 for SX127x SPI MISO Pin | |
GPIO 5 for SX127x SPI MOSI Pin | |
GPIO 3 for SX127x 'NSS' (Slave Select) PIN | |
// OLED Screen - One of these generic 128x32 ones from AliExpress | |
// https://www.aliexpress.com/item/1005005973981064.html?spm=a2g0o.productlist.main.1.5870g7JMg7JMYv | |
GPIO 33 for SDK (Clock) | |
GPIO 18 for SDA (Data) | |
// Set one of the devices to the transmitter by uncommenting 'MASTER_TRANSMIT_NODE' and the other as a reciever. | |
*/ | |
// include the library | |
#include <RadioLib.h> | |
#include <Arduino.h> | |
#include <U8x8lib.h> | |
#include <Adafruit_NeoPixel.h> | |
// uncomment the following only on one | |
// of the nodes to initiate the pings | |
//#define MASTER_TRANSMIT_NODE | |
// Which pin on the Arduino is connected to the NeoPixels? | |
#define PIN 39 // On Trinket or Gemma, suggest changing this to 1 | |
// How many NeoPixels are attached to the Arduino? | |
#define NUMPIXELS 1 // Popular NeoPixel ring size | |
SPIClass spi(HSPI); // for esp32s2 | |
// When we are NOT the transmitter | |
#ifndef MASTER_TRANSMIT_NODE | |
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE, /* clock=*/33, /* data=*/18); // pin remapping with ESP8266 HW I2C | |
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); | |
#endif | |
// SX1278 has the following connections: | |
// NSS pin: 10 | |
// DIO0 pin: 2 | |
// NRST pin: 9 | |
// DIO1 pin: 3 | |
SX1278 radio = new Module(3, 11, 12, RADIOLIB_NC, spi); | |
// or using RadioShield | |
// https://github.com/jgromes/RadioShield | |
//SX1278 radio = RadioShield.ModuleA; | |
// save transmission states between loops | |
int transmissionState = RADIOLIB_ERR_NONE; | |
// flag to indicate transmission or reception state | |
bool transmitFlag = false; | |
// flag to indicate that a packet was sent or received | |
volatile bool operationDone = false; | |
// this function is called when a complete packet | |
// is transmitted or received by the module | |
// IMPORTANT: this function MUST be 'void' type | |
// and MUST NOT have any arguments! | |
void setFlag(void) { | |
// we sent or received packet, set the flag | |
operationDone = true; | |
} | |
void blink_led() { | |
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) | |
delay(300); | |
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW | |
} | |
unsigned long last_packet_recieve_ms = 0; | |
unsigned long time_elapsed_ms_start = 0; | |
void setup() { | |
delay(3000); | |
Serial.begin(112500); | |
#ifdef MASTER_TRANSMIT_NODE | |
pinMode(LED_BUILTIN, OUTPUT); | |
#endif | |
// IF NOT the transmitter | |
#ifndef MASTER_TRANSMIT_NODE | |
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) | |
u8x8.begin(); | |
u8x8.setPowerSave(0); | |
u8x8.setFont(u8x8_font_chroma48medium8_r); | |
u8x8.drawString(0, 1, "Starting!"); | |
u8x8.setInverseFont(1); | |
u8x8.drawString(0, 0, "012345678901234567890123456789"); | |
u8x8.drawString(0, 3, "012345678901234567890123456789"); | |
u8x8.setInverseFont(0); | |
//u8x8.drawString(0,8,"Line 8"); | |
//u8x8.drawString(0,9,"Line 9"); | |
// u8x8.refreshDisplay(); // only required for SSD1606/7 | |
delay(1000); | |
u8x8.setInverseFont(0); | |
#endif | |
/* | |
for (int i = 0; i <3; i++) | |
{ | |
Serial.println("Starting..."); | |
delay(1000); | |
} | |
*/ | |
Serial.println("Starting..."); | |
spi.begin(9, 7, 5, 3); | |
// initialize SX1278 with default settings | |
Serial.print(F("[SX1278] Initializing ... ")); | |
int state = radio.begin(); | |
if (state == RADIOLIB_ERR_NONE) { | |
Serial.println(F("success!")); | |
} else { | |
Serial.print(F("failed, code ")); | |
Serial.println(state); | |
while (true) | |
; | |
} | |
// set output power to 10 dBm (accepted range is -3 - 17 dBm) | |
// NOTE: 20 dBm value allows high power operation, but transmission | |
// duty cycle MUST NOT exceed 1% | |
if (radio.setOutputPower(16) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { | |
Serial.println(F("Selected output power is invalid for this module!")); | |
while (true) | |
; | |
} | |
// set the function that will be called | |
// when new packet is received | |
radio.setDio0Action(setFlag, RISING); | |
#if defined(MASTER_TRANSMIT_NODE) | |
// send the first packet on this node | |
Serial.print(F("[SX1278] Sending first packet ... ")); | |
transmissionState = radio.startTransmit("Hello World!"); | |
transmitFlag = true; | |
#else | |
// start listening for LoRa packets on this node | |
Serial.print(F("[SX1278] Starting to listen ... ")); | |
state = radio.startReceive(); | |
if (state == RADIOLIB_ERR_NONE) { | |
Serial.println(F("success!")); | |
} else { | |
Serial.print(F("failed, code ")); | |
Serial.println(state); | |
while (true) | |
; | |
} | |
#endif | |
time_elapsed_ms_start = millis(); | |
} | |
void loop() { | |
unsigned long time_elapsed_sec = (millis() - time_elapsed_ms_start) / 1000; | |
if ((millis() - last_packet_recieve_ms > 3000)) { | |
// send another one | |
Serial.print(F("[SX1278] Timeout occured, sending another packet ... ")); | |
transmissionState = radio.startTransmit("You there?"); | |
transmitFlag = true; | |
last_packet_recieve_ms = millis(); | |
operationDone = true; | |
transmitFlag = true; | |
} | |
// check if the previous operation finished | |
if (operationDone) { | |
// reset flag | |
operationDone = false; | |
if (transmitFlag) { | |
// the previous operation was transmission, listen for response | |
// print the result | |
if (transmissionState == RADIOLIB_ERR_NONE) { | |
// packet was successfully sent | |
Serial.println(F("transmission finished!")); | |
#ifdef MASTER_TRANSMIT_NODE | |
blink_led(); | |
#endif | |
last_packet_recieve_ms = millis(); | |
} else { | |
Serial.print(F("failed, code ")); | |
Serial.println(transmissionState); | |
} | |
// listen for response | |
radio.startReceive(); | |
transmitFlag = false; | |
} else { | |
// the previous operation was reception | |
// print data and send another packet | |
String str; | |
int state = radio.readData(str); | |
if (state == RADIOLIB_ERR_NONE) { | |
// packet was successfully received | |
Serial.println(F("[SX1278] Received packet!")); | |
#ifndef MASTER_TRANSMIT_NODE | |
blink_led(); | |
#endif | |
// print data of the packet | |
Serial.print(F("[SX1278] Data:\t\t")); | |
Serial.println(str); | |
// print RSSI (Received Signal Strength Indicator) | |
Serial.print(F("[SX1278] RSSI:\t\t")); | |
float rssi = radio.getRSSI(); | |
Serial.print(rssi); | |
Serial.println(F(" dBm")); | |
// print SNR (Signal-to-Noise Ratio) | |
Serial.print(F("[SX1278] SNR:\t\t")); | |
Serial.print(radio.getSNR()); | |
Serial.println(F(" dB")); | |
#ifndef MASTER_TRANSMIT_NODE | |
u8x8.clearDisplay(); | |
u8x8.drawString(0, 0, "Got packet!"); | |
u8x8.drawString(0, 1, String(str).c_str()); | |
char dbm_cstr[16]; | |
snprintf(dbm_cstr, 15, "%.0f dBm", rssi); | |
u8x8.drawString(0, 2, dbm_cstr); | |
// Print Millis | |
u8x8.drawString(0, 3, String(time_elapsed_sec).c_str()); | |
if (rssi > -50) { | |
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255 | |
// Here we're using a moderately bright green color: | |
pixels.setPixelColor(0, pixels.Color(0, 192, 0)); | |
} else if (rssi > -90) { | |
// orange | |
// https://www.w3schools.com/colors/colors_picker.asp | |
pixels.setPixelColor(0, pixels.Color(255, 153, 51)); | |
} else { | |
pixels.setPixelColor(0, pixels.Color(192, 0, 0)); | |
} | |
pixels.show(); // Send the updated pixel colors to the hardware. | |
#endif | |
} | |
// wait a second before transmitting again | |
delay(1000); | |
// send another one | |
Serial.print(F("[SX1278] Sending another packet ... ")); | |
transmissionState = radio.startTransmit("Hello World!"); | |
transmitFlag = true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment