Reputation: 317
I'm trying send data from Arduino to ESP32 through LoRa. I'm using 2 identical Ra-02 Aithinker modules with antennas. I use ususal library for Arduino "LoRa" and same one ported for ESP32. I didn't implemented all the functions because I need only the sipliest setup.
Here is the code of ported library:
LoRa.h:
#ifndef LORA_H
#define LORA_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "soc/gpio_struct.h"
#include "driver/gpio.h"
#define PIN_NUM_MISO 25
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 19
#define PIN_NUM_CS 22
#define PIN_NUM_RST 18
#define LORA_DEFAULT_DIO0_PIN 2
#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1
// registers
#define REG_FIFO 0x00
#define REG_OP_MODE 0x01
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define REG_PA_CONFIG 0x09
#define REG_LNA 0x0c
#define REG_FIFO_ADDR_PTR 0x0d
#define REG_FIFO_TX_BASE_ADDR 0x0e
#define REG_FIFO_RX_BASE_ADDR 0x0f
#define REG_FIFO_RX_CURRENT_ADDR 0x10
#define REG_IRQ_FLAGS 0x12
#define REG_RX_NB_BYTES 0x13
#define REG_PKT_RSSI_VALUE 0x1a
#define REG_PKT_SNR_VALUE 0x1b
#define REG_MODEM_CONFIG_1 0x1d
#define REG_MODEM_CONFIG_2 0x1e
#define REG_PREAMBLE_MSB 0x20
#define REG_PREAMBLE_LSB 0x21
#define REG_PAYLOAD_LENGTH 0x22
#define REG_MODEM_CONFIG_3 0x26
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42
// modes
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
// PA config
#define PA_BOOST 0x80
// IRQ masks
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40
#define MAX_PKT_LENGTH 255
class LoRaClass{
public:
LoRaClass();
uint8_t begin(long frequency=0);
void sleep();
void setFrequency(long frequency);
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
void idle();
int parsePacket(int size = 0);
virtual int available();
virtual int read();
int packetRssi();
uint8_t beginPacket(uint8_t implicitHeader = false);
uint8_t endPacket();
size_t write(const uint8_t *buffer, size_t size);
void setSpreadingFactor(int sf);
void dumpRegisters();
private:
uint8_t singleTransfer(uint8_t data);
uint8_t readRegister(uint8_t address);
void writeRegister(uint8_t address, uint8_t value);
void explicitHeaderMode();
void implicitHeaderMode();
private:
//SPISettings _spiSettings;
spi_device_handle_t _spi;
int _ss;
int _reset;
int _dio0;
int _frequency;
int _packetIndex;
int _implicitHeaderMode;
void (*_onReceive)(int);
};
extern LoRaClass LoRa;
#endif
LoRa.c:
#include "LoRa.h"
// registers
#define REG_FIFO 0x00
#define REG_OP_MODE 0x01
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define REG_PA_CONFIG 0x09
#define REG_LNA 0x0c
#define REG_FIFO_ADDR_PTR 0x0d
#define REG_FIFO_TX_BASE_ADDR 0x0e
#define REG_FIFO_RX_BASE_ADDR 0x0f
#define REG_FIFO_RX_CURRENT_ADDR 0x10
#define REG_IRQ_FLAGS 0x12
#define REG_RX_NB_BYTES 0x13
#define REG_PKT_RSSI_VALUE 0x1a
#define REG_PKT_SNR_VALUE 0x1b
#define REG_MODEM_CONFIG_1 0x1d
#define REG_MODEM_CONFIG_2 0x1e
#define REG_PREAMBLE_MSB 0x20
#define REG_PREAMBLE_LSB 0x21
#define REG_PAYLOAD_LENGTH 0x22
#define REG_MODEM_CONFIG_3 0x26
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42
// modes
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
// PA config
#define PA_BOOST 0x80
// IRQ masks
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40
#define MAX_PKT_LENGTH 255
LoRaClass::LoRaClass() {
//_spiSettings(8E6, MSBFIRST, SPI_MODE0),
_ss = PIN_NUM_CS;
_reset = PIN_NUM_RST;
_dio0 = LORA_DEFAULT_DIO0_PIN;
_frequency = 0;
_packetIndex = 0;
_implicitHeaderMode = 0;
//_onReceive(NULL)
// setup pins
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE ;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (uint64_t)(((uint64_t)(((uint64_t)1)<<_ss)) | ((uint64_t)(((uint64_t)1)<<_reset)));
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE ;
gpio_config(&io_conf);
// perform reset
gpio_set_level((gpio_num_t)_reset, 0);
vTaskDelay(10 / portTICK_RATE_MS);
gpio_set_level((gpio_num_t)_reset, 1);
vTaskDelay(10 / portTICK_RATE_MS);
// set SS high
gpio_set_level((gpio_num_t)_ss, 1);
esp_err_t ret;
//memset(_spi,0,sizeof(spi_device_handle_t));
spi_bus_config_t buscfg;
memset(&buscfg,0,sizeof(buscfg));
buscfg.miso_io_num=PIN_NUM_MISO;
buscfg.mosi_io_num=PIN_NUM_MOSI;
buscfg.sclk_io_num=PIN_NUM_CLK;
buscfg.quadwp_io_num=-1;
buscfg.quadhd_io_num=-1;
spi_device_interface_config_t devcfg;
memset(&devcfg,0,sizeof(devcfg));
devcfg.clock_speed_hz=2*1000*1000; //Clock out at 10 MHz
devcfg.mode=0;
devcfg.spics_io_num=-1; //CS pin
devcfg.queue_size=7; //We want to be able to queue 7 transactions at a time
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
if (ret != ESP_OK) {
printf("Error: spi_bus_initialize: %0d",ret);
}
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &_spi);
if (ret != ESP_OK) {
printf("Error: spi_bus_add_device: %0d",ret);
}
printf("\n\nLoRa Initialized\n");
}
uint8_t LoRaClass::begin(long frequency) {
uint8_t version = readRegister(REG_VERSION);
if (version != 0x12) {
return version;
}
sleep();
if (frequency>0) setFrequency(frequency);
writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
writeRegister(REG_FIFO_RX_BASE_ADDR, 0);
writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);
writeRegister(REG_MODEM_CONFIG_3, 0x04);
setTxPower(17);
idle();
printf("\n\nLoRa started\n");
return 1;
}
uint8_t LoRaClass::singleTransfer(uint8_t data)
{
uint32_t resp=0;
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8; //Command is 8 bits
t.tx_buffer=&data; //The data is the cmd itself
t.rx_buffer=&resp;
ret = spi_device_transmit(_spi, &t); //Transmit!
if (ret != ESP_OK) printf("spi_device_transmit error: 0x%0x\n",ret);
return resp;
}
uint8_t LoRaClass::readRegister(uint8_t address)
{
gpio_set_level((gpio_num_t)_ss, 0);
vTaskDelay(1 / portTICK_RATE_MS);
singleTransfer(address & 0x7f);
//printf(".");
uint8_t resp = singleTransfer(0x00);
vTaskDelay(1 / portTICK_RATE_MS);
gpio_set_level((gpio_num_t)_ss, 1);
return resp;
}
void LoRaClass::writeRegister(uint8_t address, uint8_t value)
{
gpio_set_level((gpio_num_t)_ss, 0);
vTaskDelay(1 / portTICK_RATE_MS);
singleTransfer(address | 0x80);
singleTransfer(value);
vTaskDelay(1 / portTICK_RATE_MS);
gpio_set_level((gpio_num_t)_ss, 1);
}
void LoRaClass::sleep()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
}
void LoRaClass::setFrequency(long frequency)
{
_frequency = frequency;
long fstep = 61.03515625;
long frfl = frequency/fstep;
uint64_t frf = ((uint64_t)frfl);
writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16));
writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8));
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
}
void LoRaClass::setTxPower(int level, int outputPin)
{
if (PA_OUTPUT_RFO_PIN == outputPin) {
// RFO
if (level < 0) {
level = 0;
} else if (level > 14) {
level = 14;
}
writeRegister(REG_PA_CONFIG, 0x70 | level);
} else {
// PA BOOST
if (level < 2) {
level = 2;
} else if (level > 17) {
level = 17;
}
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
}
}
void LoRaClass::idle()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
}
int LoRaClass::parsePacket(int size)
{
int packetLength = 0;
int irqFlags = readRegister(REG_IRQ_FLAGS);
if (size > 0) {
implicitHeaderMode();
writeRegister(REG_PAYLOAD_LENGTH, size & 0xff);
} else {
explicitHeaderMode();
}
writeRegister(REG_IRQ_FLAGS, irqFlags);
if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
_packetIndex = 0;
if (_implicitHeaderMode) {
packetLength = readRegister(REG_PAYLOAD_LENGTH);
} else {
packetLength = readRegister(REG_RX_NB_BYTES);
}
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));
idle();
} else
if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE)) {
writeRegister(REG_FIFO_ADDR_PTR, 0);
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE);
}
return packetLength;
}
void LoRaClass::explicitHeaderMode()
{
_implicitHeaderMode = 0;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
}
void LoRaClass::implicitHeaderMode()
{
_implicitHeaderMode = 1;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | 0x01);
}
int LoRaClass::available()
{
return (readRegister(REG_RX_NB_BYTES) - _packetIndex);
}
int LoRaClass::read()
{
_packetIndex++;
return readRegister(REG_FIFO);
}
int LoRaClass::packetRssi()
{
return (readRegister(REG_PKT_RSSI_VALUE) - (_frequency < 868000000 ? 164 : 157));
}
uint8_t LoRaClass::beginPacket(uint8_t implicitHeader)
{
idle();
if (implicitHeader) {
implicitHeaderMode();
} else {
explicitHeaderMode();
}
writeRegister(REG_FIFO_ADDR_PTR, 0);
writeRegister(REG_PAYLOAD_LENGTH, 0);
return 1;
}
uint8_t LoRaClass::endPacket()
{
// put in TX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
// wait for TX done
while((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0);
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
return 1;
}
size_t LoRaClass::write(const uint8_t *buffer, size_t size)
{
int currentLength = readRegister(REG_PAYLOAD_LENGTH);
// check size
if ((currentLength + size) > MAX_PKT_LENGTH) {
size = MAX_PKT_LENGTH - currentLength;
}
// write data
for (size_t i = 0; i < size; i++) {
writeRegister(REG_FIFO, buffer[i]);
}
// update length
writeRegister(REG_PAYLOAD_LENGTH, currentLength + size);
return size;
}
void LoRaClass::setSpreadingFactor(int sf)
{
if (sf < 6) {
sf = 6;
} else if (sf > 12) {
sf = 12;
}
if (sf == 6) {
writeRegister(REG_DETECTION_OPTIMIZE, 0xc5);
writeRegister(REG_DETECTION_THRESHOLD, 0x0c);
} else {
writeRegister(REG_DETECTION_OPTIMIZE, 0xc3);
writeRegister(REG_DETECTION_THRESHOLD, 0x0a);
}
writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0));
}
void LoRaClass::dumpRegisters()
{
for (int i = 0; i < 128; i++) {
printf("0x%02X=0x%02X\n",i,readRegister(i));
}
}
On Arduino I send like this:
LoRa.beginPacket();
LoRa.write(0);
LoRa.write(1);
LoRa.write(2);
LoRa.write(3);
LoRa.endPacket();
delay(3000);
On ESP32 I receive like this:
while (1) {
packetSize = LoRa.parsePacket();
if (packetSize>0) {
printf("\nReceived: ");
while (LoRa.available()) {
printf("%02X ",LoRa.read());
}
printf(" (RSSI: %0d)\n", LoRa.packetRssi());
}
}
But problem is that I receive this:
Received: 99 CB 2B 0F (RSSI: -89)
Received: 90 0D 2B 1F (RSSI: -90)
Received: 9A 9D 2B 0F (RSSI: -94)
Received: 00 01 2B 07 (RSSI: -87)
Received: 00 0D 2B 0F (RSSI: -89)
Received: 9A 0B 2B 0F (RSSI: -94)
Received: A8 C1 2B 0F (RSSI: -90)
Received: 00 01 A3 03 (RSSI: -88)
Received: 00 07 2B 0F (RSSI: -87)
Received: 00 0D 2B 0F (RSSI: -89)
Received: 09 08 2B 5F (RSSI: -89)
Received: 99 08 02 0A (RSSI: -95)
Received: A9 0B 2B 0F (RSSI: -95)
Could anybody please suggest waht to fix in order to receive data correct?
BTW, from ESP32 to ESP32 data comes correctly. I also dumped SX1278 registers on both sides - they are identical.
Upvotes: 0
Views: 1604
Reputation: 11
Have you checked the SPI frequency on the Arduino side? The developer of the LoRa library says in the FAQ that 5v Arduinos might experience problems when using logic level converters to talk to the 3.3v LoRa module. You might need to slowdown the speed of the SPI bus in order to work.
Upvotes: 1