more simplifications

This commit is contained in:
Wastl Kraus 2025-10-02 00:31:24 +02:00
parent a763786fbf
commit 30d87aae4f
12 changed files with 181 additions and 207 deletions

View File

@ -6,5 +6,8 @@
* @license MIT
*/
#pragma once
#include <Arduino.h>
#include "src/DShotRMT.h"

View File

@ -29,7 +29,7 @@ static constexpr auto IS_BIDIRECTIONAL = false;
// static constexpr auto MOTOR01_MAGNET_COUNT = 14;
// Creates the motor instance
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL);
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL, DEFAULT_MOTOR_MAGNET_COUNT);
//
void setup()

View File

@ -28,7 +28,7 @@ static constexpr auto IS_BIDIRECTIONAL = false;
static constexpr auto MOTOR01_MAGNET_COUNT = 14;
// Creates the motor instance
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL, MOTOR01_MAGNET_COUNT);
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL, DEFAULT_MOTOR_MAGNET_COUNT);
// Forward declaration
void handleSerialInput(const String &input);

View File

@ -20,8 +20,8 @@
#include <WiFi.h>
#include <DShotRMT.h>
#include <ota_update.h>
#include <web_content.h>
#include "web_utilities/ota_update.h"
#include "web_utilities/web_content.h"
#include <ArduinoJson.h>
#include <AsyncTCP.h>
@ -51,7 +51,7 @@ static constexpr auto IS_BIDIRECTIONAL = false; // Note: Bidirectional DShot is
static constexpr auto MOTOR01_MAGNET_COUNT = 14;
// Creates the motor instance
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL);
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL, MOTOR01_MAGNET_COUNT);
// Web Server Configuration
AsyncWebServer server(80);
@ -254,7 +254,8 @@ void setupOTA()
ESP.restart();
} else {
USB_SERIAL.println("OTA Update failed!");
} }, handleOTAUpload);
}
}, handleOTAUpload);
USB_SERIAL.println("OTA Update ready at: /update");
}
@ -344,7 +345,7 @@ void printWiFiStatus()
{
USB_SERIAL.println();
USB_SERIAL.println("***********************************************");
USB_SERIAL.println(" --- WIFI INFO --- ");
USB_SERIAL.println(" --- WIFI INFO ---");
USB_SERIAL.println("***********************************************");
USB_SERIAL.printf("SSID: %s\n", WiFi.SSID().c_str());
USB_SERIAL.printf("IP Address: %s\n", WiFi.localIP().toString().c_str());
@ -393,7 +394,7 @@ void printMenu()
{
USB_SERIAL.println(" ");
USB_SERIAL.println("***********************************************");
USB_SERIAL.println(" --- DShotRMT Web Client Demo --- ");
USB_SERIAL.println(" --- DShotRMT Web Client Demo ---");
USB_SERIAL.println("***********************************************");
if (wifi_connected)

View File

@ -19,7 +19,7 @@
#include <WiFi.h>
#include <DShotRMT.h>
#include <web_content.h>
#include "web_utilities/web_content.h"
#include <ArduinoJson.h>
#include <AsyncTCP.h>
@ -50,7 +50,7 @@ static constexpr auto IS_BIDIRECTIONAL = false; // Note: Bidirectional DShot is
static constexpr auto MOTOR01_MAGNET_COUNT = 14;
// Creates the motor instance
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL);
DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL, MOTOR01_MAGNET_COUNT);
// Web Server Configuration
AsyncWebServer server(80);

View File

@ -6,7 +6,7 @@
* @license MIT
*/
#include <DShotRMT.h>
#include "DShotRMT.h"
// Constructor with GPIO number
DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional, uint16_t magnet_count)
@ -62,6 +62,7 @@ DShotRMT::~DShotRMT()
dshot_result_t DShotRMT::begin()
{
dshot_result_t result = init_rmt_tx_channel(_gpio, &_rmt_tx_channel, _is_bidirectional);
if (!result.success)
{
return result;
@ -81,6 +82,7 @@ dshot_result_t DShotRMT::begin()
}
result = init_dshot_encoder(&_dshot_encoder, _rmt_ticks, _pulse_level, _idle_level);
if (!result.success)
{
// Cleanup previously allocated channels on failure
@ -97,7 +99,7 @@ dshot_result_t DShotRMT::begin()
return result;
}
return {true, dshot_msg_code_t::DSHOT_INIT_SUCCESS};
return {true, DSHOT_INIT_SUCCESS};
}
// Send throttle value
@ -106,7 +108,7 @@ dshot_result_t DShotRMT::sendThrottle(uint16_t throttle)
// A throttle value of 0 is a disarm command
if (throttle == 0)
{
return sendCommand(dshotCommands_e::DSHOT_CMD_MOTOR_STOP);
return sendCommand(DSHOT_CMD_MOTOR_STOP);
}
// Constrain throttle to the valid DShot range
@ -121,7 +123,7 @@ dshot_result_t DShotRMT::sendThrottlePercent(float percent)
{
if (percent < 0.0f || percent > 100.0f)
{
return {false, dshot_msg_code_t::DSHOT_PERCENT_NOT_IN_RANGE};
return {false, DSHOT_PERCENT_NOT_IN_RANGE};
}
// Map percent to DShot throttle range
@ -135,7 +137,7 @@ dshot_result_t DShotRMT::sendCommand(uint16_t command_value)
// Validate the integer command value before casting
if (command_value < DSHOT_CMD_MOTOR_STOP || command_value > DSHOT_CMD_MAX)
{
return {false, dshot_msg_code_t::DSHOT_COMMAND_NOT_VALID};
return {false, DSHOT_COMMAND_NOT_VALID};
}
return sendCommand(static_cast<dshotCommands_e>(command_value));
}
@ -165,11 +167,11 @@ dshot_result_t DShotRMT::sendCommand(dshotCommands_e command)
// Sends a DShot command (0-47) to the ESC with a specified repeat count and delay.
dshot_result_t DShotRMT::sendCommand(dshotCommands_e command, uint16_t repeat_count, uint16_t delay_us)
{
dshot_result_t result = {false, dshot_msg_code_t::DSHOT_UNKNOWN, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY};
dshot_result_t result = {false, DSHOT_UNKNOWN, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY};
if (!_isValidCommand(command))
{
result.result_code = dshot_msg_code_t::DSHOT_INVALID_COMMAND;
result.result_code = DSHOT_INVALID_COMMAND;
return result;
}
@ -198,7 +200,7 @@ dshot_result_t DShotRMT::sendCommand(dshotCommands_e command, uint16_t repeat_co
if (result.success)
{
result.result_code = dshot_msg_code_t::DSHOT_COMMAND_SUCCESS;
result.result_code = DSHOT_COMMAND_SUCCESS;
}
return result;
@ -207,11 +209,11 @@ dshot_result_t DShotRMT::sendCommand(dshotCommands_e command, uint16_t repeat_co
// Get telemetry data
dshot_result_t DShotRMT::getTelemetry()
{
dshot_result_t result = {false, dshot_msg_code_t::DSHOT_TELEMETRY_FAILED, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY};
dshot_result_t result = {false, DSHOT_TELEMETRY_FAILED, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY};
if (!_is_bidirectional)
{
result.result_code = dshot_msg_code_t::DSHOT_BIDIR_NOT_ENABLED;
result.result_code = DSHOT_BIDIR_NOT_ENABLED;
return result;
}
@ -233,7 +235,7 @@ dshot_result_t DShotRMT::getTelemetry()
result.success = true;
result.erpm = erpm;
result.motor_rpm = motor_rpm;
result.result_code = dshot_msg_code_t::DSHOT_TELEMETRY_SUCCESS;
result.result_code = DSHOT_TELEMETRY_SUCCESS;
}
}
@ -275,8 +277,6 @@ dshot_result_t DShotRMT::_executeCommand(dshotCommands_e command)
return result;
}
// Private Packet Management Functions
dshot_packet_t DShotRMT::_buildDShotPacket(const uint16_t &value) const
{
@ -338,7 +338,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
// Ensure enough time has passed since the last transmission
if (!_isFrameIntervalElapsed())
{
return {true, dshot_msg_code_t::DSHOT_NONE};
return {true, DSHOT_NONE};
}
_encoded_frame_value = _buildDShotFrameValue(packet);
@ -355,12 +355,12 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
if (rmt_transmit(_rmt_tx_channel, _dshot_encoder, &swapped_value, tx_size_bytes, &tx_config) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_TRANSMISSION_FAILED};
return {false, DSHOT_TRANSMISSION_FAILED};
}
_recordFrameTransmissionTime(); // Reset the timer for the next frame
return {true, dshot_msg_code_t::DSHOT_TRANSMISSION_SUCCESS};
return {true, DSHOT_TRANSMISSION_SUCCESS};
}
// This function needs to be fast, as it generates the RMT symbols just before sending

View File

@ -1,134 +1,107 @@
/**
* @file DShotRMT.h
* @brief Optimized DShot signal generation using ESP32 RMT with bidirectional support
* @brief DShot signal generation using ESP32 RMT with bidirectional support
* @author Wastl Kraus
* @date 2025-09-18
* @date 2025-06-11
* @license MIT
*/
#pragma once
#include <Arduino.h>
#include <atomic>
#include <driver/gpio.h>
#include <driver/rmt_tx.h>
#include <driver/rmt_rx.h>
#include <atomic>
#include "dshot_definitions.h"
#include <driver/rmt_encoder.h>
#include "dshot_config.h"
// DShotRMT Class Definition
//
class DShotRMT
{
public:
// Constructor for DShotRMT with GPIO number.
explicit DShotRMT(gpio_num_t gpio = GPIO_NUM_16, dshot_mode_t mode = DSHOT300, bool is_bidirectional = false, uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT);
// Constructor with GPIO number
DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional, uint16_t magnet_count);
// Constructor for DShotRMT with Arduino pin number.
DShotRMT(uint16_t pin_nr, dshot_mode_t mode, bool is_bidirectional, uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT);
// Constructor using pin number
DShotRMT(uint16_t pin_nr, dshot_mode_t mode, bool is_bidirectional, uint16_t magnet_count);
// Destructor
~DShotRMT();
// Public Core Functions
// Initializes the DShot RMT channels and encoder.
// Initialize DShotRMT
dshot_result_t begin();
// Sends a throttle value as a percentage (0.0-100.0) to the ESC.
dshot_result_t sendThrottlePercent(float percent);
// Sends a raw throttle value (48-2047) to the ESC. A value of 0 sends a motor stop command.
// Send throttle value
dshot_result_t sendThrottle(uint16_t throttle);
// Sends a DShot command (0-47) to the ESC.
dshot_result_t sendCommand(dshotCommands_e command);
// Sends a DShot command (0-47) to the ESC with a specified repeat count and delay.
dshot_result_t sendCommand(dshotCommands_e command, uint16_t repeat_count, uint16_t delay_us);
// Send throttle value as a percentage
dshot_result_t sendThrottlePercent(float percent);
// Sends a DShot command (0-47) to the ESC by accepting an integer value.
dshot_result_t sendCommand(uint16_t command_value);
// Retrieves telemetry data from the ESC.
// Sends a DShot command (0-47) to the ESC.
dshot_result_t sendCommand(dshotCommands_e command);
// Sends a DShot command (0-47) to the ESC with a specified repeat count and delay.
dshot_result_t sendCommand(dshotCommands_e command, uint16_t repeat_count, uint16_t delay_us);
// Get telemetry data
dshot_result_t getTelemetry();
// Sets the motor spin direction. 'true' for reversed, 'false' for normal.
// Reverse motor direction directly
dshot_result_t setMotorSpinDirection(bool reversed);
// Sends a command to the ESC to save its current settings. Use with caution as this writes to ESC's non-volatile memory.
// Use with caution
dshot_result_t saveESCSettings();
// Public Utility & Info Functions
// Sets the motor magnet count for RPM calculation.
void setMotorMagnetCount(uint16_t magnet_count);
// Gets the current DShot mode.
// Getters for DShot info
dshot_mode_t getMode() const { return _mode; }
// Checks if bidirectional DShot is enabled.
bool isBidirectional() const { return _is_bidirectional; }
// Gets the encoded frame value.
uint16_t getThrottleValue() const { return _last_throttle; }
uint16_t getEncodedFrameValue() const { return _encoded_frame_value; }
// Gets the last transmitted throttle value.
uint16_t getThrottleValue() const { return _packet.throttle_value; }
// Testing return "verbose" messages
const char *getDShotMsg(dshot_result_t &result) const { return (_get_result_code_str(result.result_code)); }
// Deprecated Methods
private:
// --- UTILITY METHODS ---
bool _isValidCommand(dshotCommands_e command) const;
dshot_result_t _executeCommand(dshotCommands_e command);
// Core Configuration Variables
gpio_num_t _gpio;
dshot_mode_t _mode;
bool _is_bidirectional;
uint16_t _motor_magnet_count;
const dshot_timing_us_t &_dshot_timing;
uint64_t _frame_timer_us = 0;
// Timing & Packet Variables
rmt_ticks_t _rmt_ticks{};
uint16_t _last_throttle = dshotCommands_e::DSHOT_CMD_MOTOR_STOP;
uint64_t _last_transmission_time_us = 0;
uint64_t _last_command_timestamp = 0;
uint16_t _encoded_frame_value = 0;
dshot_packet_t _packet{};
uint16_t _pulse_level = 1; // DShot protocol: Signal is idle-low, so pulses start by going HIGH.
uint16_t _idle_level = 0; // DShot protocol: Signal returns to LOW after the high pulse.
// RMT Hardware Handles
dshot_timing_us_t _dshot_timing;
rmt_channel_handle_t _rmt_tx_channel = nullptr;
rmt_channel_handle_t _rmt_rx_channel = nullptr;
rmt_encoder_handle_t _dshot_encoder = nullptr;
rmt_ticks_t _rmt_ticks;
uint16_t _pulse_level = 1; // Default to high
uint16_t _idle_level = 0; // Default to low
uint64_t _last_transmission_time_us = 0;
uint64_t _frame_timer_us = 0;
uint16_t _last_throttle = 0;
dshot_packet_t _packet;
uint16_t _encoded_frame_value = 0;
uint64_t _last_command_timestamp = 0;
// Telemetry related
std::atomic<uint16_t> _last_erpm_atomic = 0;
std::atomic<bool> _telemetry_ready_flag_atomic = false;
rmt_rx_event_callbacks_t _rx_event_callbacks = {
.on_recv_done = _on_rx_done,
};
// Bidirectional / Telemetry Variables
rmt_rx_event_callbacks_t _rx_event_callbacks{};
std::atomic<uint16_t> _last_erpm_atomic{0};
std::atomic<bool> _telemetry_ready_flag_atomic{false};
// Private Packet Management Functions
// Private helper functions
bool _isValidCommand(dshotCommands_e command) const;
dshot_result_t _executeCommand(dshotCommands_e command);
dshot_packet_t _buildDShotPacket(const uint16_t &value) const;
uint16_t _buildDShotFrameValue(const dshot_packet_t &packet) const;
uint16_t _calculateCRC(const uint16_t &data) const;
void _preCalculateRMTTicks();
// Private Frame Processing Functions
dshot_result_t _sendDShotFrame(const dshot_packet_t &packet);
uint16_t _decodeDShotFrame(const rmt_symbol_word_t *symbols) const;
// Private Timing Control Functions
bool _isFrameIntervalElapsed() const;
uint16_t IRAM_ATTR _decodeDShotFrame(const rmt_symbol_word_t *symbols) const;
bool IRAM_ATTR _isFrameIntervalElapsed() const;
void _recordFrameTransmissionTime();
// Static Callback Functions
static bool _on_rx_done(rmt_channel_handle_t rmt_rx_channel, const rmt_rx_done_event_data_t *edata, void *user_data);
static bool IRAM_ATTR _on_rx_done(rmt_channel_handle_t rmt_rx_channel, const rmt_rx_done_event_data_t *edata, void *user_data);
};
// Include utility functions after class definition
#include "dshot_utils.h"
#include "dshot_utils.h" // Workround for util functions

View File

@ -17,15 +17,15 @@ dshot_result_t init_rmt_tx_channel(gpio_num_t gpio, rmt_channel_handle_t *out_ch
if (rmt_new_tx_channel(&tx_channel_config, out_channel) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_TX_INIT_FAILED};
return {false, DSHOT_TX_INIT_FAILED};
}
if (rmt_enable(*out_channel) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_TX_INIT_FAILED};
return {false, DSHOT_TX_INIT_FAILED};
}
return {true, dshot_msg_code_t::DSHOT_TX_INIT_SUCCESS};
return {true, DSHOT_TX_INIT_SUCCESS};
}
// Function to initialize the RMT RX channel
@ -43,19 +43,16 @@ dshot_result_t init_rmt_rx_channel(gpio_num_t gpio, rmt_channel_handle_t *out_ch
.signal_range_max_ns = DSHOT_PULSE_MAX_NS,
};
if (rmt_new_rx_channel(&rx_channel_config, out_channel) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_RX_INIT_FAILED};
}
return {false, DSHOT_RX_INIT_FAILED};
if (rmt_rx_register_event_callbacks(*out_channel, rx_event_callbacks, user_data) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_CALLBACK_REGISTERING_FAILED};
return {false, DSHOT_CALLBACK_REGISTERING_FAILED};
}
if (rmt_enable(*out_channel) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_RX_INIT_FAILED};
return {false, DSHOT_RX_INIT_FAILED};
}
// Start the receiver to wait for incoming telemetry data
@ -63,10 +60,10 @@ dshot_result_t init_rmt_rx_channel(gpio_num_t gpio, rmt_channel_handle_t *out_ch
size_t rx_size_bytes = GCR_BITS_PER_FRAME * sizeof(rmt_symbol_word_t);
if (rmt_receive(*out_channel, rx_symbols, rx_size_bytes, &rmt_rx_config) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_RECEIVER_FAILED};
return {false, DSHOT_RECEIVER_FAILED};
}
return {true, dshot_msg_code_t::DSHOT_RX_INIT_SUCCESS};
return {true, DSHOT_RX_INIT_SUCCESS};
}
// Function to initialize the DShot RMT encoder
@ -91,8 +88,8 @@ dshot_result_t init_dshot_encoder(rmt_encoder_handle_t *out_encoder, const rmt_t
if (rmt_new_bytes_encoder(&encoder_config, out_encoder) != DSHOT_OK)
{
return {false, dshot_msg_code_t::DSHOT_ENCODER_INIT_FAILED};
return {false, DSHOT_ENCODER_INIT_FAILED};
}
return {true, dshot_msg_code_t::DSHOT_ENCODER_INIT_SUCCESS};
return {true, DSHOT_ENCODER_INIT_SUCCESS};
}

View File

@ -43,7 +43,7 @@ typedef struct rmt_ticks
} rmt_ticks_t;
// Enum class for specific error and success codes
enum class dshot_msg_code_t
enum dshot_msg_code_t
{
DSHOT_NONE = 0,
DSHOT_UNKNOWN,
@ -161,90 +161,3 @@ const dshot_timing_us_t DSHOT_TIMING_US[] = {
{0.83, 0.67}, // DSHOT1200
{0.00, 0.00} // DSHOT_MODE_MAX (dummy entry)
};
// Error Messages
static constexpr char NONE[] = "";
static constexpr char UNKNOWN_ERROR[] = "Unknown Error!";
static constexpr char INIT_SUCCESS[] = "SignalGeneratorRMT initialized successfully";
static constexpr char INIT_FAILED[] = "SignalGeneratorRMT init failed!";
static constexpr char TX_INIT_SUCCESS[] = "TX RMT channel initialized successfully";
static constexpr char TX_INIT_FAILED[] = "TX RMT channel init failed!";
static constexpr char RX_INIT_SUCCESS[] = "RX RMT channel initialized successfully";
static constexpr char RX_INIT_FAILED[] = "RX RMT channel init failed!";
static constexpr char ENCODER_INIT_SUCCESS[] = "RMT encoder initialized successfully";
static constexpr char ENCODER_INIT_FAILED[] = "RMT encoder init failed!";
static constexpr char ENCODING_SUCCESS[] = "Packet encoded successfully";
static constexpr char TRANSMISSION_SUCCESS[] = "Transmission successfully";
static constexpr char TRANSMISSION_FAILED[] = "Transmission failed!";
static constexpr char RECEIVER_FAILED[] = "RMT receiver failed!";
static constexpr char THROTTLE_NOT_IN_RANGE[] = "Throttle not in range! (48 - 2047)";
static constexpr char PERCENT_NOT_IN_RANGE[] = "Percent not in range! (0.0 - 100.0)";
static constexpr char COMMAND_NOT_VALID[] = "Command not valid! (0 - 47)";
static constexpr char BIDIR_NOT_ENABLED[] = "Bidirectional DShot not enabled!";
static constexpr char TELEMETRY_SUCCESS[] = "Valid Telemetric Frame received!";
static constexpr char TELEMETRY_FAILED[] = "No valid Telemetric Frame received!";
static constexpr char INVALID_MAGNET_COUNT[] = "Invalid motor magnet count!";
static constexpr char TIMING_CORRECTION[] = "Timing correction!";
static constexpr char CALLBACK_REGISTERING_FAILED[] = "RMT RX Callback registering failed!";
static constexpr char INVALID_COMMAND[] = "Invalid command!";
static constexpr char COMMAND_SUCCESS[] = "DShot command sent successfully";
// Helper to get result code string
inline const char *_get_result_code_str(dshot_msg_code_t code)
{
switch (code)
{
case dshot_msg_code_t::DSHOT_NONE:
return NONE;
case dshot_msg_code_t::DSHOT_UNKNOWN:
return UNKNOWN_ERROR;
case dshot_msg_code_t::DSHOT_TX_INIT_FAILED:
return TX_INIT_FAILED;
case dshot_msg_code_t::DSHOT_RX_INIT_FAILED:
return RX_INIT_FAILED;
case dshot_msg_code_t::DSHOT_ENCODER_INIT_FAILED:
return ENCODER_INIT_FAILED;
case dshot_msg_code_t::DSHOT_CALLBACK_REGISTERING_FAILED:
return CALLBACK_REGISTERING_FAILED;
case dshot_msg_code_t::DSHOT_RECEIVER_FAILED:
return RECEIVER_FAILED;
case dshot_msg_code_t::DSHOT_TRANSMISSION_FAILED:
return TRANSMISSION_FAILED;
case dshot_msg_code_t::DSHOT_THROTTLE_NOT_IN_RANGE:
return THROTTLE_NOT_IN_RANGE;
case dshot_msg_code_t::DSHOT_PERCENT_NOT_IN_RANGE:
return PERCENT_NOT_IN_RANGE;
case dshot_msg_code_t::DSHOT_COMMAND_NOT_VALID:
return COMMAND_NOT_VALID;
case dshot_msg_code_t::DSHOT_BIDIR_NOT_ENABLED:
return BIDIR_NOT_ENABLED;
case dshot_msg_code_t::DSHOT_TELEMETRY_FAILED:
return TELEMETRY_FAILED;
case dshot_msg_code_t::DSHOT_INVALID_MAGNET_COUNT:
return INVALID_MAGNET_COUNT;
case dshot_msg_code_t::DSHOT_INVALID_COMMAND:
return INVALID_COMMAND;
case dshot_msg_code_t::DSHOT_TIMING_CORRECTION:
return TIMING_CORRECTION;
case dshot_msg_code_t::DSHOT_INIT_FAILED:
return INIT_FAILED;
case dshot_msg_code_t::DSHOT_INIT_SUCCESS:
return INIT_SUCCESS;
case dshot_msg_code_t::DSHOT_TX_INIT_SUCCESS:
return TX_INIT_SUCCESS;
case dshot_msg_code_t::DSHOT_RX_INIT_SUCCESS:
return RX_INIT_SUCCESS;
case dshot_msg_code_t::DSHOT_ENCODER_INIT_SUCCESS:
return ENCODER_INIT_SUCCESS;
case dshot_msg_code_t::DSHOT_ENCODING_SUCCESS:
return ENCODING_SUCCESS;
case dshot_msg_code_t::DSHOT_TRANSMISSION_SUCCESS:
return TRANSMISSION_SUCCESS;
case dshot_msg_code_t::DSHOT_TELEMETRY_SUCCESS:
return TELEMETRY_SUCCESS;
case dshot_msg_code_t::DSHOT_COMMAND_SUCCESS:
return COMMAND_SUCCESS;
default:
return UNKNOWN_ERROR;
}
}

View File

@ -3,6 +3,93 @@
#include <Arduino.h>
#include "DShotRMT.h" // Include the full class definition
// Error Messages
static constexpr char NONE[] = "";
static constexpr char UNKNOWN_ERROR[] = "Unknown Error!";
static constexpr char INIT_SUCCESS[] = "SignalGeneratorRMT initialized successfully";
static constexpr char INIT_FAILED[] = "SignalGeneratorRMT init failed!";
static constexpr char TX_INIT_SUCCESS[] = "TX RMT channel initialized successfully";
static constexpr char TX_INIT_FAILED[] = "TX RMT channel init failed!";
static constexpr char RX_INIT_SUCCESS[] = "RX RMT channel initialized successfully";
static constexpr char RX_INIT_FAILED[] = "RX RMT channel init failed!";
static constexpr char ENCODER_INIT_SUCCESS[] = "RMT encoder initialized successfully";
static constexpr char ENCODER_INIT_FAILED[] = "RMT encoder init failed!";
static constexpr char ENCODING_SUCCESS[] = "Packet encoded successfully";
static constexpr char TRANSMISSION_SUCCESS[] = "Transmission successfully";
static constexpr char TRANSMISSION_FAILED[] = "Transmission failed!";
static constexpr char RECEIVER_FAILED[] = "RMT receiver failed!";
static constexpr char THROTTLE_NOT_IN_RANGE[] = "Throttle not in range! (48 - 2047)";
static constexpr char PERCENT_NOT_IN_RANGE[] = "Percent not in range! (0.0 - 100.0)";
static constexpr char COMMAND_NOT_VALID[] = "Command not valid! (0 - 47)";
static constexpr char BIDIR_NOT_ENABLED[] = "Bidirectional DShot not enabled!";
static constexpr char TELEMETRY_SUCCESS[] = "Valid Telemetric Frame received!";
static constexpr char TELEMETRY_FAILED[] = "No valid Telemetric Frame received!";
static constexpr char INVALID_MAGNET_COUNT[] = "Invalid motor magnet count!";
static constexpr char TIMING_CORRECTION[] = "Timing correction!";
static constexpr char CALLBACK_REGISTERING_FAILED[] = "RMT RX Callback registering failed!";
static constexpr char INVALID_COMMAND[] = "Invalid command!";
static constexpr char COMMAND_SUCCESS[] = "DShot command sent successfully";
// Helper to get result code string
inline const char *_get_result_code_str(dshot_msg_code_t code)
{
switch (code)
{
case DSHOT_NONE:
return NONE;
case DSHOT_UNKNOWN:
return UNKNOWN_ERROR;
case DSHOT_TX_INIT_FAILED:
return TX_INIT_FAILED;
case DSHOT_RX_INIT_FAILED:
return RX_INIT_FAILED;
case DSHOT_ENCODER_INIT_FAILED:
return ENCODER_INIT_FAILED;
case DSHOT_CALLBACK_REGISTERING_FAILED:
return CALLBACK_REGISTERING_FAILED;
case DSHOT_RECEIVER_FAILED:
return RECEIVER_FAILED;
case DSHOT_TRANSMISSION_FAILED:
return TRANSMISSION_FAILED;
case DSHOT_THROTTLE_NOT_IN_RANGE:
return THROTTLE_NOT_IN_RANGE;
case DSHOT_PERCENT_NOT_IN_RANGE:
return PERCENT_NOT_IN_RANGE;
case DSHOT_COMMAND_NOT_VALID:
return COMMAND_NOT_VALID;
case DSHOT_BIDIR_NOT_ENABLED:
return BIDIR_NOT_ENABLED;
case DSHOT_TELEMETRY_FAILED:
return TELEMETRY_FAILED;
case DSHOT_INVALID_MAGNET_COUNT:
return INVALID_MAGNET_COUNT;
case DSHOT_INVALID_COMMAND:
return INVALID_COMMAND;
case DSHOT_TIMING_CORRECTION:
return TIMING_CORRECTION;
case DSHOT_INIT_FAILED:
return INIT_FAILED;
case DSHOT_INIT_SUCCESS:
return INIT_SUCCESS;
case DSHOT_TX_INIT_SUCCESS:
return TX_INIT_SUCCESS;
case DSHOT_RX_INIT_SUCCESS:
return RX_INIT_SUCCESS;
case DSHOT_ENCODER_INIT_SUCCESS:
return ENCODER_INIT_SUCCESS;
case DSHOT_ENCODING_SUCCESS:
return ENCODING_SUCCESS;
case DSHOT_TRANSMISSION_SUCCESS:
return TRANSMISSION_SUCCESS;
case DSHOT_TELEMETRY_SUCCESS:
return TELEMETRY_SUCCESS;
case DSHOT_COMMAND_SUCCESS:
return COMMAND_SUCCESS;
default:
return UNKNOWN_ERROR;
}
}
// Helper to quick print DShot result codes
inline void printDShotResult(dshot_result_t &result, Stream &output = Serial)
{