Skip to content
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

refactor(rc channels): Use event handler for fail-safe and RC channels #79

Merged
merged 8 commits into from
Feb 6, 2024

Conversation

ZZ-Cat
Copy link
Owner

@ZZ-Cat ZZ-Cat commented Feb 6, 2024

Overview

This Pull Request re-factors the old API for reading RC Channels, and puts them into their own event handler.
This same event handler also reads the receiver's fail-safe state based on the RSSI and LQI thresholds set in the CFA_Config.hpp file.

Details

Like the other event handlers, you register the callback using CRSFforArduino::setRcCallback(serialReceiverLayer::rcChannels_t *)
The underlying _rcChannels array has been rewritten as a data structure, which now holds not only your raw RC channels data, but also holds a failsafe flag which you can read out in the Event's callback function.

Here is what the RC Channels Event Handler API looks like:

#include "Arduino.h"
#include "CRSFforArduino.hpp"

/* Declare CRSF for Arduino up here as a null pointer. */
CRSFforArduino *crsf = nullptr;

/* As is the case with other callback functions, this is required to be here. */
void onReceiveRcChannels(serialReceiverLayer::rcChannels_t *rcChannels);

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

    /* Instantiate CRSF for Arduino and initialise it. */
    crsf = new CRSFforArduino();
    if (!crsf->begin())
    {
        Serial.println("CRSF for Arduino failed to initialise.");

        delete crsf;
        crsf = nullptr;

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

    /* Register your RC Channels callback function. */
    crsf->setRcChannelsCallback(onReceiveRcChannels);
}

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

  /* Note how there is nothing else to do in the main loop anymore.
  This is all handled by the new events system. */
}

/* The RC Channels callback is executed when RC Channels are received. */
void onReceiveRcChannels(serialReceiverLayer::rcChannels_t *rcChannels)
{
    static unsigned long lastPrint = millis();
    if (millis() - lastPrint >= 100)
    {
        lastPrint = millis();

        static bool initialised = false;
        static bool lastFailSafe = false;
        if (rcChannels->failsafe != lastFailSafe || !initialised)
        {
            initialised = true;
            lastFailSafe = rcChannels->failsafe;
            Serial.print("FailSafe: ");
            Serial.println(lastFailSafe ? "Active" : "Inactive");
        }

        if (rcChannels->failsafe == false)
        {
            /* Here, you can read back your RC channels. */
            Serial.print("RC Channels <A: ");
            Serial.print(crsf->rcToUs(rcChannels->value[0]));
            Serial.print(", E: ");
            Serial.print(crsf->rcToUs(rcChannels->value[1]));
            Serial.print(", T: ");
            Serial.print(crsf->rcToUs(rcChannels->value[2]));
            Serial.print(", R: ");
            Serial.print(crsf->rcToUs(rcChannels->value[3]));
            Serial.print(", Aux1: ");
            Serial.print(crsf->rcToUs(rcChannels->value[4]));
            Serial.print(", Aux2: ");
            Serial.print(crsf->rcToUs(rcChannels->value[5]));
            Serial.print(", Aux3: ");
            Serial.print(crsf->rcToUs(rcChannels->value[6]));
            Serial.print(", Aux4: ");
            Serial.print(crsf->rcToUs(rcChannels->value[7]));
            Serial.println(">");
        }
        else
        {
            /* Here, you may add in your own fail-safe handling code.
            For now, simply do nothing. */
        }
    }
}

In CFA_Config.hpp you have two options:

  • CRSF_FAILSAFE_LQI_THRESHOLD
  • CRSF_FAILSAFE_RSSI_THRESHOLD

The CRSF_FAILSAFE_LQI_THRESHOLD is the minimum Link Quality value that the receiver considers to be connected. You can set this to any arbitrary value from 0 to 100.
The CRSF_FAILSAFE_RSSI_THRESHOLD is the minimum RSSI. It is recommended that you set this to the same value as your packet rate's RSSI Sensitivity Limit.

When either one of these thresholds are crossed, this is what constitutes a fail-safe.
This is pretty rudimentary, but it will do for now, and it can be expanded later on down the track, if the need to do so arises.

Additional notes

I decided to leave out the ability to read back whether-or-not a received CRSF packet has either passed or failed its checksum for the time being. I know this was a part of what was brought up in #51, however, later on down the track, it may be better to automatically incorporate multiple checksum fails into "what constitutes a fail-safe".

@ZZ-Cat ZZ-Cat linked an issue Feb 6, 2024 that may be closed by this pull request
@ZZ-Cat ZZ-Cat self-assigned this Feb 6, 2024
@ZZ-Cat ZZ-Cat added this to the Version 1.0.0 milestone Feb 6, 2024
@ZZ-Cat ZZ-Cat merged commit a70ef2e into Main-Trunk Feb 6, 2024
4 checks passed
@ZZ-Cat ZZ-Cat deleted the ZZ-Cat/issue69 branch February 6, 2024 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Add failsafe handling
1 participant