Skip to content

Instantly share code, notes, and snippets.

@MZachmann
Last active October 18, 2022 13:10
Show Gist options
  • Save MZachmann/e6b3892c357e30c7debf57af510e6c82 to your computer and use it in GitHub Desktop.
Save MZachmann/e6b3892c357e30c7debf57af510e6c82 to your computer and use it in GitHub Desktop.
A simple LoRa ping-pong application for the LoRa-E5 module by Seeed Studio
/*
* Copyright (c) 2022 Mark Zachmann
* Merged blinky, lora\receive, and lora\send from the Zephyr samples
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/device.h>
#include <zephyr/drivers/lora.h>
#include <errno.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#define DEFAULT_RADIO_NODE DT_ALIAS(lora0)
BUILD_ASSERT(DT_NODE_HAS_STATUS(DEFAULT_RADIO_NODE, okay),
"No default LoRa radio specified in DT");
#define MAX_DATA_LEN 255
// time to wait before sending a packet after reception
#define SLEEP_TIME_MS 1000
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(lora_receive);
/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
// clear the data area so we ensure we are receiving
void clearData(uint8_t* pdata)
{
for(int i=0; i<MAX_DATA_LEN; i++)
pdata[i] = 0;
}
// configure reception
int configureRx(const struct device *const lora_dev)
{
struct lora_modem_config config;
config.frequency = 915000000;
config.bandwidth = BW_125_KHZ;
config.datarate = SF_10;
config.preamble_len = 8;
config.coding_rate = CR_4_5;
config.iq_inverted = false;
config.public_network = false;
config.tx_power = 14;
config.tx = false;
int ret = lora_config(lora_dev, &config);
if (ret < 0) {
LOG_ERR("LoRa config failed");
}
return ret;
}
// configure transmission
int configureTx(const struct device *const lora_dev)
{
struct lora_modem_config config;
config.frequency = 915000000;
config.bandwidth = BW_125_KHZ;
config.datarate = SF_10;
config.preamble_len = 8;
config.coding_rate = CR_4_5;
config.iq_inverted = false;
config.public_network = false;
config.tx_power = 14;
config.tx = true;
int ret = lora_config(lora_dev, &config);
if (ret < 0) {
LOG_ERR("LoRa config failed");
}
return ret;
}
// MAIN
void main(void)
{
const struct device *const lora_dev = DEVICE_DT_GET(DEFAULT_RADIO_NODE);
int ret, len;
uint8_t data[MAX_DATA_LEN] = {0};
int16_t rssi;
int8_t snr;
int8_t cntr = '0';
// initialize the led output pin
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return;
}
// initialize the LoRa device
if (!device_is_ready(lora_dev)) {
LOG_ERR("%s Device not ready", lora_dev->name);
return;
}
// send and receive
LOG_INF("Starting the cycle");
for (int i = 0; i < 10; i++) {
// wait for a packet
gpio_pin_set_dt(&led, 1);
clearData(data);
// receive data
configureRx(lora_dev);
LOG_INF("Receiving data.");
len = lora_recv(lora_dev, data, MAX_DATA_LEN, K_SECONDS(5), &rssi, &snr);
if (len < 0) {
// if we didn't get a packet just reset the counter
LOG_ERR("LoRa receive failed");
cntr = '0';
}
else {
// we did get a packet, read the sent counter and increment it
LOG_INF("Received data: %s (RSSI:%ddBm, SNR:%ddBm)", data, rssi, snr);
cntr = ++data[1];
k_sleep(K_MSEC(SLEEP_TIME_MS));
if(cntr < '0' || cntr > '9')
cntr = '0';
}
// prep to send a packet
gpio_pin_set_dt(&led, 0);
clearData(data);
data[0] = 'N';
data[1] = cntr;
// send a packet
LOG_INF("Sending data.");
configureTx(lora_dev);
ret = lora_send(lora_dev, data, 2);
if (ret < 0) {
LOG_ERR("LoRa send failed");
}
}
// go to sleep
LOG_INF("Going to sleep.");
gpio_pin_set_dt(&led, 0);
k_sleep(K_FOREVER);
}
CONFIG_LOG=y
CONFIG_SPI=y
CONFIG_GPIO=y
CONFIG_LORA=y
CONFIG_LORA_SX12XX=y
CONFIG_PRINTK=y
CONFIG_CONSOLE=y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment