jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.47k stars 369 forks source link

AX.25 Reception does not work properly #1162

Closed ReacherMiao closed 1 month ago

ReacherMiao commented 1 month ago

Hi, I would like to ask for help for one of our project.

We are trying to write a decoder for ax.25 frames on our SX1268 chip. We have tried a lot of things, but the reception still does not work properly.

There are mainly two functions for reception from the radiolib, from what we read: receive() and receiveDirect(). But it seems that receiveDirect() was not implemented for SX1268. After successful initialization, we were unable to capture anything meaningful using either of these two functions. Most of the things we printed out did not make any sense.

Here is the function we wrote for receive. It would be very great if it was just that we made some mistakes.

void ax25_reception() {
  size_t len = 255;
  byte data[255];
  byte flag = 0x7E;
  // Check for flag byte first
  byte receivedByte;
  int state = radio.receive(&receivedByte, 1);
  if (state == RADIOLIB_ERR_NONE && receivedByte == flag) {

    // Flag detected, start receiving the packet
    Serial.println(F("Flag detected, receiving packet..."));
    state = radio.receive(data, len);
    if (state == RADIOLIB_ERR_NONE) {
      Serial.println(F("Received packet!"));

      // Print data as hex string
      Serial.print(F("HEX Data:\t"));
      for (unsigned int i = 0; i < len; i++) {
        Serial.print(data[i], HEX);
        Serial.print(' ');
      }
      Serial.println();

And this is our initialization:


void ax25_init(float freq, float br, float freqDev, float rxBw) {

  AX25Client ax25(&radio);
  Serial.begin(1200);

  Serial.print(F("[SX1268] Initializing ... "));
  // carrier frequency:           434.0 MHz
  // bit rate:                    1.2 kbps (1200 baud 2-FSK AX.25)
  int state = radio.beginFSK(freq, br, freqDev, rxBw);

  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }

 // initialize AX.25 client

  Serial.print(F("[AX.25] Initializing ... "));

  // source station callsign:     "N7LEM"
  // source station SSID:         0
  // preamble length:             8 bytes

  state = ax25.begin("N7LEM");
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }
  }
}

As of setup we are using 9600 Baude rate and (434.0, 4.8, 5.0, 156.2) for input of beginFSK()

// SX1268 has the following connections:
// NSS pin:   10
// DIO0 pin:  5
// RESET pin: 6
// DIO1 pin:  1
SX1268 radio = new Module(10, 5, 6, 1);
AX25Client ax25(&radio);

Thanks in advance!

jgromes commented 1 month ago

First of all, receiving AFSK-modulated AX.25 frames is not possible, see #569. From the code you have shown, you are not using AFSK, but I just wanted to get this limitation out of the way. More generically, receiving AX.25 is not tested. It can be possible in some cases, but most likely not with SX126x.

The primary issue you have is that the SX126x (as well as all the other sub-GHz FSK modules) packets follow the common preamble-syncword-length-payload format. AX.25 does not, it has a specific frame structure made of flags that denote packet start/end and the length is implicit. So you will have to disable the SX126x internal FSK packet engine and do all the decoding yourself. And here you will hit the final problem - to do this, you would need to use the receiveDirect API. In this mode, the radio outputs demodulated data directly on one of its pins, which allows you to bypass the packet engine (see the SX127x example for that) As you have observed, it is not implemented on SX126x. There are a few reason for that, the two biggest ones are:

  1. It is not very well documented how to achieve this mode of operation on SX126x; there is an application note that shows something similar, but I was not able to get it working in my experiments so far.
  2. It requires DIO3 pin of the SX126x to be free, and most devices use it for TCXO reference voltage. Coincidentally, I have recently gotten a couple of SX1262 modules that seem to have DIO3 free, so I might revisit this, but it's not a high priority for me at the moment.

TL;DR Currently this is not possible using SX126x. Your best shot is using SX127x, but even then, this is not something that's directly supported - that's why there is no example for it.

jgromes commented 1 month ago

Closed due to inactivity.