[go: nahoru, domu]

Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SX1262 + RaspberryPi 5 Not Receiving #1200

Closed
limccart7 opened this issue Aug 30, 2024 · 14 comments
Closed

SX1262 + RaspberryPi 5 Not Receiving #1200

limccart7 opened this issue Aug 30, 2024 · 14 comments

Comments

@limccart7
Copy link
limccart7 commented Aug 30, 2024

Hardware:

  • Raspberry Pi 5 - Raspbian OS (Most up to date version)
  • SX1262 - MBED Shield

Other notes:

  • We used wiringPi instead of lgpio. I attempted to use both, but wiringPi with this pinout is the only way I have been able to run the code and not get an error message.
  • Had to set SX126x::XTAL = true. If we did not, or didn't use 0.0 for txcoVoltage we would get a -707 error.

This is not a new issue, but it's also really weird that we were receiving, albeit poorly, with LoRa using these settings, pinout, and drivers. It also was working better in FSK mode, but now receiving is broken for that as well. The interrupt seems to never fire, but it did at one point so I'm fairly confident I'm not setting up the interrupt function incorrectly. I really wish I could provide more information or context as to why it stopped working, but I have basically none and can't even get back to it "working sometimes" to troubleshoot. On the other hand, the Transmitter counterpart to this code is having no problems starting or transmitting! It's only receive.

I'll leave the code here in case it's helpful. When we run this, even with different settings or using beginFSK() instead, it still never fires. This could likely be an issue with using the RaspberryPi, our PiHal.h seems to be working fine but I can include that as well. I enabled the debug messages as well, and I don't 100% know what I'm looking at but the SPI transactions seem to be fine, but again I can provide that if it is at all helpful. I'm also a student learning this for a class essentially, so forgive me if I make silly mistakes in my code or understanding.

main.cpp

#include <RadioLib.h>
#include <unistd.h>     // For usleep
#include <iostream>     // For std::cout
#include <vector>       // For std::vector
#include <algorithm>    //std::find
#include "PiHal.h"
PiHal* hal = new PiHal(0);

// Create the radio module instance
// NSS pin: WiringPi 10 (GPIO 8)
// DIO1 pin: WiringPi 2 (GPIO 27)
// NRST pin: WiringPi 21 (GPIO 5)
// BUSY pin: WiringPi 0 (GPIO 17)
SX1262 radio = new Module(hal, 10, 2, 21, 0);

volatile bool receivedFlag = false;

// Function to be called when a packet is received
void setFlag() {
    receivedFlag = true;
    std::cout << "we received" << std::endl;
}

int main(int argc, char** argv) {
    // Initialize radio
    std::cout << "[SX1262] Initializing ... ";
    int state = radio.begin(915.0, 250.0, 12, 5, 0x34, 10, 8, 1.6, true);
    if (state != RADIOLIB_ERR_NONE) {
        std::cout << "failed, code " << state << std::endl;
        return 1;
    }
    std::cout << "success!" << std::endl;

    // Set the function that will be called when a new packet is received
    radio.setPacketReceivedAction(setFlag);

    //try to rx now..?
    std::cout << "[SX1262] Starting to listen ... ";
    state = radio.startReceive();
    if (state != RADIOLIB_ERR_NONE) {
        std::cout << "failed, code " << state << std::endl;
        return 1;
    }
    std::cout << "success!" << std::endl;

    while (true) {
        if (receivedFlag) {
            // Reset flag
            receivedFlag = false;

            size_t maxLength = 256;
            std::vector<uint8_t> byteArr(maxLength);

            // Read the received data
            state = radio.readData(byteArr.data(), maxLength);

            if (state == RADIOLIB_ERR_NONE) {
                //determine actual packet length
                size_t numBytes = std::find(byteArr.begin(), byteArr.end(), static_cast<unsigned char>('\0')) - byteArr.begin();
                
                //serial print packet
                std::cout << "[SX1262] Received packet!" << std::endl;
                std::cout << "[SX1262] Data:\t\t";
                
                // try to convert might break ...?
                std::string receivedData(byteArr.begin(), byteArr.begin() + numBytes);
                std::cout << receivedData << std::endl;

                // Print RSSI (Received Signal Strength Indicator)
                std::cout << "[SX1262] RSSI:\t\t" << radio.getRSSI() << " dBm" << std::endl;

                // Print SNR (Signal-to-Noise Ratio)
                std::cout << "[SX1262] SNR:\t\t" << radio.getSNR() << " dB" << std::endl;

                // Print frequency error
                std::cout << "[SX1262] Frequency error:\t" << radio.getFrequencyError() << " Hz" << std::endl;

            } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
                // Packet was received, but is malformed
                std::cout << "CRC error!" << std::endl;

            } else {
                // Some other error occurred
                std::cout << "failed, code " << state << std::endl;
            }
        }
    //could use delay?
    }

    return 0;
}
@jgromes
Copy link
Owner
jgromes commented Aug 30, 2024

SX1262 - MBED Shield

I do wonder about the reliability of the connection you have between the RPi and an Arduino shield. A loose wire could easily explain this behavior.

Had to set SX126x::XTAL = true

That can be expected, considering the shield does have an XTAL instead of the more common TCXO, it is specified on the website you have linked to. However, your code does not show this ...?

I really wish I could provide more information or context as to why it stopped working

You can - start by following the issue template. One of the things it calls for is to specify the library version you are using, which for me is a critical piece of information. Next up, post the output. You have some prints in the program, do they show up? Even just seeing a successful startup is very important to me. Without it I have no idea whether the program crashes at some point or continues running, waiting for the interrupt.

Most importantly: what is your transmitter? Does its configuration match the receiver? And can you independently verify something is actually being sent? You seem to be using LoRaWAN sync word, which really shouldn't be used for peer-to-peer traffic, assuming that is what you're trying to do.

Also, regarding your code: you can use getPacketLength to get ... well, the packet length, instead of trying to figure it out from the NULL terminator position.

@limccart7
Copy link
Author
limccart7 commented Aug 31, 2024

I apologize for not using the issue template or providing the necessary information. I believe this would be a module not working issue, so I will follow that template.

Sketch that is causing the module fail
rx.cpp - I made a few changes. I was changing XTAL=true in the SX126x.cpp file (terrible practice I know), but changed it to just set txcoVoltage=0 and that was working as well until today. Now with the exact same code and pinout, I'm getting -707.

rx.cpp

#include <RadioLib.h>
#include <iostream>     // For std::cout
#include <vector>       // For std::vector
#include "PiHal.h"
PiHal* hal = new PiHal(0);

// Create the radio module instance
// NSS pin: WiringPi 10 (GPIO 8)
// DIO1 pin: WiringPi 2 (GPIO 27)
// NRST pin: WiringPi 21 (GPIO 5)
// BUSY pin: WiringPi 0 (GPIO 17)
SX1262 radio = new Module(hal, 10, 2, 21, 0);

volatile bool receivedFlag = false;

//IRQ
void setFlag() {
    receivedFlag = true;
    std::cout << "we received" << std::endl;
}

int main(int argc, char** argv) {
    std::cout << "[SX1262] Initializing ... ";
    //int state = radio.begin(915.0, 250.0, 12, 5, 0x12, 10, 8, 0.0, true);
    int state = radio.beginFSK(915.0, 4.8, 125.0, 467.0, 20.0, 16.0, 0.0, false);
    if (state != RADIOLIB_ERR_NONE) {
        std::cout << "failed, code " << state << std::endl;
        return 1;
    }
    std::cout << "success!" << std::endl;
    radio.setPacketReceivedAction(setFlag);

    //try to rx now..?
    std::cout << "[SX1262] Starting to listen ... ";
    state = radio.startReceive();
    if (state != RADIOLIB_ERR_NONE) {
        std::cout << "failed, code " << state << std::endl;
        return 1;
    }
    std::cout << "success!" << std::endl;

    while (true) {
        if (receivedFlag) {
            //toggle flag
            receivedFlag = false;

            size_t maxLength = 256;
            std::vector<uint8_t> byteArr(maxLength);

            //put data in array
            state = radio.readData(byteArr.data(), maxLength);

            if (state == RADIOLIB_ERR_NONE) {
                //determine actual packet length
                size_t numBytes = radio.getPacketLength();
                
                //serial print packet
                std::cout << "[SX1262] Received packet!" << std::endl;
                std::cout << "[SX1262] Data:\t\t";
                

            } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
                std::cout << "CRC error!" << std::endl;

            } else {
                std::cout << "failed, code " << state << std::endl;
            }
        }
    //could use delay?
    //hal->delay(100);
    }

    return 0;
}

tx.cp

#include <RadioLib.h>
#include "PiHal.h"
#include <chrono> // For timestamping

// Create a new instance of the HAL class
PiHal* hal = new PiHal(0);

// Create the radio module instance
// Pinout corresponds to your SX1262 setup
// NSS pin: WiringPi 10 (GPIO 8)
// DIO1 pin: WiringPi 2 (GPIO 27)
// NRST pin: WiringPi 21 (GPIO 5)
// BUSY pin: WiringPi 0 (GPIO 17)
SX1262 radio = new Module(hal, 10, 2, 21, 0);

int main() {
    printf("[SX1262] Initializing ... ");
    //int state = radio.beginFSK(915.0, 4.8, 125.0, 467.0, 20.0, 16.0, 0.0, false);
    int state = radio.begin(915.0, 250.0, 12, 5, 0x12, 10, 8, 0.0, true);
    if (state != RADIOLIB_ERR_NONE) {
        printf("Initialization failed, code %d\n", state);
        return 1;
    }
    printf("Initialization success!\n");

    int count = 0;

    while (true) {
        //getcurrent time 
        auto now = std::chrono::high_resolution_clock::now();
        auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();

        //print the timestamp and packet number
        printf("[SX1262] Transmitting packet #%d at time %lld ms ... ", count, timestamp);

        //create a packet with the timestamp and message
        char str[64];
        sprintf(str, "Timestamp: %lld, Hello World! #%d", timestamp, count++);

        //send the packet
        state = radio.transmit(str);
        if (state == RADIOLIB_ERR_NONE) {
            printf("success!\n");

            //print the effective data rate for the transmitted packet
            float effectiveDataRate = radio.getDataRate();
            printf("Effective Data Rate: %.2f bps\n", effectiveDataRate);
        } else {
            printf("failed, code %d\n", state);
        }

        //don't want to overwhelm receiver
        hal->delay(1000);
    }

    return 0;
}

Also, I have an update regarding the behavior with FSK. I spoke with my partner who has handled the FSK and his receiver IS working for FSK on his machine, but not (any of) mine. As you can see, I was trying to swap between FSK and LoRa to see if either would work. The transmitter code is taken directly from him.

We were able to verify transmitting LoRa packets using a handheld Spectrum Analyzer and/or a Software Defined Radio. We were able to detect and read packets from the 1262 a few weeks ago.

Hardware setup
I can provide pictures if need be, but I want to use this section to address some things you brought up.

SX1262 - MBED Shield

I do wonder about the reliability of the connection you have between the RPi and an Arduino shield. A loose wire could easily explain this behavior.

I completely agree with this, and wish I could've chosen the hardware myself since both the Pi and Hat layout are not ideal. That being said we've double and even triple checked this with logic analyzers and replacing any wire that feels even the slightest bit loose. Between my partner and I, we have 4+ of these setups that we've been testing on which gives us a little bit of a sanity check when all 4 are not functioning for one thing. He is having the same problem with LoRa as I am, but is able to transmit and receive FSK. I also was able to transmit LoRa which leads me to believe that at least some of the pins are working. We at first believed it was an issue with our DIO1 or BUSY Pins, but DIO1 still goes high when receiving on FSK. A final note, my partner bought a different 1262 hat specifically for the RPi pinout, so there were no jumper wires, and it still was not receiving LoRa.

Debug mode output

[SX1262] Initializing ... RLB_DBG: 
RadioLib Info
Version:  "6.6.0.0"
Platform: "Generic"
Compiled: "Aug 30 2024" "17:02:09"
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	0	0	
RLB_DBG: -2 at /home/limccart/SX12XX_Project/lora_src/RadioLib/src/Module.cpp:277
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	1D	3	20	
RLB_SPI: SI				0	0	0	0	0	00	0	0	0	0	0	0	0	0	0	0
RLB_SPI: SO	A2	A2	A2	A2	53	58	31	32	36	31	20	56	32	44	20	32	44	30	32	0	
RLB_DBG: Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
RLB_DBG: 00000320: 53 58 31 32 36 31 20 56 32 44 20 32 44 30 32 00  SX1261 V2D 2D02.
RLB_DBG: 
RLB_DBG: M	SX126x
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	FF	FF	
RLB_DBG: -2 at /home/limccart/SX12XX_Project/lora_src/RadioLib/src/Module.cpp:277
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8A	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	93	
RLB_SPI: SI		20	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	88	
RLB_SPI: SI		3	16	A	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8	
RLB_SPI: SI		0	0	0	0	0	0	0	0
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	89	
RLB_SPI: SI		7F	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		9	6	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	D	7	40	
RLB_SPI: SI				14	24	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	96	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	9D	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		C	6	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		C	5	1	1	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	98	
RLB_SPI: SI		E1	E9	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	86	
RLB_SPI: SI		39	30	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	D8	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	C8	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	8	D8	
RLB_SPI: SI				DE	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	E7	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	18	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	95	
RLB_SPI: SI		4	7	0	1	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8E	
RLB_SPI: SI		A	4	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
success!
[SX1262] Starting to listen ... RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	A2	A2	A2	A2	
success!

Notes: I know it's unhelpful to hear, but I swear I was not getting "-2" when I was running this same code yesterday. I do think this is a SPI issue (as per your Troubleshooting Guide), but I was hoping you could help me understand what's happening better. To further my point, I know you couldn't see what the receiver was printing yesterday, but it would print

[SX1262] Initializing ... success!
[SX1262] Starting to listen ... success!

Now it prints:

[SX1262] Initializing ... success!
[SX1262] Starting to listen ... failed, code -707

No change to any code. Just a different day and a restart of my Pi. I know this probably leads you to believe it's a wiring issue, but I triple checked that nothing got loose, and it's the exact same as yesterday.

Additional info (please complete):

  • MCU: Raspberry Pi 5
  • Wireless module type: SX1262
  • Arduino IDE version: N/A, compiled on machine
  • Library version: 6.6.0.0

@jgromes
Copy link
Owner
jgromes commented Aug 31, 2024

Thank you for the additional information, I have a couple of observations:

I made a few changes. I was changing XTAL=true in the SX126x.cpp file (terrible practice I know)

Terrible indeed - but why change it in the library source? SX126x::XTAL is a public member variable, you can set it from your main file, that's why it is public.

Now with the exact same code and pinout, I'm getting -707

How are you compiling the library and your main files? If you are installing the library on your machine, you will have to recompile it each time you change it. So if you did some changes to the library source, you will have to reinstall the library, otherwise you are still using the unchanged version.

Seeing as you have shown two .cpp files, I'm guessing you have two Raspberry Pi computers, one running rx, the other running tx, correct?

A final note, my partner bought a different 1262 hat specifically for the RPi pinout, so there were no jumper wires, and it still was not receiving LoRa.

It's always possible some bug got introduced recently. Are you using the 6.6.0.0 update, or the latest master? And did you update the library since it worked last?

I was not getting "-2" when I was running this same code yesterday

The -2 in the log is from an assertion - during initialization, the module returns 0xFF which gets evaluated as a faulty SPI. It is strange this appears after the SPI was working, as the library can read the SX126x version. It seems like this did not cause any further issue, and the SPI appears to be working afterwards, but it is strange nonetheless. Are there any other programs running on the RPi that could be using the SPI?

@K4KDR
Copy link
K4KDR commented Aug 31, 2024

Please forgive me if this is unrelated to the issue here, but I have numerous Pi-Pico boards working great w/ both straight LoRa as well as for LoRaWAN comms, so I wanted to reply here in case my setup is of any assistance.

My LoRa add-on for the Pico is:

https://www.waveshare.com/pico-lora-sx1262-868m.htm

pico-lora-hat

... and after a great deal of help here from the RadioLib folks, found that the following sequence worked flawlessly for me.

Prior to any int state = radio.begin(); statements, you need:

SX1262 radio = new Module(3, 20, 15, 2, SPI1, RADIOLIB_DEFAULT_SPI_SETTINGS);

... and then:

  SPI1.setSCK(10);            // fix from https://github.com/jgromes/RadioLib/issues/729
  SPI1.setTX(11);             // ~
  SPI1.setRX(12);             // ~
  pinMode(3, OUTPUT);         // ~
  digitalWrite(3, HIGH);      // ~
  SPI1.begin(false);          // fix from https://github.com/jgromes/RadioLib/issues/729

... and to make sure I'm not leaving out anything critical, regarding the conventional LoRa parameters (freq, BW, SF, etc.), when using LoRaWAN that will be handled by the option you have selected in:

const LoRaWANBand_t Region =

... and when using this hardware for 'plain' LoRa comms, those parameters are set directly in your code w/ something like:

// modem configuration
#define FREQUENCY             433.000   // 
#define BANDWIDTH             125.0    // Sets LoRa bandwidth. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz.
#define SPREADING_FACTOR      7      // Sets LoRa spreading factor. Allowed values range from 5 to 12.
#define CODING_RATE           5      // Sets LoRa coding rate 4/x denominator. Allowed x values range from 5 to 8.
#define CURRENT_LIMIT         140     // mA
#define OUTPUT_POWER          22      // dBm
#define LORA_PREAMBLE_LEN     8       // preambleLength LoRa preamble length in symbols. Allowed values range from 1 to 65535.
#define SYNC_WORD             0x12       // public default=0x12,  LoRaWAN default=0x34
#define LDRO                  false   // normally 'true' for SF-11 or 12
#define CRC                   true    
#define IQINVERTED            false
#define DATA_SHAPING          RADIOLIB_SHAPING_1_0     // Data shaping = 1.0
#define TCXO_VOLTAGE          1.7     // volts
#define WHITENING_INITIAL     0x00FF   // initial whitening LFSR value

... followed by the actual command:

  int state = radio.begin(FREQUENCY,
                          BANDWIDTH,
                          SPREADING_FACTOR,
                          CODING_RATE,
                          SYNC_WORD,
                          OUTPUT_POWER,
                          LORA_PREAMBLE_LEN,
                          TCXO_VOLTAGE);
  radio.setCurrentLimit(CURRENT_LIMIT);
  radio.forceLDRO(LDRO);
  radio.setCRC(CRC);
  radio.invertIQ(IQINVERTED);
  radio.setWhitening(true, WHITENING_INITIAL);
  radio.explicitHeader();

... since this configuration works SO extremely well for me w/ the Pi-Pico & the LoRa hat mentioned above, I just wanted to share in case it helps!

@K4KDR
Copy link
K4KDR commented Aug 31, 2024

... just realized that this issue is discussing the Pi-5, not the Pico. Perhaps I am mixing multiple issues that I've seen posted.

Regardless, I am still using an sx1262 device, perhaps this is some help. Or, if someone determines that this is helpful to another issue #, please feel free to move it.

@BenDuval
Copy link

Hello. I am the partner of the OP. I wanted to chime and and answer some of those questions you proposed.

How are you compiling the library and your main files? If you are installing the library on your machine, you will have to recompile it each time you change it. So if you did some changes to the library source, you will have to reinstall the library, otherwise you are still using the unchanged version.

  • So we are compiling using the make file. To recap, how we got started was we cloned into RadioLib, went into the NonAurdrino/Raspberry directory and edited the PiHal.h to work with wiring Pi, We did properly link wiring Pi in the cmake, along with our executables. We do re make the file after any changes.

Seeing as you have shown two .cpp files, I'm guessing you have two Raspberry Pi computers, one running rx, the other running tx, correct?

  • Yes, we have tx on one RPI and rx on another RPI. (We have already tried this on multiple different Pi's, I myself have 3 Pi's and the lora receive wont work for any of them, it was a few weeks ago)

It's always possible some bug got introduced recently. Are you using the 6.6.0.0 update, or the latest master? And did you update the library since it worked last?

Yeah as my partner said, i bought a wave share LORAWAN SX1262 Pi Hat to see if maybe that would work for receiving Lora, and it does not. I believe we are using the latest master, and no I believe neither of us have pulled any further updates since our original pull from github.

The -2 in the log is from an assertion - during initialization, the module returns 0xFF which gets evaluated as a faulty SPI. It is strange this appears after the SPI was working, as the library can read the SX126x version. It seems like this did not cause any further issue, and the SPI appears to be working afterwards, but it is strange nonetheless. Are there any other programs running on the RPi that could be using the SPI?

  • No there shouldn't be any other programs using SPI. We have no other SPI peripherals connected.

To update from my side of things. I am able to transmit and receive FSK. No issues really. I am able to change parameters, see the data rates change and all. I wanted to share a few pictures I captured.

FSK_debug

This is the output i get on the RX side of things when using the FSK modem.

LORA_debug

And this is the output I get when i comment out the begin.fsk and include the begin function for Lora. (on each pi)

We appreciate your time.

@jgromes
Copy link
Owner
jgromes commented Sep 1, 2024

I believe we are using the latest master, and no I believe neither of us have pulled any further updates since our original pull from github.

I believe in a few things, but repository revisions are not one of them. git describe --always will let us know for sure, run it on both machines in the cloned repository and post the output.

this is the output I get when i comment out the begin.fsk and include the begin function for Lora

I can see it prints out "Received:" - that is not part of the code that is posted above, so I'm very confused as to what exactly are you running, but I'm guessing that this means the interrupt does arrive. The debug output shows command 0x13 returns 0 0 - that means there are no data in the Rx buffer for LoRa. So I suspect a misconfiguration. I also need to repeat my question as to the fact you seem to be using a LoRaWAN-reserved sync word - why?

To make sure no bug was introduced recently, I ran this on my RPi 3B+ with the following result (transmitter is an ESP32 with SX1278):

pi@raspberrypi:~/repos/sketches/SX126x_Receive $ ./build/rlb 
[SX1261] Initializing ... success!
[SX1261] Starting to listen ... success!
Data: Hello World! #69
Data: Hello World! #70
Data: Hello World! #71
Data: Hello World! #72
Data: Hello World! #73
Data: Hello World! #74
^C

Library version:

pi@raspberrypi:~/repos/RadioLib $ git describe --always
d3f9eaf3
Pi Code

#include <RadioLib.h>
#include "../hal/lgpio.h"

PiHal* hal = new PiHal(0);
SX1262 radio = new Module(hal, 21, 16, 18, 20);
PhysicalLayer* phy = (PhysicalLayer*)&radio;

volatile bool receivedFlag = false;
void setFlag(void) {
  receivedFlag = true;
}

// the entry point for the program
int main(int argc, char** argv) {
  radio.XTAL = true;

  // initialize just like with Arduino
  printf("[SX1261] Initializing ... ");
  int state = radio.begin();
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  radio.setPacketReceivedAction(setFlag);

  printf("[SX1261] Starting to listen ... ");
  state = radio.startReceive();
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  // loop forever
  int count = 0;
  uint8_t buff[256] = { 0 };
  for(;;) {
    if(receivedFlag) {
      // reset flag
      receivedFlag = false;
      size_t len = radio.getPacketLength();

      int state = radio.readData(buff, len);
      if (state != RADIOLIB_ERR_NONE) {
        printf("Read failed, code %d\n", state);
      } else {
        printf("Data: %s\n", (char*)buff);
      }
    }
  }

  return(0);
}

@HeadBoffin
Copy link
Collaborator

I wanted to share a few pictures I captured.

Capturing as text would allow someone to potentially parse / interpret them - as pictures not so much.

@BenDuval
Copy link
BenDuval commented Sep 1, 2024

I believe in a few things, but repository revisions are not one of them. git describe --always will let us know for sure, run it on both machines in the cloned repository and post the output.
(Transmitter Pi)

  • sdr@PIZero2W:~/RadioLib $ git describe --always
  • 0798743

(Receiver Pi)

  • sdr@PI4:~/SX12XX_Project/src/RadioLib $ git describe --always
  • b9dd294

I can see it prints out "Received:" - that is not part of the code that is posted above, so I'm very confused as to what exactly are you running, but I'm guessing that this means the interrupt does arrive. The debug output shows command 0x13 returns 0 0 - that means there are no data in the Rx buffer for LoRa. So I suspect a misconfiguration. I also need to repeat my question as to the fact you seem to be using a LoRaWAN-reserved sync word - why?

  • Yeah, my partners code may slightly differ. We went through lots of changes trying to figure out what went wrong. I will attach my tx and rx code.
TX (hardware Pi Zero 2W, Semtech SX1262 MBED Shield)

#include <RadioLib.h>
#include "PiHal.h"
#include <chrono> // For timestamping

// Create a new instance of the HAL class
PiHal* hal = new PiHal(0);

// Create the radio module instance
// Pinout corresponds to your SX1262 setup
// NSS pin: WiringPi 10 (GPIO 8)
// DIO1 pin: WiringPi 2 (GPIO 27)
// NRST pin: WiringPi 21 (GPIO 5)
// BUSY pin: WiringPi 0 (GPIO 17)
SX1262 radio = new Module(hal, 10, 2, 21, 0);

int main() {
    // Initialize the radio module
    printf("[SX1262] Initializing ... ");
    //int state = radio.beginFSK(915.0, 4.8, 125.0, 467.0, 20.0, 16.0, 0.0, false);
      int state = radio.begin(915.0, 125.0, 7, 5, 10, 8, 0.0, false);
    if (state != RADIOLIB_ERR_NONE) {
        printf("Initialization failed, code %d\n", state);
        return 1;
    }
    printf("Initialization success!\n");

    int count = 0;

    while (true) {
        // Get the current time 
        auto now = std::chrono::high_resolution_clock::now();
        auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();

        // Print the timestamp and packet number
        printf("[SX1262] Transmitting packet #%d at time %lld ms ... ", count, timestamp);

        // Create a packet with the timestamp and message
        char str[64];
        sprintf(str, "Timestamp: %lld, Hello World! #%d", timestamp, count++);

        // Send the packet
        state = radio.transmit(str);
        if (state == RADIOLIB_ERR_NONE) {
            printf("success!\n");

            // Get and print the effective data rate for the transmitted packet
            float effectiveDataRate = radio.getDataRate();
            printf("Effective Data Rate: %.2f bps\n", effectiveDataRate);
        } else {
            printf("failed, code %d\n", state);
        }

        // Wait for a second before transmitting again
        hal->delay(1000);
    }

    return 0;
}

RX (hardware Pi 4, Semtech SX1262 MBED Shield)

#include <iostream>
#include <RadioLib.h>
#include "PiHal.h"
#include <cstdio>

// Create a new instance of the HAL class
PiHal* hal = new PiHal(0);

// Create the radio module instance
Module* module = new Module(hal, 10, 2, 21, 0);
SX1262 radio(module);

// Flag to indicate a packet was received
volatile bool receivedFlag = false;

// ISR function to set the received flag
void setFlag(void) {
  receivedFlag = true;
}

int main(int argc, char** argv) {
  freopen("debug.txt", "w", stdout);
  hal->init();

  int16_t resetState = radio.reset();
  if (resetState != RADIOLIB_ERR_NONE) {
    printf("Reset failed, code %d\n", resetState);
    return 1;
  }

  radio.XTAL = true;

  // Initialize the radio module
  printf("[SX1262] Initializing ... ");
// int state = radio.beginFSK(915.0, 4.8, 125.0, 467.0, 20.0, 16.0, 0.0, false); // FSK mode
  int state = radio.begin(915.0, 125.0, 7, 5, 10, 8, 0.0, false); // LoRa mode
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  // Set the ISR for packet received
  radio.setPacketReceivedAction(setFlag);

  // Start receiving packets
  printf("[SX1262] Starting to listen ... ");
  state = radio.startReceive();
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  // Main loop
  uint8_t buff[256] = { 0 };
  for(;;) {
    if(receivedFlag) {
      // Reset flag
      receivedFlag = false;
      
      // Get the length of the received packet
      size_t len = radio.getPacketLength();
      
      // Read the received packet
      int state = radio.readData(buff, len);
      if (state != RADIOLIB_ERR_NONE) {
        printf("Read failed, code %d\n", state);
      } else {
        printf("Data: %s\n", (char*)buff);
      }

      // Restart the receiver
      state = radio.startReceive();
      if (state != RADIOLIB_ERR_NONE) {
        printf("Restart receive failed, code %d\n", state);
        return 1;
      }
    }
  }

  return(0);
}

Debug Output for RX (Lora Modem)

RLB_SPI: CMDW	
RLB_SPI: SI	0	
RLB_SPI: SO	A2	
[SX1262] Initializing ... RLB_DBG: 
RadioLib Info
Version:  "6.6.0.0"
Platform: "Generic"
Compiled: "Sep  1 2024" "08:47:55"
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	1D	3	20	
RLB_SPI: SI				0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	53	58	31	32	36	31	20	56	32	44	20	32	44	30	32	0	
RLB_DBG: Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
RLB_DBG: 00000320: 53 58 31 32 36 31 20 56 32 44 20 32 44 30 32 00  SX1261 V2D 2D02.
RLB_DBG: 
RLB_DBG: M	SX126x
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8A	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	93	
RLB_SPI: SI		20	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	88	
RLB_SPI: SI		3	16	A	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8	
RLB_SPI: SI		0	0	0	0	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	89	
RLB_SPI: SI		7F	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		9	6	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	D	7	40	
RLB_SPI: SI				4	A4	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	0	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	96	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	9D	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	0	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	0	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		7	6	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		7	4	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	98	
RLB_SPI: SI		E1	E9	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	86	
RLB_SPI: SI		39	30	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	D8	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	C8	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	8	D8	
RLB_SPI: SI				DE	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	E7	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	18	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	95	
RLB_SPI: SI		4	7	0	1	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8E	
RLB_SPI: SI		8	4	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
success!
[SX1262] Starting to listen ... RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	0	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	A2	A2	

Debug Output for RX (FSK Modem, just chaning the begin function in both files)

RLB_SPI: CMDW	
RLB_SPI: SI	0	
RLB_SPI: SO	A2	
[SX1262] Initializing ... RLB_DBG: 
RadioLib Info
Version:  "6.6.0.0"
Platform: "Generic"
Compiled: "Sep  1 2024" "08:47:55"
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	1D	3	20	
RLB_SPI: SI				0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	53	58	31	32	36	31	20	56	32	44	20	32	44	30	32	0	
RLB_DBG: Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
RLB_DBG: 00000320: 53 58 31 32 36 31 20 56 32 44 20 32 44 30 32 00  SX1261 V2D 2D02.
RLB_DBG: 
RLB_DBG: M	SX126x
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8A	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	93	
RLB_SPI: SI		20	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	88	
RLB_SPI: SI		3	D	A	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8	
RLB_SPI: SI		0	0	0	0	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	89	
RLB_SPI: SI		7F	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		3	41	55	9	1A	0	CC	CC	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		3	41	55	9	1A	2	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		3	41	55	9	9	2	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	0	0	0	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	96	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	D	6	C0	
RLB_SPI: SI				12	AD	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	0	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		3	41	55	0	9	2	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	0	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	D	6	BC	
RLB_SPI: SI				1D	F	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	D	6	BE	
RLB_SPI: SI				10	21	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	9D	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	98	
RLB_SPI: SI		E1	E9	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	86	
RLB_SPI: SI		39	30	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	D8	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	C8	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	8	D8	
RLB_SPI: SI				DE	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	E7	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	18	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	95	
RLB_SPI: SI		4	7	0	1	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8E	
RLB_SPI: SI		14	4	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
success!
[SX1262] Starting to listen ... RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	A2	A2	A2	A2	
success!
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	0	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	54	54	
RLB_SPI: CMDR	12	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	0	2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	0	
RLB_SPI: CMDR	1E	0	
RLB_SPI: SI			0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	D4	D4	D4	54	69	6D	65	73	74	61	6D	70	3A	20	31	37	32	35	32	30	39	33	39	30	34	30	38	2C	20	48	65	6C	6C	6F	20	57	6F	72	6C	64	21	20	23	31	35	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	D4	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
Data: Timestamp: 1725209390408, Hello World! #15
RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	D2	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	54	54	
RLB_SPI: CMDR	12	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	0	2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	1E	0	
RLB_SPI: SI			0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	D4	D4	D4	54	69	6D	65	73	74	61	6D	70	3A	20	31	37	32	35	32	30	39	33	39	31	34	39	39	2C	20	48	65	6C	6C	6F	20	57	6F	72	6C	64	21	20	23	31	36	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	D4	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
Data: Timestamp: 1725209391499, Hello World! #16
RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	D2	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	54	54	
RLB_SPI: CMDR	12	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	0	2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	1E	0	
RLB_SPI: SI			0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	D4	D4	D4	54	69	6D	65	73	74	61	6D	70	3A	20	31	37	32	35	32	30	39	33	39	32	35	38	38	2C	20	48	65	6C	6C	6F	20	57	6F	72	6C	64	21	20	23	31	37	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	D4	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
Data: Timestamp: 1725209392588, Hello World! #17
RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	D2	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	54	54	
RLB_SPI: CMDR	12	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	0	2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	1E	0	
RLB_SPI: SI			0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	D4	D4	D4	54	69	6D	65	73	74	61	6D	70	3A	20	31	37	32	35	32	30	39	33	39	33	36	37	37	2C	20	48	65	6C	6C	6F	20	57	6F	72	6C	64	21	20	23	31	38	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	D4	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
Data: Timestamp: 1725209393677, Hello World! #18
RLB_SPI: CMDW	8	
RLB_SPI: SI		2	62	0	2	0	0	0	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D2	D2	0	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	10	5	10	0	1	FF	6	0	
RLB_SPI: SO	D2	D2	D2	D2	D2	D2	D2	D2	D2	D2	
RLB_SPI: CMDW	82	
RLB_SPI: SI		FF	FF	FF	
RLB_SPI: SO	D2	D2	D2	D2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	54	54	
RLB_SPI: CMDR	12	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	0	2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	0	
RLB_SPI: CMDR	13	
RLB_SPI: SI		0	0	0	
RLB_SPI: SO	D4	D4	2A	2A	
RLB_SPI: CMDR	1E	0	
RLB_SPI: SI			0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
RLB_SPI: SO	D4	D4	D4	54	69	6D	65	73	74	61	6D	70	3A	20	31	37	32	35	32	30	39	33	39	34	37	36	36	2C	20	48	65	6C	6C	6F	20	57	6F	72	6C	64	21	20	23	31	39	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	D4	D4	D4	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	D2	D2	D2	
Data: Timestamp: 1725209394766, Hello World! #19

@jgromes
Copy link
Owner
jgromes commented Sep 1, 2024

(Receiver Pi)

sdr@PI4:~/SX12XX_Project/src/RadioLib $ git describe --always
b9dd294

Try as I may, I cannot find that revision in this repository - are you sure you're not on some fork/branch? Either way, you have two different revisions, that doesn't seem intentional.

You also seem to be missing a sync word in your begin call, so you are transmitting packets with no preamble.

I would propose the following:

  1. Make sure you have the same version of RadioLib on both ends. The 6.6.0 update has some known issues, so I would suggest just doing a git pull in the repository to get the latest master. Check the version afterwards.
  2. Stick as close to the default configuration as possible. Only change the frequency and disable TCXO by calling radio.XTAL = false; prior to calling radio.begin. Only make incremental changes to the default values and after each one, make sure that the link still works.

Also, minor point - in your receive code, you don't have to call startReceive again in the loop.

PS: I took the liberty of editing your post to hide the long code listigns and debug logs with a "Details" section. A lot easier to read now, no?

@limccart7
Copy link
Author
limccart7 commented Sep 1, 2024

Okay, I have many updates. I wanted to address your suggestions first. I am running the exact same code as the receiver you sent, except obviously modified the pins for how my hardware is set up. (Just use radio.XTAL = true;, then radio.begin(), not changing any other parameters yet, only call startReceive outside of loop). These changes were of course reflected in the transmitter code as well, so the sync word is now 0x12, not 0x34. I'll attach them as details below.

  1. ... I would suggest just doing a git pull in the repository to get the latest master. Check the version afterwards.

I did this with the libraries on both Pi's and then from there did git describe --always. The following is the output from both, confirming they match:

lmk@QuADbackup:~/SX12XX_Project/RadioLib $ git pull
Already up to date.
lmk@QuADbackup:~/SX12XX_Project/RadioLib $ git describe --always
eda4ec22

Note: this is the secondary pi, hence the slightly different filepath. Same exact project, code, and cmake file accounts for this.

The transmitter is working, for sure. I am able to receive on my SDR running the same LoRa parameters, even despite the "-2" I get in SX126X.cpp at line 277 again. However when I run the receiver it gives me this:

Serial Output simple_rx (compiled from ref_rx.cpp)
lmk@QuADbackup:~/SX12XX_Project/lora_src $ ./simple_rx
[SX1261] Initializing ... RLB_DBG: 
RadioLib Info
Version:  "6.6.0.0"
Platform: "Generic"
Compiled: "Sep  1 2024" "14:28:36"
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	FF	FF	
RLB_DBG: -2 at /home/lmk/SX12XX_Project/RadioLib/src/Module.cpp:277
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	1D	3	20	
RLB_SPI: SI				0	0	0	0	0	00	0	0	0	0	0	0	0	0	0	0
RLB_SPI: SO	A2	A2	A2	A2	53	58	31	32	36	31	20	56	32	44	20	32	44	30	32	0	
RLB_DBG: Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
RLB_DBG: 00000320: 53 58 31 32 36 31 20 56 32 44 20 32 44 30 32 00  SX1261 V2D 2D02.
RLB_DBG: 
RLB_DBG: M	SX126x
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	FF	FF	
RLB_DBG: -2 at /home/lmk/SX12XX_Project/RadioLib/src/Module.cpp:277
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	80	
RLB_SPI: SI		0	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	8F	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8A	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	93	
RLB_SPI: SI		20	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	88	
RLB_SPI: SI		3	16	A	0	0	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	2	
RLB_SPI: SI		43	FF	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	8	
RLB_SPI: SI		0	0	0	0	0	0	0	0
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	89	
RLB_SPI: SI		7F	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		9	6	3	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	D	7	40	
RLB_SPI: SI				14	24	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	96	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	9D	
RLB_SPI: SI		1	
RLB_SPI: SO	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDR	1D	7	36	
RLB_SPI: SI				0	0	
RLB_SPI: SO	A2	A2	A2	A2	D	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	22	22	
RLB_SPI: CMDW	D	7	36	
RLB_SPI: SI				D	
RLB_SPI: SO	A2	A2	A2	A2	
RLB_SPI: CMDW	8C	
RLB_SPI: SI		0	8	0	FF	1	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		9	6	3	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	11	
RLB_SPI: SI		0	0	
RLB_SPI: SO	A2	A2	1	
RLB_SPI: CMDW	8B	
RLB_SPI: SI		9	4	3	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDW	98	
RLB_SPI: SI		6B	6F	
RLB_SPI: SO	A2	A2	A2	
RLB_SPI: CMDW	86	
RLB_SPI: SI		1B	20	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	D8	
RLB_SPI: SI				0	0	
RLB_SPI: SO	C2	C2	C2	C2	C8	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	C2	42	42	
RLB_SPI: CMDW	D	8	D8	
RLB_SPI: SI				DE	
RLB_SPI: SO	C2	C2	C2	C2	
RLB_SPI: CMDR	1D	8	E7	
RLB_SPI: SI				0	0	
RLB_SPI: SO	C2	C2	C2	C2	18	
RLB_SPI: CMDR	C0	
RLB_SPI: SI		0	0	
RLB_SPI: SO	C2	42	42	
RLB_SPI: CMDW	95	
RLB_SPI: SI		4	7	0	1	
RLB_SPI: SO	C2	C2	C2	C2	C2	
RLB_SPI: CMDW	8E	
RLB_SPI: SI		A	4	
RLB_SPI: SO	C2	C2	C2	
RLB_SPI: CMDW	D	8	E7	
RLB_SPI: SI				18	
RLB_SPI: SO	C2	C2	C2	C2	
success!
[SX1261] Starting to listen ... RLB_SPI: CMDW	8	
RLB_SPI: SI		2	72	0	2	0	0	0	0
RLB_SPI: SO	AA	AA	AA	AA	AA	AA	AA	AA	AA	
RLB_DBG: -707 at /home/lmk/SX12XX_Project/RadioLib/src/Module.cpp:277
RLB_DBG: -707 at /home/lmk/SX12XX_Project/RadioLib/src/modules/SX126x/SX126x.cpp:693
RLB_DBG: -707 at /home/lmk/SX12XX_Project/RadioLib/src/modules/SX126x/SX126x.cpp:611
failed, code -707

I've looked at the lines of SX126X.cpp that this error is received in and the two new lines (611, 693) deal with the IRQ pin. I have tried changing hardware pins for DIO1/IRQ as well as wires between the module and Pi to fix this, but still no change.

I'm providing my most up-to-date receiver and transmitter here:

ref_rx.cpp Note: edits were made to test using both lgpio HAL and wiringPi HAL. Both result in the same serial output (at least crashing with -707 at the lines listed). Wiring was also adjusted for this Pi, and the HAL code reflects that.
#include <RadioLib.h>
#include <iostream>     // For std::cout
#include <vector>       // For std::vector
#include "PiHal_WP.h"
//#include "PiHal_LG.h"

PiHal* hal = new PiHal(0);

//wiringPi module instance, use with PiHal_WP.h
// Create the radio module instance
// NSS pin: WiringPi 21 (GPIO 5)
// DIO1 pin: WiringPi 22 (GPIO 6)
// NRST pin: WiringPi 25 (GPIO 26)
// BUSY pin: WiringPi 27 (GPIO 16)

//testing other groups' pinout with both wiringPi and lgpio
// Create the radio module instance
// NSS pin: WiringPi 21 (GPIO 5)
// DIO1 pin: WiringPi 22 (GPIO 6)
// NRST pin: WiringPi 25 (GPIO 26)
// BUSY pin: WiringPi 27 (GPIO 16)
//SX1262 radio = new Module(hal, 5, 6, 26, 16);
volatile bool receivedFlag = false;
SX1262 radio = new Module(hal, 21, 22, 25, 27);
PhysicalLayer* phy = (PhysicalLayer*)&radio;

//IRQ
void setFlag() {
    receivedFlag = true;
    std::cout << "we received" << std::endl;
}

// the entry point for the program
int main(int argc, char** argv) {
  radio.XTAL = true;

  // initialize just like with Arduino
  printf("[SX1261] Initializing ... ");
  int state = radio.begin();
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  radio.setPacketReceivedAction(setFlag);

  printf("[SX1261] Starting to listen ... ");
  state = radio.startReceive();
  if (state != RADIOLIB_ERR_NONE) {
    printf("failed, code %d\n", state);
    return(1);
  }
  printf("success!\n");

  // loop forever
  int count = 0;
  uint8_t buff[256] = { 0 };
  for(;;) {
    if(receivedFlag) {
      // reset flag
      receivedFlag = false;
      size_t len = radio.getPacketLength();

      int state = radio.readData(buff, len);
      if (state != RADIOLIB_ERR_NONE) {
        printf("Read failed, code %d\n", state);
      } else {
        printf("Data: %s\n", (char*)buff);
      }
    }
  }

  return(0);
}
ref_tx.cpp
#include <RadioLib.h>
#include <chrono> // For timestamping
#include "PiHal_WP.h"
//#include "PiHal_LG.h"

PiHal* hal = new PiHal(0);

//wiringPi module instance, use with PiHal_WP.h
// Create the radio module instance
// NSS pin: WiringPi 21 (GPIO 5)
// DIO1 pin: WiringPi 22 (GPIO 6)
// NRST pin: WiringPi 25 (GPIO 26)
// BUSY pin: WiringPi 27 (GPIO 16)

//testing other groups' pinout with both wiringPi and lgpio
// Create the radio module instance
// NSS pin: WiringPi 21 (GPIO 5)
// DIO1 pin: WiringPi 22 (GPIO 6)
// NRST pin: WiringPi 25 (GPIO 26)
// BUSY pin: WiringPi 27 (GPIO 16)
//SX1262 radio = new Module(hal, 5, 6, 26, 16);
SX1262 radio = new Module(hal, 21, 22, 25, 27);
PhysicalLayer* phy = (PhysicalLayer*)&radio;

int main() {
    radio.XTAL = true;
    printf("[SX1262] Initializing ... ");
    //int state = radio.beginFSK(915.0, 4.8, 125.0, 467.0, 20.0, 16.0, 0.0, false);
    //int state = radio.begin(915.0, 250.0, 12, 5, 0x12, 10, 8, 0.0, true);
    int state = radio.begin();
    if (state != RADIOLIB_ERR_NONE) {
        printf("Initialization failed, code %d\n", state);
        return 1;
    }
    printf("Initialization success!\n");

    int count = 0;

    while (true) {
        //getcurrent time 
        auto now = std::chrono::high_resolution_clock::now();
        auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();

        //print the timestamp and packet number
        printf("[SX1262] Transmitting packet #%d at time %lld ms ... ", count, timestamp);

        //create a packet with the timestamp and message
        char str[64];
        sprintf(str, "Timestamp: %lld, Hello World! #%d", timestamp, count++);

        //send the packet
        state = radio.transmit(str);
        if (state == RADIOLIB_ERR_NONE) {
            printf("success!\n");

            //print the effective data rate for the transmitted packet
            float effectiveDataRate = radio.getDataRate();
            printf("Effective Data Rate: %.2f bps\n", effectiveDataRate);
        } else {
            printf("failed, code %d\n", state);
        }

        //don't want to overwhelm receiver
        hal->delay(1000);
    }

    return 0;
}

@jgromes
Copy link
Owner
jgromes commented Sep 2, 2024

The debug output shows something interesting:

RLB_SPI: CMDW	86	
RLB_SPI: SI		1B	20	0	0	
RLB_SPI: SO	A2	A2	A2	A2	A2	
RLB_SPI: CMDR	1D	8	D8	
RLB_SPI: SI				0	0	
RLB_SPI: SO	C2	C2	C2	C2	C8	

After the command 0x86 RADIOLIB_SX126X_CMD_SET_RF_FREQUENCY is sent, the status turns from 0xA2 to 0xC2. That means the device switched from standby to frequency synthesis, and then it just stays there. However, FS should be a transient mode, usually it's entered only prior to transmission or reception. I'm not sure why this only becomes an issue after the call to set IRQ, but it's definitely not something that should be happening.

Can you share you HAL?

Below is output from my RPi - you can see that it does not enter FS mode after setting the frequency. The hardware I'm using is a Waveshare LoRaWAN HAT. Same code as I posted above, just enabled debug.

Details

[SX1261] Initializing ... RLB_DBG: 
RadioLib Info
Version:  "6.6.0.0"
Platform: "Generic"
Compiled: "Sep  2 2024" "17:10:23"
RLB_SPI: CMDW   80
RLB_SPI: SI             0
RLB_SPI: SO     A2      A2
RLB_SPI: CMDR   1D      3       20
RLB_SPI: SI                             0       0       0       0       0       0       0       0       0       0       0       0    00       0       0       0
RLB_SPI: SO     A2      A2      A2      A2      53      58      31      32      36      31      20      56      32      44      20   32       44      30      32      0
RLB_DBG: Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
RLB_DBG: 00000320: 53 58 31 32 36 31 20 56 32 44 20 32 44 30 32 00  SX1261 V2D 2D02.
RLB_DBG: 
RLB_DBG: M      SX126x
RLB_SPI: CMDW   80
RLB_SPI: SI             0
RLB_SPI: SO     A2      A2
RLB_SPI: CMDW   80
RLB_SPI: SI             0
RLB_SPI: SO     A2      A2
RLB_SPI: CMDW   8F
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDW   8A
RLB_SPI: SI             1
RLB_SPI: SO     A2      A2
RLB_SPI: CMDW   93
RLB_SPI: SI             20
RLB_SPI: SO     A2      A2
RLB_SPI: CMDW   88
RLB_SPI: SI             3       16      A       0       0       0       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDW   2
RLB_SPI: SI             43      FF
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDW   8
RLB_SPI: SI             0       0       0       0       0       0       0       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDW   89
RLB_SPI: SI             7F
RLB_SPI: SO     A2      A2
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDW   8B
RLB_SPI: SI             9       6       3       0
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDW   D       7       40
RLB_SPI: SI                             14      24
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDR   1D      7       36
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      D
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   D       7       36
RLB_SPI: SI                             D
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDW   8C
RLB_SPI: SI             0       8       0       FF      1       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDW   96
RLB_SPI: SI             1
RLB_SPI: SO     A2      A2
RLB_SPI: CMDW   D       8       E7
RLB_SPI: SI                             18
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDW   9D
RLB_SPI: SI             1
RLB_SPI: SO     A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDR   1D      7       36
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      D
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   D       7       36
RLB_SPI: SI                             D
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDW   8C
RLB_SPI: SI             0       8       0       FF      1       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDR   1D      7       36
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      D
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   D       7       36
RLB_SPI: SI                             D
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDW   8C
RLB_SPI: SI             0       8       0       FF      1       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDW   8B
RLB_SPI: SI             9       6       3       0
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDW   8B
RLB_SPI: SI             9       4       3       0
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDW   98
RLB_SPI: SI             6B      6F
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDW   86
RLB_SPI: SI             1B      20      0       0
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDR   1D      8       D8
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      C8
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   D       8       D8
RLB_SPI: SI                             DE
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDR   1D      8       E7
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      18
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   95
RLB_SPI: SI             4       7       0       1
RLB_SPI: SO     A2      A2      A2      A2      A2
RLB_SPI: CMDW   8E
RLB_SPI: SI             A       4
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDW   D       8       E7
RLB_SPI: SI                             18
RLB_SPI: SO     A2      A2      A2      A2
success!
[SX1261] Starting to listen ... RLB_SPI: CMDW   8
RLB_SPI: SI             2       72      0       2       0       0       0       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDW   8F
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDW   2
RLB_SPI: SI             43      FF
RLB_SPI: SO     A2      A2      A2
RLB_SPI: CMDR   11
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      A2      1
RLB_SPI: CMDR   1D      7       36
RLB_SPI: SI                             0       0
RLB_SPI: SO     A2      A2      A2      A2      D
RLB_SPI: CMDR   C0
RLB_SPI: SI             0       0
RLB_SPI: SO     A2      22      22
RLB_SPI: CMDW   D       7       36
RLB_SPI: SI                             D
RLB_SPI: SO     A2      A2      A2      A2
RLB_SPI: CMDW   8C
RLB_SPI: SI             0       8       0       FF      1       0
RLB_SPI: SO     A2      A2      A2      A2      A2      A2      A2
RLB_SPI: CMDW   82
RLB_SPI: SI             FF      FF      FF
RLB_SPI: SO     A2      A2      A2      A2
success!

@limccart7
Copy link
Author

Here are both the lgpio (unedited from source I believe) HAL and wiringPi HAL. The wiringPi HAL has worked consistently, but using different pins than my partner's setup I am able to use both and reproduce the same error I pasted in my last reply.

PiHAL_LG.h
#ifndef PI_HAL_LGPIO_H
#define PI_HAL_LGPIO_H

// include RadioLib
#include <RadioLib.h>

// include the library for Raspberry GPIO pins
#include <lgpio.h>

#define PI_RISING         (LG_RISING_EDGE)
#define PI_FALLING        (LG_FALLING_EDGE)
#define PI_INPUT          (0)
#define PI_OUTPUT         (1)
#define PI_MAX_USER_GPIO  (31)

// forward declaration of alert handler that will be used to emulate interrupts
static void lgpioAlertHandler(int num_alerts, lgGpioAlert_p alerts, void *userdata);

// create a new Raspberry Pi hardware abstraction layer
// using the lgpio library
// the HAL must inherit from the base RadioLibHal class
// and implement all of its virtual methods
class PiHal : public RadioLibHal {
  public:
    // default constructor - initializes the base HAL and any needed private members
    PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000, uint8_t spiDevice = 0, uint8_t gpioDevice = 4)
      : RadioLibHal(PI_INPUT, PI_OUTPUT, LG_LOW, LG_HIGH, PI_RISING, PI_FALLING),
      _gpioDevice(gpioDevice),
      _spiDevice(spiDevice),
      _spiChannel(spiChannel),
      _spiSpeed(spiSpeed) {
    }

    void init() override {
      // first initialise lgpio library
      if((_gpioHandle = lgGpiochipOpen(_gpioDevice)) < 0) {
        fprintf(stderr, "Could not open GPIO chip: %s\n", lguErrorText(_gpioHandle));
        return;
      }

      // now the SPI
      spiBegin();
    }

    void term() override {
      // stop the SPI
      spiEnd();

      // finally, stop the lgpio library
      lgGpiochipClose(_gpioHandle);
    }

    // GPIO-related methods (pinMode, digitalWrite etc.) should check
    // RADIOLIB_NC as an alias for non-connected pins
    void pinMode(uint32_t pin, uint32_t mode) override {
      if(pin == RADIOLIB_NC) {
        return;
      }

      int result;
      int flags = 0;
      switch(mode) {
        case PI_INPUT:
          result = lgGpioClaimInput(_gpioHandle, 0, pin);
          break;
        case PI_OUTPUT:
          result = lgGpioClaimOutput(_gpioHandle, flags, pin, LG_HIGH);
          break;
        default:
          fprintf(stderr, "Unknown pinMode mode %" PRIu32 "\n", mode);
          return;
      }

      if(result < 0) {
        fprintf(stderr, "Could not claim pin %" PRIu32 " for mode %" PRIu32 ": %s\n",
            pin, mode, lguErrorText(result));
      }
    }

    void digitalWrite(uint32_t pin, uint32_t value) override {
      if(pin == RADIOLIB_NC) {
        return;
      }

      int result = lgGpioWrite(_gpioHandle, pin, value);
      if(result < 0) {
        fprintf(stderr, "Error writing value to pin %" PRIu32 ": %s\n", pin, lguErrorText(result));
      }
    }

    uint32_t digitalRead(uint32_t pin) override {
      if(pin == RADIOLIB_NC) {
        return(0);
      }

      int result = lgGpioRead(_gpioHandle, pin);
      if(result < 0) {
        fprintf(stderr, "Error writing reading from pin %" PRIu32 ": %s\n", pin, lguErrorText(result));
      }
      return result;
    }

    void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
      if((interruptNum == RADIOLIB_NC) || (interruptNum > PI_MAX_USER_GPIO)) {
        return;
      }

      // set lgpio alert callback
      int result = lgGpioClaimAlert(_gpioHandle, 0, mode, interruptNum, -1);
      if(result < 0) {
        fprintf(stderr, "Could not claim pin %" PRIu32 " for alert: %s\n", interruptNum, lguErrorText(result));
        return;
      }

      // enable emulated interrupt
      interruptEnabled[interruptNum] = true;
      interruptModes[interruptNum] = mode;
      interruptCallbacks[interruptNum] = interruptCb;

      lgGpioSetAlertsFunc(_gpioHandle, interruptNum, lgpioAlertHandler, (void *)this);
    }

    void detachInterrupt(uint32_t interruptNum) override {
      if((interruptNum == RADIOLIB_NC) || (interruptNum > PI_MAX_USER_GPIO)) {
        return;
      }

      // clear emulated interrupt
      interruptEnabled[interruptNum] = false;
      interruptModes[interruptNum] = 0;
      interruptCallbacks[interruptNum] = NULL;

      // disable lgpio alert callback
      lgGpioFree(_gpioHandle, interruptNum);
      lgGpioSetAlertsFunc(_gpioHandle, interruptNum, NULL, NULL);
    }

    void delay(unsigned long ms) override {
      if(ms == 0) {
        sched_yield();
        return;
      }

      lguSleep(ms / 1000.0);
    }

    void delayMicroseconds(unsigned long us) override {
      if(us == 0) {
        sched_yield();
        return;
      }

      lguSleep(us / 1000000.0);
    }

    void yield() override {
      sched_yield();
    }

    unsigned long millis() override {
      uint32_t time = lguTimestamp() / 1000000UL;
      return time;
    }

    unsigned long micros() override {
      uint32_t time = lguTimestamp() / 1000UL;
      return time;
    }

    long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
      if(pin == RADIOLIB_NC) {
        return(0);
      }

      this->pinMode(pin, PI_INPUT);
      uint32_t start = this->micros();
      uint32_t curtick = this->micros();

      while(this->digitalRead(pin) == state) {
        if((this->micros() - curtick) > timeout) {
          return(0);
        }
      }

      return(this->micros() - start);
    }

    void spiBegin() {
      if(_spiHandle < 0) {
        if((_spiHandle = lgSpiOpen(_spiDevice, _spiChannel, _spiSpeed, 0)) < 0) {
          fprintf(stderr, "Could not open SPI handle on 0: %s\n", lguErrorText(_spiHandle));
        }
      }
    }

    void spiBeginTransaction() {}

    void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
      int result = lgSpiXfer(_spiHandle, (char *)out, (char*)in, len);
      if(result < 0) {
        fprintf(stderr, "Could not perform SPI transfer: %s\n", lguErrorText(result));
      }
    }

    void spiEndTransaction() {}

    void spiEnd() {
      if(_spiHandle >= 0) {
        lgSpiClose(_spiHandle);
        _spiHandle = -1;
      }
    }

    void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) {
      lgTxPwm(_gpioHandle, pin, frequency, 50, 0, duration);
    }

    void noTone(uint32_t pin) {
      lgTxPwm(_gpioHandle, pin, 0, 0, 0, 0);
    }

    // interrupt emulation
    bool interruptEnabled[PI_MAX_USER_GPIO + 1];
    uint32_t interruptModes[PI_MAX_USER_GPIO + 1];
    typedef void (*RadioLibISR)(void);
    RadioLibISR interruptCallbacks[PI_MAX_USER_GPIO + 1];

  private:
    // the HAL can contain any additional private members
    const unsigned int _spiSpeed;
    const uint8_t _gpioDevice;
    const uint8_t _spiDevice;
    const uint8_t _spiChannel;
    int _gpioHandle = -1;
    int _spiHandle = -1;
};

// this handler emulates interrupts
static void lgpioAlertHandler(int num_alerts, lgGpioAlert_p alerts, void *userdata) {
  if(!userdata)
    return;

  // PiHal instance is passed via the user data
  PiHal* hal = (PiHal*)userdata;

  // check the interrupt is enabled, the level matches and a callback exists
  for(lgGpioAlert_t *alert = alerts; alert < (alerts + num_alerts); alert++) {
    if((hal->interruptEnabled[alert->report.gpio]) &&
       (hal->interruptModes[alert->report.gpio] == alert->report.level) &&
       (hal->interruptCallbacks[alert->report.gpio])) {
      hal->interruptCallbacks[alert->report.gpio]();
    }
  }
}

#endif
PiHAL_WP.h
#ifndef PI_HAL_WIRINGPI_H
#define PI_HAL_WIRINGPI_H

// include RadioLib
#include <RadioLib.h>

// include the library for Raspberry GPIO pins
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <cerrno>
#include <sched.h>
#include <inttypes.h>


#define PI_RISING         (INT_EDGE_RISING)
#define PI_FALLING        (INT_EDGE_FALLING)
#define PI_INPUT          (INPUT)
#define PI_OUTPUT         (OUTPUT)
#define PI_MAX_USER_GPIO  (31)

// forward declaration of alert handler that will be used to emulate interrupts
static void wiringPiInterruptHandler(void);

// create a new Raspberry Pi hardware abstraction layer
// using the wiringPi library
// the HAL must inherit from the base RadioLibHal class
// and implement all of its virtual methods
class PiHal : public RadioLibHal {
  public:
    // default constructor - initializes the base HAL and any needed private members
    PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000)
      : RadioLibHal(PI_INPUT, PI_OUTPUT, LOW, HIGH, PI_RISING, PI_FALLING),
      _spiChannel(spiChannel),
      _spiSpeed(spiSpeed) {
    }

    void init() override {
      // Initialize wiringPi library
      if (wiringPiSetup() == -1) {
        fprintf(stderr, "Failed to initialize wiringPi\n");
        return;
      }

      // now the SPI
      spiBegin();
    }

    void term() override {
      // stop the SPI
      spiEnd();
    }

    // GPIO-related methods (pinMode, digitalWrite etc.) should check
    // RADIOLIB_NC as an alias for non-connected pins
    void pinMode(uint32_t pin, uint32_t mode) override {
      if(pin == RADIOLIB_NC) {
        return;
      }

      ::pinMode(pin, mode);
    }

    void digitalWrite(uint32_t pin, uint32_t value) override {
      if(pin == RADIOLIB_NC) {
        return;
      }

      ::digitalWrite(pin, value);
    }

    uint32_t digitalRead(uint32_t pin) override {
      if(pin == RADIOLIB_NC) {
        return(0);
      }

      return ::digitalRead(pin);
    }

    void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
      if(interruptNum == RADIOLIB_NC || interruptNum > PI_MAX_USER_GPIO) {
        return;
      }

      // enable emulated interrupt
      interruptEnabled[interruptNum] = true;
      interruptModes[interruptNum] = mode;
      interruptCallbacks[interruptNum] = interruptCb;

      // set wiringPi interrupt callback
      if (wiringPiISR(interruptNum, mode, interruptCb) < 0) {
        fprintf(stderr, "Could not set ISR for pin %" PRIu32 "\n", interruptNum);
      }
    }

    void detachInterrupt(uint32_t interruptNum) override {
      if(interruptNum == RADIOLIB_NC || interruptNum > PI_MAX_USER_GPIO) {
        return;
      }

      // clear emulated interrupt
      interruptEnabled[interruptNum] = false;
      interruptModes[interruptNum] = 0;
      interruptCallbacks[interruptNum] = NULL;
      
      // No direct way to detach in wiringPi, disable callback
      if (wiringPiISR(interruptNum, INT_EDGE_SETUP, nullptr) < 0) {
        fprintf(stderr, "Could not detach ISR for pin %" PRIu32 "\n", interruptNum);
      }
    }

    void delay(unsigned long ms) override {
      if(ms == 0) {
        sched_yield();
        return;
      }

      ::delay(ms);
    }

    void delayMicroseconds(unsigned long us) override {
      if(us == 0) {
        sched_yield();
        return;
      }

      ::delayMicroseconds(us);
    }

    void yield() override {
      sched_yield();
    }

    unsigned long millis() override {
      return ::millis();
    }

    unsigned long micros() override {
      return ::micros();
    }

    long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
      if(pin == RADIOLIB_NC) {
        return(0);
      }

      this->pinMode(pin, PI_INPUT);
      uint32_t start = this->micros();
      uint32_t curtick = this->micros();

      while(this->digitalRead(pin) == state) {
        if((this->micros() - curtick) > timeout) {
          return(0);
        }
      }

      return(this->micros() - start);
    }

    void spiBegin() {
      // SPI initialization is done in init
      if (wiringPiSPISetup(_spiChannel, _spiSpeed) < 0) {
        fprintf(stderr, "Could not open SPI handle: %s\n", strerror(errno));
      }
    }

    void spiBeginTransaction() {}

    void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
      uint8_t* buffer = new uint8_t[len];
      memcpy(buffer, out, len);

      if (wiringPiSPIDataRW(_spiChannel, buffer, len) == -1) {
        fprintf(stderr, "Could not perform SPI transfer: %s\n", strerror(errno));
      }

      memcpy(in, buffer, len);
      delete[] buffer;
    }

    void spiEndTransaction() {}

    void spiEnd() {
      // No specific end method for SPI in wiringPi
    }

    void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) {
      // No direct implementation in wiringPi, can be customized if needed
    }

    void noTone(uint32_t pin) {
      // No direct implementation in wiringPi, can be customized if needed
    }

    // interrupt emulation
    bool interruptEnabled[PI_MAX_USER_GPIO + 1];
    uint32_t interruptModes[PI_MAX_USER_GPIO + 1];
    typedef void (*RadioLibISR)(void);
    RadioLibISR interruptCallbacks[PI_MAX_USER_GPIO + 1];

  private:
    // the HAL can contain any additional private members
    const unsigned int _spiSpeed;
    const uint8_t _spiChannel;
};

#endif

@jgromes
Copy link
Owner
jgromes commented Sep 13, 2024

Thanks for sharing the HAL, aside from some strange stuff (why are copying the buffers in spiTransfer ... ? and are you sure the interrupt is working?), nothing seems immediately obvious.

I'm still puzzled as to the device being stuck in FS mode. You could try different frequencies to see if that behavior persists, or force calibration by calling SX1262::setFrequency(freq, true);. Another thing to check is the power supply, I suspect there may be some high-frequency noise from the RPi that causes this (e.g. by intefering with its oscillators/PLL). Decoupling capacitors go some way to remove that. As a last resort, I would try an older RPi.

Unfortunately since the behavior seems rather random (behaving differently on different devices), it seems to be pointing to an issue with the hardware setup, specifically the RPi 5. So until we have more information taht points to some bug in the library code, I will convert this thread to a discussion.

Repository owner locked and limited conversation to collaborators Sep 13, 2024
@jgromes jgromes converted this issue into discussion #1218 Sep 13, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants