0

我正在尝试通过 LoRa 将数据从 Arduino 发送到 ESP32。我正在使用 2 个带有天线的相同 Ra-02 Aithinker 模块。我为 Arduino “LoRa”使用常用库,为 ESP32移植相同的库。我没有实现所有功能,因为我只需要最简单的设置。

这是移植库的代码:

罗拉.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

洛拉.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));
  }
}

在 Arduino 上,我这样发送:

  LoRa.beginPacket();
  LoRa.write(0);
  LoRa.write(1);
  LoRa.write(2);
  LoRa.write(3);
  LoRa.endPacket();

  delay(3000);

在 ESP32 上,我收到这样的信息:

while (1) {     

            packetSize = LoRa.parsePacket();        
            if (packetSize>0) {
                printf("\nReceived: ");
                while (LoRa.available()) {
                    printf("%02X ",LoRa.read());
                }       
                printf(" (RSSI: %0d)\n", LoRa.packetRssi());

            }                       

        }

但问题是我收到了这个:

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)

有人可以建议修复以正确接收数据吗?

顺便说一句,从 ESP32 到 ESP32 的数据正确。我还在两边都转储了 SX1278 寄存器——它们是相同的。

4

1 回答 1

1

你检查过 Arduino 端的 SPI 频率吗?LoRa 库的开发人员在FAQ中表示,5v Arduinos 在使用逻辑电平转换器与 3.3v LoRa 模块通信时可能会遇到问题。您可能需要降低 SPI 总线的速度才能工作。

于 2018-03-16T17:38:25.280 回答