ZZ-Cat / CRSFforArduino

An Arduino Library for communicating with ExpressLRS and TBS Crossfire receivers.
GNU Affero General Public License v3.0
143 stars 24 forks source link

feat(link statistics): Add Link Statistics API #78

Closed ZZ-Cat closed 8 months ago

ZZ-Cat commented 8 months ago

Overview

This Pull Request introduces the ability to read link statistics from the CRSF data stream, using an event-driven API.

Details

The following example highlights the new API...

#include "CRSFforArduino.hpp"

/* Declare a null pointer to CRSF for Arduino. */
CRSFforArduino *crsf = nullptr;

/* This needs to be up here, to prevent compiler warnings. */
void onLinkStatisticsUpdate(serialReceiverLayer::link_statistics_t);

void setup()
{
    Serial.begin(115200);
    while (!Serial)
    {
        delay(10);
    }

    Serial.println("Link Statistics Example.");

    /* Initialise CRSF for Arduino. */
    crsf = new CRSFforArduino();

    if (!crsf->begin())
    {
        Serial.println("CRSF for Arduino failed to initialise.");

        delete crsf;
        crsf = nullptr;

        while (1)
        {
            delay(10);
        }
    }

    /* Set your link statistics callback. */
    crsf->setLinkStatisticsCallback(onLinkStatisticsUpdate);

    /* Example firmware is ready. */
    Serial.println("Ready.");
    delay(1000);
}

void loop()
{
    /* Update CRSF for Arduino in the main loop. */
    crsf->update();
}

void onLinkStatisticsUpdate(serialReceiverLayer::link_statistics_t linkStatistics)
{
    /* Here is where you can read out the link statistics.
    You have access to the following data:
    - RSSI (dBm)
    - Link Quality (%)
    - Signal-to-Noise Ratio (dBm)
    - Transmitter Power (mW) */
    static unsigned long lastPrint = 0;
    if (millis() - lastPrint >= 200)
    {
        lastPrint = millis();
        Serial.print("Link Statistics: ");
        Serial.print("RSSI: ");
        Serial.print(linkStatistics.rssi);
        Serial.print(", Link Quality: ");
        Serial.print(linkStatistics.lqi);
        Serial.print(", Signal-to-Noise Ratio: ");
        Serial.print(linkStatistics.snr);
        Serial.print(", Transmitter Power: ");
        Serial.println(linkStatistics.tx_power);
    }
}

Additional notes

The Link Statistics Event only fires when complete CRSF packets are received.
ExpressLRS receivers emit several Link Statistics packets for about five seconds after the receiver has gone into Fail-Safe state.
This is reliable enough to see whether-or-not the receiver has lost connection with the transmitter.
By watching the Link Quality value, we can determine the stability of the connection, plus whether-or-not there's a Fail-Safe.