有没有办法在 SX1262 868M LoRa Hat 和 Heltec 的 ESP32 WiFi LoRa V3 之间建立 LoRa 连接?

问题描述 投票:0回答:1

我有 SX1262 868M LoRa 帽子,附带测试代码。这总结了初始化设备的函数调用。

node = sx126x.sx126x(serial_num = "/dev/ttyS0", freq=868, addr=0, power=22, rssi=True, air_speed=2400, relay=False)

现在,我尝试将这顶帽子设置为接收器(代码已经做到了),并将 ESP32(也配备了 SX1262)设置为具有以下代码的发送器:

LoRa发射器.h

#include "LoRaWan_APP.h"
#include "Arduino.h"

class LoRaTransmitter {
  private:
    RadioEvents_t RadioEvents;
    static LoRaTransmitter* instance;
    bool txDone;
    LoRaTransmitter();

  public:
    static LoRaTransmitter* getInstance();
    void send(const char *message);
    void send(const String &message);
    static void OnTxDone(void);
    static void OnTxTimeout(void);
};

LoRa发射器.cpp


#include "LoRaTransmitter.h"

#define RF_FREQUENCY 868000000 // Hz
#define TX_OUTPUT_POWER 22 // dBm
#define LORA_BANDWIDTH 2 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7..SF12]
#define LORA_CODINGRATE 1 // [1: 4/5, 2: 4/6, 3: 4/7, // 4: 4/8]
#define LORA_PREAMBLE_LENGTH 4 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define BUFFER_SIZE 512

LoRaTransmitter* LoRaTransmitter::instance;

LoRaTransmitter::LoRaTransmitter() {
  Mcu.begin();
  RadioEvents.TxDone = OnTxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  Radio.Init(&RadioEvents);
  Radio.SetChannel(RF_FREQUENCY);
  Radio.SetTxConfig(
    MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
    LORA_SPREADING_FACTOR, LORA_CODINGRATE,
    LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
    true, 0, 0, LORA_IQ_INVERSION_ON, 3000);
  txDone = true;
}

LoRaTransmitter* LoRaTransmitter::getInstance() {
  if (instance == nullptr)
    instance = new LoRaTransmitter();
  return instance;
}

void LoRaTransmitter::send(const char *message) {
  if (txDone) {
    txDone = false;
    Serial.println("Sending message: " + String(message) + ", Length: " + String(strlen(message)));
    char packet[BUFFER_SIZE];
    strncpy(packet, message, BUFFER_SIZE);
    Radio.Send((uint8_t *)packet, strlen(packet));
  }
  Radio.IrqProcess();
}

void LoRaTransmitter::send(const String &message) {
  send(message.c_str());
}

void LoRaTransmitter::OnTxDone(void) {
  Serial.print("TX done......");
  instance->txDone = true;
}

void LoRaTransmitter::OnTxTimeout(void) {
  Radio.Sleep();
  Serial.print("TX Timeout......");
}

现在,我还将复制用于帽子的设置类:

import RPi.GPIO as GPIO
import serial
import time
class sx126x:
    M0 = 22
    M1 = 27
    # if the header is 0xC0, then the LoRa register settings don't get lost when it powers off, and 0xC2 will be lost.
    # cfg_reg = [0xC0, 0x00, 0x09, 0x00, 0x00, 0x00, 0x62, 0x00, 0x17, 0x43, 0x00, 0x00]
    cfg_reg = [0xC2, 0x00, 0x09, 0x00, 0x00, 0x00, 0x62, 0x00, 0x12, 0x43, 0x00, 0x00]
    get_reg = bytes(12)
    rssi = False
    addr = 65535
    serial_n = ""
    addr_temp = 0
    # start frequency of the two LoRa modules
    # E22-400T22S           E22-900T22S
    # 410~493MHz      or    850~930MHz
    start_freq = 850
    # offset between start and end frequency of the two LoRa modules
    # E22-400T22S           E22-900T22S
    # 410~493MHz      or    850~930MHz
    offset_freq = 18
    # power = 22
    # air_speed =2400
    SX126X_UART_BAUDRATE_1200 = 0x00
    SX126X_UART_BAUDRATE_2400 = 0x20
    SX126X_UART_BAUDRATE_4800 = 0x40
    SX126X_UART_BAUDRATE_9600 = 0x60
    SX126X_UART_BAUDRATE_19200 = 0x80
    SX126X_UART_BAUDRATE_38400 = 0xA0
    SX126X_UART_BAUDRATE_57600 = 0xC0
    SX126X_UART_BAUDRATE_115200 = 0xE0
    SX126X_PACKAGE_SIZE_240_BYTE = 0x00
    SX126X_PACKAGE_SIZE_128_BYTE = 0x40
    SX126X_PACKAGE_SIZE_64_BYTE = 0x80
    SX126X_PACKAGE_SIZE_32_BYTE = 0xC0
    SX126X_Power_22dBm = 0x00
    SX126X_Power_17dBm = 0x01
    SX126X_Power_13dBm = 0x02
    SX126X_Power_10dBm = 0x03
    lora_air_speed_dic = {
        1200:0x01,
        2400:0x02,
        4800:0x03,
        9600:0x04,
        19200:0x05,
        38400:0x06,
        62500:0x07
    }
    lora_power_dic = {
        22:0x00,
        17:0x01,
        13:0x02,
        10:0x03
    }
    lora_buffer_size_dic = {
        240:SX126X_PACKAGE_SIZE_240_BYTE,
        128:SX126X_PACKAGE_SIZE_128_BYTE,
        64:SX126X_PACKAGE_SIZE_64_BYTE,
        32:SX126X_PACKAGE_SIZE_32_BYTE
    }

    def __init__(self, serial_num, freq, addr, power, rssi, air_speed=2400, net_id=0, buffer_size = 240, crypt=0, relay=False, lbt=False, wor=False):
        self.rssi = rssi
        self.addr = addr
        self.freq = freq
        self.serial_n = serial_num
        self.power = power
        # Initial the GPIO for M0 and M1 Pin
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        GPIO.setup(self.M0, GPIO.OUT)
        GPIO.setup(self.M1, GPIO.OUT)
        GPIO.output(self.M0, GPIO.LOW)
        GPIO.output(self.M1, GPIO.HIGH)
        # The hardware UART of Pi3B+, Pi4B is /dev/ttyS0
        self.ser = serial.Serial(serial_num, 9600)
        self.ser.flushInput()
        self.set(freq, addr, power, rssi, air_speed, net_id, buffer_size, crypt, relay, lbt, wor)

    def set(self, freq, addr, power, rssi, air_speed=2400, \
            net_id=0, buffer_size = 240, crypt=0, \
            relay=False, lbt=False, wor=False):
        self.send_to = addr
        self.addr = addr
        # We should pull up the M1 pin when setting the module
        GPIO.output(self.M0, GPIO.LOW)
        GPIO.output(self.M1, GPIO.HIGH)
        time.sleep(0.1)
        low_addr = addr & 0xff
        high_addr = addr >> 8 & 0xff
        net_id_temp = net_id & 0xff
        if freq > 850:
            freq_temp = freq - 850
            self.start_freq = 850
            self.offset_freq = freq_temp
        elif freq >410:
            freq_temp = freq - 410
            self.start_freq  = 410
            self.offset_freq = freq_temp
        air_speed_temp = self.lora_air_speed_dic.get(air_speed, None)
        # if air_speed_temp != None
        buffer_size_temp = self.lora_buffer_size_dic.get(buffer_size, None)
        # if air_speed_temp != None:
        power_temp = self.lora_power_dic.get(power, None)
        #if power_temp != None:
        if rssi:
            # enable printing rssi value
            rssi_temp = 0x80
        else:
            # disable printing rssi value
            rssi_temp = 0x00
        # get crypt
        l_crypt = crypt & 0xff
        h_crypt = crypt >> 8 & 0xff
        if relay==False:
            self.cfg_reg[3] = high_addr
            self.cfg_reg[4] = low_addr
            self.cfg_reg[5] = net_id_temp
            self.cfg_reg[6] = self.SX126X_UART_BAUDRATE_9600 + air_speed_tempreadingto read noise rssi value when add 0x20 as follows
            self.cfg_reg[7] = buffer_size_temp + power_temp + 0x20
            self.cfg_reg[8] = freq_temp
            # it will output a packet rssi value following received message
            # when enabling the eighth bit with 06H register(rssi_temp = 0x80)
            self.cfg_reg[9] = 0x43 + rssi_temp
            self.cfg_reg[10] = h_crypt
            self.cfg_reg[11] = l_crypt
        else:
            self.cfg_reg[3] = 0x01
            self.cfg_reg[4] = 0x02
            self.cfg_reg[5] = 0x03
            self.cfg_reg[6] = self.SX126X_UART_BAUDRATE_9600 + air_speed_temp
            # it will enable to read noise rssi value when add 0x20 as follow
            self.cfg_reg[7] = buffer_size_temp + power_temp + 0x20
            self.cfg_reg[8] = freq_temp
            # it will output a packet rssi value following received message
            # when enabling the
            self.cfg_reg[9] = 0x03 + rssi_temp
            self.cfg_reg[10] = h_crypt
            self.cfg_reg[11] = l_crypt
        self.ser.flushInput()
        for i in range(2):
            self.ser.write(bytes(self.cfg_reg))
            r_buff = 0
            time.sleep(0.2)
            if self.ser.inWaiting() > 0:
                time.sleep(0.1)
                r_buff = self.ser.read(self.ser.inWaiting())
                if r_buff[0] == 0xC1:
                    pass
                    # print("parameters setting is :", end='')
                    # for i in self.cfg_reg:
                        # print(hex(i), end=' ')
                    # print('\r\n')
                    # print("parameters return is  :", end='')
                    # for i in r_buff:
                        # print(hex(i), end=' ')
                    # print('\r\n')
                else:
                    pass
                    #print("parameters setting fail :", r_buff)
                break
            else:
                print("setting fail, setting again")
                self.ser.flushInput()
                time.sleep(0.2)
                print('\x1b[1A', end='\r')
                if i == 1:
                    print("setting fail, Press Esc to Exit and run again")
                    # time.sleep(2)
                    # print('\x1b[1A', end='\r')
        GPIO.output(self.M0, GPIO.LOW)
        GPIO.output(self.M1, GPIO.LOW)
        time.sleep(0.1)

    def get_settings(self):
        # the pin M1 of lora HAT must be high when entering setting mode and getting parameters
        GPIO.output(M1, GPIO.HIGH)
        time.sleep(0.1)
        # send command to get setting parameters
        self.ser.write(bytes([0xC1, 0x00, 0x09]))
        if self.ser.inWaiting() > 0:
            time.sleep(0.1)
            self.get_reg = self.ser.read(self.ser.inWaiting())
        # check the return characters from hat and print the setting parameters
        if self.get_reg[0] == 0xC1 and self.get_reg[2] == 0x09:
            fre_temp = self.get_reg[8]
            addr_temp = self.get_reg[3] + self.get_reg[4]
            air_speed_temp = self.get_reg[6] & 0x03
            power_temp = self.get_reg[7] & 0x03
            print("Frequence is {0}.125MHz.", fre_temp)
            print("Node address is {0}.", addr_temp)
            print("Air speed is {0} bps"+ lora_air_speed_dic.get(None, air_speed_temp))
            print("Power is {0} dBm" + lora_power_dic.get(None, power_temp))
            GPIO.output(M1, GPIO.LOW)
# the data format is as follows
# "node address, frequency, payload"
# "20, 868, Hello World"

    def send(self, data):
        GPIO.output(self.M1, GPIO.LOW)
        GPIO.output(self.M0, GPIO.LOW)
        time.sleep(0.1)
        self.ser.write(data)
        # if self.rssi == True:
            # self.get_channel_rssi()
        time.sleep(0.1)

    def receive(self):
        if self.ser.inWaiting() > 0:
            time.sleep(0.5)
            r_buff = self.ser.read(self.ser.inWaiting())
            print("receive message from node address with frequence\033[1;32m %d, %d.125MHz\033[0m"%((r_buff[0]<<8)+r_buff[1], r_buff[2]+self.start_freq), end='\r\n', flush = True)
            print("message is "+str(r_buff[3:-1]), end='\r\n')
            # print the rssi
            if self.rssi:
                # print('\x1b[3A', end='\r')
                print("the packet rssi value: -{0}dBm".format(256-r_buff[-1:][0]))
                self.get_channel_rssi()
            else:
                pass
                #print('\x1b[2A', end='\r')

    def get_channel_rssi(self):
        GPIO.output(self.M1, GPIO.LOW)
        GPIO.output(self.M0, GPIO.LOW)
        time.sleep(0.1)
        self.ser.flushInput()
        self.ser.write(bytes([0xC0, 0xC1, 0xC2, 0xC3, 0x00, 0x02]))
        time.sleep(0.5)
        re_temp = bytes(5)
        if self.ser.inWaiting() > 0:
            time.sleep(0.1)
            re_temp = self.ser.read(self.ser.inWaiting())
        if re_temp[0] == 0xC1 and re_temp[1] == 0x00 and re_temp[2] == 0x02:
            print("the current noise rssi value: -{0}dBm".format(256-re_temp[3]))
            # print("the last receive packet rssi value: -{0}dBm".format(256-re_temp[4]))
        else:
            # pass
            print("receive rssi value fail")
            # print("receive rssi value fail: ", re_temp)

我想这两个设备应该能够通信,因为最终它们是相同的。有人知道为什么接收器 HAT 没有收到来自 ESP32 LoRa 发送器的任何消息吗?

raspberry-pi iot esp32 lora
1个回答
0
投票

我想这两个设备应该能够通信,因为最终它们是相同的。

但这就是问题所在。虽然它们的核心是相同的(两个 SX1262),但它们根本不同。其中一个是 ebyte 垃圾,是一个托管 LoRa 模块,您可以通过 UART 访问它,并且几乎无法控制。另一种是“真正的”SX1262,您可以通过 SPI 自行管理和控制。

您应该注意到的一件事是两者之间的设置非常不同。亿佰特与普通SX1262模块的主要区别是:

  • “空速”设置,这不是 LoRa 设置。
  • 事实上,您无法使用 ebyte 设置 SF 值。
  • ebyte中的
    addr
    地址设置?那是什么?
  • 频率是以 ebyte 为单位的 MHz 的整数倍。无法将其设置为 868.125。
  • ebyte 只有 3 个 BW 值,而不是 10 个。

我认为相关的前两点使得 ebyte 模块几乎不可能与普通 LoRa 模块一起工作。他们的固件似乎从“空气速度”的东西中得出了 SF 值。我无法将这些空速与 BW / SF / CR 值相匹配。例如,查看LoRa计算器,非常常见的SF 10、BW 7、CR 4/5设置为您提供每秒977波特的数据速率。无法将这些设置扭曲到接近 2,400。

我在某处读到一个人设法使 ebyte 与 SX1276 进行通信。不记得在哪里或如何,但听起来很复杂。你最好的猜测是要么留在 ebyte 生态系统中(无论如何这都是垃圾),要么使用像样的产品,无论是 SPI 还是 UART 管理的产品。那里有很多,我最喜欢的是 RAKwireless(为了质量)和 Heltec(为了更便宜的东西)。

© www.soinside.com 2019 - 2024. All rights reserved.