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(library): Flight Modes API and Custom Flight Modes integration, plus code and comments clean-up #84

Merged
merged 31 commits into from
Feb 20, 2024

Conversation

ZZ-Cat
Copy link
Owner

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

Overview

This Pull Request is the "final touches" I need to do with the code-base before it's released.
It brings in some much needed housekeeping, and quality-of-life fixes.

Details

Deleted...

  • CoPilot Prompts.
  • Deprecated code.
  • Unnecessary code.
  • Unnecessary comments.

Disabled...

  • Arduino CI compile-testing on "supported platforms", until Adafruit fixes a bug with CI on their end.

Fixes...

  • Class constructors being called twice. EG serialReceiverLayer::SerialReceiver::SerialReceiver();
  • Compiler warnings.
  • Memory leaks.

Re-factors...

  • Flight Modes API
  • Custom Flight Modes integration

API changes

Flight Modes API

Both standard and custom flight modes are registered with this function:

  • setFlightMode(serialReceiverLayer::flightModeId_t flightModeId, const char *flightModeName, uint8_t channel, uint16_t min, uint16_t max)
    • flightModeId is the same Flight Mode constants you all have been using, thus far.
    • flightModeName allows you to give your flight mode a name to identify it.
      This is particularly useful for Custom Flight Modes.
    • channel is your chosen channel number from 1 to 16.
    • min is the minimum channel value (in microseconds) that will trigger this mode.
    • max is the maximum channel value (in microseconds) that will trigger this mode.

Both standard Flight Modes and custom Flight Modes are written out using this function:

  • telemetryWriteFlightMode(serialReceiverLayer::flightModeId_t flightMode, bool disarmed)
    • flightMode is the Flight Mode ID to pass in.
    • disarmed is whether-or-not you have flicked your Disarmed channel (Usually Aux1 for ExpressLRS) or not.
      • true means it is disarmed.
      • false means it is armed.

An example usage situation looks like this:

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

/* Define our modes up here, including putting ARM on Channel 5 (Aux1). */
#define FLIGHT_MODE_ARM_CHANNEL 5
#define FLIGHT_MODE_ARM_MIN     1000
#define FLIGHT_MODE_ARM_MAX     1800

#define FLIGHT_MODE_NORMAL_CHANNEL 6
#define FLIGHT_MODE_NORMAL_MIN     750
#define FLIGHT_MODE_NORMAL_MAX     1250

#define FLIGHT_MODE_IDLEUP1_CHANNEL 6
#define FLIGHT_MODE_IDLEUP1_MIN     1250
#define FLIGHT_MODE_IDLEUP1_MAX     1750

#define FLIGHT_MODE_IDLEUP2_CHANNEL 6
#define FLIGHT_MODE_IDLEUP2_MIN     1750
#define FLIGHT_MODE_IDLEUP2_MAX     2250

/* Pointer to CRSF for Arduino. */
CRSFforArduino *crsf = nullptr;

/* Our Flight Modes handler may be declared here. */
void onFlightModeUpdate(serialReceiverLayer::flightModeId_t);

void setup()
{
    /* Initialise the native USB port and wait for it to be ready. */
    Serial.begin(115200);
    while (!Serial)
    {
        delay(10);
    }

    Serial.println("[Sketch | INFO]: CRSF for Arduino Example");

    /* Create a new CRSF for Arduino object and initialise it. */
    crsf = new CRSFforArduino();
    if (!crsf->begin())
    {
        /* CRSF for Arduino failed to initialise.
        Tear-down and clean up any resources what were allocated. */
        crsf->end();
        delete crsf;
        crsf = nullptr;

        Serial.println("[Sketch | ERROR]: CRSF failed to initialise.");
    }
    else
    {
        /* CRSF for Arduino successfully initialised.
        Now, register the custom flight modes, along with the Disarmed mode. */
        crsf->setFlightMode(serialReceiverLayer::FLIGHT_MODE_DISARMED, FLIGHT_MODE_ARM_CHANNEL, FLIGHT_MODE_ARM_MIN, FLIGHT_MODE_ARM_MAX);
        crsf->setFlightMode(serialReceiverLayer::CUSTOM_FLIGHT_MODE1, "Normal", FLIGHT_MODE_NORMAL_CHANNEL, FLIGHT_MODE_NORMAL_MIN, FLIGHT_MODE_NORMAL_MAX);
        crsf->setFlightMode(serialReceiverLayer::CUSTOM_FLIGHT_MODE2, "Idle-Up 1", FLIGHT_MODE_IDLEUP1_CHANNEL, FLIGHT_MODE_IDLEUP1_MIN, FLIGHT_MODE_IDLEUP1_MAX);
        crsf->setFlightMode(serialReceiverLayer::CUSTOM_FLIGHT_MODE3, "Idle-Up 2", FLIGHT_MODE_IDLEUP2_CHANNEL, FLIGHT_MODE_IDLEUP2_MIN, FLIGHT_MODE_IDLEUP2_MAX);

        /* Set the Flight Modes callback. */
        crsf->setFlightModeCallback(onFlightModeUpdate);

        Serial.println("[Sketch | INFO]: CRSF initialised.");
    }
}

void loop()
{
    /* Guard CRSF for Arduino. */
    if (crsf != nullptr)
    {
        /* Update CRSF for Arduino. */
        crsf->update();
    }
}

void onFlightModeUpdate(serialReceiverLayer::flightModeId_t flightMode)
{
    /* This is our Flight Modes callback that we declared earlier.
    Whenever a Flight Mode is changed, this is what gets called.
    You may write your own Flight Modes implementation using this callback function.
    For the purposes of this example, simply relaying the flight modes back to the handset is shown here,
    and the modes are printed to the Serial Monitor. */

    /* Are we disarmed? */
    bool isDisarmed = true;
    if (flightMode != serialReceiverLayer::FLIGHT_MODE_DISARMED)
    {
        isDisarmed = false;
    }
    else if (isFailsafeActive)
    {
        isDisarmed = true;
    }

    /* Update the flight mode telemetry with the new value. */
    crsf->telemetryWriteFlightMode(flightMode, isDisarmed);


    /* Print the flight mode to the Serial Monitor, but only if the flight mode has changed. */
    static serialReceiverLayer::flightModeId_t lastFlightMode = serialReceiverLayer::FLIGHT_MODE_DISARMED;
    if (flightMode != lastFlightMode)
    {
        lastFlightMode = flightMode;

        Serial.print("[Sketch | INFO]: Flight Mode: ");
        switch (flightMode)
        {
            case serialReceiverLayer::FLIGHT_MODE_DISARMED:
                Serial.println("Disarmed");
                break;
            case serialReceiverLayer::CUSTOM_FLIGHT_MODE1:
                Serial.println("Normal");
                break;
            case serialReceiverLayer::CUSTOM_FLIGHT_MODE2:
                Serial.println("Idle Up 1");
                break;
            case serialReceiverLayer::CUSTOM_FLIGHT_MODE3:
                Serial.println("Idle Up 2");
                break;
            default:
                Serial.println("Unknown");
                break;
        }
    }
}

In order to use the API above, you MUST have the following flags set in CFA_Config.hpp:

  • CRSF_FLIGHTMODES_ENABLED set to 1
  • CRSF_CUSTOM_FLIGHT_MODES_ENABLED set to 1 if you want access to the Custom Flight Modes integration.

This is also assuming that you have CRSF_RC_ENABLED set to 1 (which is the default, by the way. Because the entire library relies on this for everything), and you have CRSF_TELEMETRY_ENABLED set to 1 if you want your Flight Modes to be fed back to your controller.

Additional

Now that this is complete. All that is left is the documentation.
Then, CRSF for Arduino version 1.0.0 will be released to the public.

Thank you all from the bottom of my heart for being here, and using my library in your projects.
A huge thanks to those daring enough to try out CRSF for Arduino in its various stages of jankiness-to-refinement and everything in between.

These were being called twice, resulting in unnecessary bloat.
…n `SerialReceiver::begin()`

A hardware fault is triggered when there is insufficient memory available anyway.
…e RC Channels Callback if a frame has been received

Polling for RC channels when none have been received is unnecessary
…PTIMISATION_HARDWARE`

Hardware-accelerated CRC is not yet implemented.
@ZZ-Cat ZZ-Cat added the Arduino IDE ♾️ This is specific to the Arduino IDE label Feb 17, 2024
@ZZ-Cat ZZ-Cat self-assigned this Feb 17, 2024
@ZZ-Cat ZZ-Cat added PlatformIO 👽 This is specific to PlatformIO. ...in progress 🚧 Development on this is in progress labels Feb 17, 2024
@ZZ-Cat ZZ-Cat added this to the Version 1.0.0 milestone Feb 17, 2024
@ZZ-Cat ZZ-Cat mentioned this pull request Feb 17, 2024
27 tasks
@ZZ-Cat
Copy link
Owner Author

ZZ-Cat commented Feb 17, 2024

Ugh! =-/.(\=
A bug on Adafruit's end has tripped my continuous integration for testing CRSF for Arduino on supported Arduino platforms.
I am actually thinking about disabling it entirely, because it actually no longer compile-tests on the platforms that CRSF for Arduino is currently compatible with. It only compile-tests for the Metro M4 Express. CRSF for Arduino supports a more diverse range of targets now, compared to when I started this project a year or two ago.

…fixes their fault detection issue

This whittles the Arduino CI back to merely checking for correct code format.
…elemetryWriteFlightMode()` up to the Sketch Layer

This is the first of two parts to re-factoring the Flight Modes telemetry function.
…eceiverLayer::flightModeId_t flightMode, uint8_t channel, uint16_t min, uint16_t max)`
…lightMode(const char *flightMode, bool armed)`
…tMode(flightModeId_t flightMode, uint8_t channel, uint16_t min, uint16_t max)`
@ZZ-Cat ZZ-Cat changed the title refactor(library): Clean up code refactor(library): Flight Modes API, Custom Flight Modes integration, clean-up code and comments Feb 20, 2024
@ZZ-Cat ZZ-Cat changed the title refactor(library): Flight Modes API, Custom Flight Modes integration, clean-up code and comments refactor(library): Flight Modes API and Custom Flight Modes integration, plus code and comments clean-up Feb 20, 2024
@ZZ-Cat ZZ-Cat marked this pull request as ready for review February 20, 2024 21:42
@ZZ-Cat ZZ-Cat merged commit 38f3609 into Main-Trunk Feb 20, 2024
4 checks passed
@ZZ-Cat ZZ-Cat deleted the Code-cleanup branch February 20, 2024 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arduino IDE ♾️ This is specific to the Arduino IDE ...in progress 🚧 Development on this is in progress PlatformIO 👽 This is specific to PlatformIO.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

1 participant