...update error handling

This commit is contained in:
Wastl Kraus 2025-09-07 13:48:48 +02:00
parent cfca2de4e9
commit feb6f4ecac
6 changed files with 190 additions and 169 deletions

View File

@ -22,7 +22,7 @@ dshot_result_t DShotCommandManager::begin()
{
dshot_result_t result;
result.success = true;
result.error_message = "Success";
result.msg = "Success";
return result;
}
@ -39,7 +39,7 @@ dshot_result_t DShotCommandManager::sendCommandWithDelay(dshot_commands_t comman
if (!isValidCommand(command))
{
result.error_message = "Invalid command";
result.msg = "Invalid command";
return result;
}
@ -53,7 +53,7 @@ dshot_result_t DShotCommandManager::sendCommandWithDelay(dshot_commands_t comman
if (!single_result.success)
{
all_successful = false;
result.error_message = single_result.error_message;
result.msg = single_result.msg;
break;
}
@ -64,12 +64,12 @@ dshot_result_t DShotCommandManager::sendCommandWithDelay(dshot_commands_t comman
}
}
//
//
result.success = all_successful;
if (result.success)
{
result.error_message = "Success";
result.msg = "Success";
}
return result;
@ -194,7 +194,7 @@ dshot_result_t DShotCommandManager::setSilentMode(bool enable)
}
// --- SEQUENCE COMMANDS ---
dshot_result_t DShotCommandManager::executeSequence(const dshot_command_sequence_item_t *sequence, size_t sequence_length)
dshot_result_t DShotCommandManager::executeSequence(const dshot_commandmanager_item_t *sequence, size_t sequence_length)
{
dshot_result_t result = {true, "Success"};
uint64_t total_start_time = esp_timer_get_time();
@ -209,7 +209,7 @@ dshot_result_t DShotCommandManager::executeSequence(const dshot_command_sequence
if (!item_result.success)
{
result.success = false;
result.error_message = item_result.error_message;
result.msg = item_result.msg;
break;
}
@ -229,7 +229,7 @@ dshot_result_t DShotCommandManager::executeSequence(const dshot_command_sequence
dshot_result_t DShotCommandManager::executeInitSequence()
{
// Basic ESC initialization sequence
dshot_command_sequence_item_t init_sequence[] = {
dshot_commandmanager_item_t init_sequence[] = {
{DSHOT_CMD_MOTOR_STOP, 5, 100}, // Stop motor, repeat 5 times, wait 100ms
{DSHOT_CMD_EXTENDED_TELEMETRY_ENABLE, 1, 50}, // Enable telemetry, wait 50ms
{DSHOT_CMD_ESC_INFO, 1, 100} // Request ESC info, wait 100ms
@ -242,7 +242,7 @@ dshot_result_t DShotCommandManager::executeInitSequence()
dshot_result_t DShotCommandManager::executeCalibrationSequence()
{
// Basic ESC calibration sequence
dshot_command_sequence_item_t calibration_sequence[] = {
dshot_commandmanager_item_t calibration_sequence[] = {
{DSHOT_CMD_MOTOR_STOP, 10, 500}, // Ensure motor is stopped
{DSHOT_CMD_SPIN_DIRECTION_NORMAL, 10, 100}, // Set normal spin direction
{DSHOT_CMD_3D_MODE_OFF, 10, 100}, // Disable 3D mode

View File

@ -12,13 +12,13 @@
#include <DShotRMT.h>
#include <dshot_commands.h>
// Command sequence item
// Command item
typedef struct
{
dshot_commands_t command;
uint16_t repeat_count;
uint32_t delay_ms;
} dshot_command_sequence_item_t;
} dshot_commandmanager_item_t;
// Advanced DShot command manager class
class DShotCommandManager
@ -76,7 +76,7 @@ public:
// --- SEQUENCE COMMANDS ---
// Execute a sequence of DShot commands
dshot_result_t executeSequence(const dshot_command_sequence_item_t *sequence, size_t sequence_length);
dshot_result_t executeSequence(const dshot_commandmanager_item_t *sequence, size_t sequence_length);
// Execute ESC initialization sequence
dshot_result_t executeInitSequence();

View File

@ -18,6 +18,36 @@ static constexpr dshot_timing_t DSHOT_TIMINGS[] = {
{16, 8, 6, 2, 3, 5} // DSHOT1200
};
// --- HELPERS ---
void printDShotResult(dshot_result_t &result, Stream &output)
{
if (result.success)
{
output.printf("Staus: SUCCESS - %s\n", result.msg);
}
else
{
output.printf("Status: FAILED - %s\n", result.msg);
}
output.println(" ");
}
//
void printDShotTelemetry(dshot_telemetry_result_t &result, Stream &output)
{
if (result.success)
{
output.printf("Telemetry: eRPM=%u, Motor RPM=%u \n", result.erpm, result.motor_rpm);
}
else
{
output.printf("Telemetry: FAILED - %s\n", result.msg);
}
output.println(" ");
}
// Constructor with GPIO number
DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional)
: _gpio(gpio),
@ -26,11 +56,8 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional)
_frame_timer_us(0),
_timing_config(DSHOT_TIMINGS[mode]),
_last_transmission_time(0),
_last_erpm(0),
_parsed_packet(0),
_packet{0},
_total_transmissions(0),
_failed_transmissions(0),
_rmt_tx_channel(nullptr),
_rmt_rx_channel(nullptr),
_dshot_encoder(nullptr),
@ -98,46 +125,45 @@ DShotRMT::~DShotRMT()
// Init DShotRMT
dshot_result_t DShotRMT::begin()
{
dshot_result_t result = {false, UNKNOWN_ERROR};
uint64_t start_time = esp_timer_get_time();
// Result container
dshot_result_t result = {false, INIT_FAILED};
// Init RX channel first
if (_is_bidirectional)
{
if (!_initRXChannel())
if (!_initRXChannel().success)
{
result.error_message = RX_INIT_FAILED;
_dshot_log(RX_INIT_FAILED);
result.msg = RX_INIT_FAILED;
return result;
}
}
// Init TX channel
if (!_initTXChannel())
if (!_initTXChannel().success)
{
result.error_message = TX_INIT_FAILED;
_dshot_log(TX_INIT_FAILED);
result.msg = TX_INIT_FAILED;
return result;
}
// Init DShot encoder
if (_initDShotEncoder() != DSHOT_OK)
if (!_initDShotEncoder().success)
{
result.error_message = ENCODER_INIT_FAILED;
_dshot_log(ENCODER_INIT_FAILED);
result.msg = ENCODER_INIT_FAILED;
return result;
}
uint64_t end_time = esp_timer_get_time();
result.success = true;
result.error_message = INIT_SUCCESS;
result.msg = INIT_SUCCESS;
return result;
}
// Init RMT TX channel
bool DShotRMT::_initTXChannel()
dshot_result_t DShotRMT::_initTXChannel()
{
// Result container
dshot_result_t result = {false, TX_INIT_FAILED};
// Configure TX channel
_tx_channel_config.gpio_num = _gpio;
_tx_channel_config.clk_src = DSHOT_CLOCK_SRC_DEFAULT;
@ -152,21 +178,33 @@ bool DShotRMT::_initTXChannel()
// Create RMT TX channel
if (rmt_new_tx_channel(&_tx_channel_config, &_rmt_tx_channel) != DSHOT_OK)
{
_dshot_log(TX_INIT_FAILED);
return DSHOT_ERROR;
return result;
}
return (rmt_enable(_rmt_tx_channel) == DSHOT_OK);
//
if (rmt_enable(_rmt_tx_channel) != 0)
{
return result;
}
result.success = true;
result.msg = TX_INIT_SUCCESS;
return result;
}
// Init RMT RX channel
bool DShotRMT::_initRXChannel()
dshot_result_t DShotRMT::_initRXChannel()
{
// Result container
dshot_result_t result = {false, RX_INIT_FAILED};
// Create a queue for RX callback data
_rx_queue = xQueueCreate(RMT_QUEUE_DEPTH, sizeof(rmt_rx_done_event_data_t));
if (_rx_queue == nullptr)
{
return DSHOT_ERROR;
result.msg = RX_BUFFER_FAILED;
return result;
}
// Config RMT RX
@ -182,8 +220,7 @@ bool DShotRMT::_initRXChannel()
// Create RMT RX channel
if (rmt_new_rx_channel(&_rx_channel_config, &_rmt_rx_channel) != DSHOT_OK)
{
_dshot_log(RX_INIT_FAILED);
return DSHOT_ERROR;
return result;
}
// Register RX callback
@ -191,48 +228,64 @@ bool DShotRMT::_initRXChannel()
if (rmt_rx_register_event_callbacks(_rmt_rx_channel, &_rx_event_callbacks, _rx_queue) != DSHOT_OK)
{
_dshot_log(RX_INIT_FAILED);
return DSHOT_ERROR;
result.msg = RX_BUFFER_FAILED;
return result;
}
return (rmt_enable(_rmt_rx_channel) == DSHOT_OK);
//
if (rmt_enable(_rmt_rx_channel) != 0)
{
return result;
}
result.success = true;
result.msg = RX_INIT_SUCCESS;
return result;
}
// Callback for RMT RX
bool IRAM_ATTR DShotRMT::_rmt_rx_done_callback(rmt_channel_handle_t rmt_rx_channel, const rmt_rx_done_event_data_t *edata, void *user_data)
{
// Init RX buffer
QueueHandle_t rx_queue = (QueueHandle_t)user_data;
QueueHandle_t rx_buffer = (QueueHandle_t)user_data;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Copy callback data into RX buffer
xQueueGenericSendFromISR(rx_queue, edata, &xHigherPriorityTaskWoken, queueSEND_TO_BACK);
xQueueGenericSendFromISR(rx_buffer, edata, &xHigherPriorityTaskWoken, queueSEND_TO_BACK);
return (xHigherPriorityTaskWoken == pdTRUE);
}
// Initialize DShot encoder
bool DShotRMT::_initDShotEncoder()
dshot_result_t DShotRMT::_initDShotEncoder()
{
// Result container
dshot_result_t result = {false, ENCODER_INIT_FAILED};
// Create copy encoder configuration
rmt_copy_encoder_config_t encoder_config = {};
// Create encoder instance
if (rmt_new_copy_encoder(&encoder_config, &_dshot_encoder) != DSHOT_OK)
{
_dshot_log(ENCODER_INIT_FAILED);
return DSHOT_ERROR;
return result;
}
return DSHOT_OK;
result.success = true;
result.msg = ENCODER_INIT_SUCCESS;
return result;
}
// Send throttle value
dshot_result_t DShotRMT::sendThrottle(uint16_t throttle)
{
static uint16_t last_throttle = DSHOT_CMD_MOTOR_STOP;
// Result container
dshot_result_t result = {false, UNKNOWN_ERROR};
static uint16_t last_throttle = DSHOT_CMD_MOTOR_STOP;
// Special case: if throttle is 0, use sendCommand() instead
if (throttle == 0)
{
@ -242,8 +295,7 @@ dshot_result_t DShotRMT::sendThrottle(uint16_t throttle)
// Log only if throttle is out of range and different from last time
if ((throttle < DSHOT_THROTTLE_MIN || throttle > DSHOT_THROTTLE_MAX) && throttle != last_throttle)
{
_dshot_log(THROTTLE_NOT_IN_RANGE);
result.error_message = THROTTLE_NOT_IN_RANGE;
result.msg = THROTTLE_NOT_IN_RANGE;
}
// Always store the original throttle value
@ -259,63 +311,67 @@ dshot_result_t DShotRMT::sendThrottle(uint16_t throttle)
// Send DShot command to ESC
dshot_result_t DShotRMT::sendCommand(uint16_t command)
{
// Result container
dshot_result_t result = {false, UNKNOWN_ERROR};
// Validate command is within DShot specification range
if (command < DSHOT_CMD_MOTOR_STOP || command > DSHOT_CMD_MAX)
{
_dshot_log(COMMAND_NOT_VALID);
result.error_message = COMMAND_NOT_VALID;
result.msg = COMMAND_NOT_VALID;
return result;
}
// Build packet and transmit
_packet = _buildDShotPacket(command);
return _sendDShotFrame(_packet);
}
// Get telemetry data with timing and error handling
dshot_telemetry_result_t DShotRMT::getTelemetry(uint8_t magnet_count)
dshot_telemetry_result_t DShotRMT::getTelemetry(uint16_t magnet_count)
{
dshot_telemetry_result_t result = {false, 0, 0, UNKNOWN_ERROR};
// Result container
dshot_telemetry_result_t result = {false, 0, 0, TELEMETRY_FAILED};
// Check if bidirectional mode is enabled
if (!_is_bidirectional)
{
result.error_message = BIDIR_NOT_ENABLED;
_dshot_log(BIDIR_NOT_ENABLED);
result.msg = BIDIR_NOT_ENABLED;
return result;
}
// Get eRPM
uint16_t erpm = getERPM();
uint16_t erpm = _getERPM();
if (erpm == DSHOT_NULL_PACKET)
{
result.error_message = TELEMETRY_TIMEOUT;
return result;
}
// Calculate motor RPM
uint8_t pole_pairs = max(1, magnet_count / 2);
uint32_t motor_rpm = erpm / pole_pairs;
uint8_t pole_pairs = max(1, (magnet_count / 2));
uint32_t motor_rpm = (erpm / pole_pairs);
result.success = true;
result.erpm = erpm;
result.motor_rpm = motor_rpm;
result.error_message = TELEMETRY_SUCCESS;
result.msg = TELEMETRY_SUCCESS;
return result;
}
// Get RPM from ESC (bidirectional mode only) - backward compatibility
uint16_t DShotRMT::getERPM()
uint16_t DShotRMT::_getERPM()
{
static uint16_t last_erpm = 0;
// Result container
dshot_telemetry_result_t result = {false, 0, 0, TELEMETRY_FAILED};
// Check if bidirectional mode is enabled
if (!_is_bidirectional)
{
_dshot_log(BIDIR_NOT_ENABLED);
return _last_erpm;
return last_erpm;
}
// RMT RX event data
@ -327,11 +383,11 @@ uint16_t DShotRMT::getERPM()
// Decode the received symbols if a valid frame was received
if (rx_data.num_symbols > DSHOT_NULL_PACKET)
{
_last_erpm = _decodeDShotFrame(rx_data.received_symbols);
last_erpm = _decodeDShotFrame(rx_data.received_symbols);
}
}
return _last_erpm;
return last_erpm;
}
// Build a complete DShot packet
@ -343,8 +399,6 @@ dshot_packet_t DShotRMT::_buildDShotPacket(const uint16_t value)
// Re-check for valid value
if (value > DSHOT_THROTTLE_MAX)
{
_dshot_log(PACKET_BUILD_ERROR);
// Something is really wrong
return packet;
}
@ -390,7 +444,6 @@ uint16_t DShotRMT::_calculateCRC(const uint16_t data)
dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
{
dshot_result_t result = {false, UNKNOWN_ERROR};
uint64_t start_time = esp_timer_get_time();
// Check timing requirements
if (!_timer_signal())
@ -406,7 +459,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
if (rmt_receive(_rmt_rx_channel, rx_symbols, sizeof(rx_symbols), &_receive_config) != DSHOT_OK)
{
result.error_message = RX_RMT_RECEIVER_ERROR;
result.msg = RECEIVER_FAILED;
return result;
}
}
@ -426,8 +479,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
// Disable RMT RX for sending
if (rmt_disable(_rmt_rx_channel) != DSHOT_OK)
{
result.error_message = RX_RMT_RECEIVER_ERROR;
_dshot_log(RX_RMT_RECEIVER_ERROR);
result.msg = RECEIVER_FAILED;
return result;
}
}
@ -435,8 +487,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
// Perform RMT transmission
if (rmt_transmit(_rmt_tx_channel, _dshot_encoder, tx_symbols, tx_size_bytes, &_transmit_config) != DSHOT_OK)
{
result.error_message = TRANSMITTER_ERROR;
_dshot_log(TRANSMITTER_ERROR);
result.msg = TRANSMISSION_FAILED;
return result;
}
@ -445,18 +496,16 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
{
if (rmt_enable(_rmt_rx_channel) != DSHOT_OK)
{
result.error_message = RX_RMT_RECEIVER_ERROR;
_dshot_log(RX_RMT_RECEIVER_ERROR);
result.msg = RECEIVER_FAILED;
return result;
}
}
// Update timestamp and calculate execution time
_timer_reset();
uint64_t end_time = esp_timer_get_time();
result.success = true;
result.error_message = TRANSMISSION_SUCCESS;
result.msg = TRANSMISSION_SUCCESS;
return result;
}

View File

@ -15,19 +15,20 @@
#include <driver/rmt_rx.h>
// DShot Protocol Constants
constexpr auto DSHOT_THROTTLE_FAILSAFE = 0;
constexpr auto DSHOT_THROTTLE_MIN = 48;
constexpr auto DSHOT_THROTTLE_MAX = 2047;
constexpr auto DSHOT_BITS_PER_FRAME = 16;
constexpr auto DSHOT_SWITCH_TIME = 30; // Time in us between TX and RX
constexpr auto DSHOT_NULL_PACKET = 0b0000000000000000;
constexpr auto DSHOT_RX_TIMEOUT_MS = 2;
static constexpr auto DSHOT_THROTTLE_FAILSAFE = 0;
static constexpr auto DSHOT_THROTTLE_MIN = 48;
static constexpr auto DSHOT_THROTTLE_MAX = 2047;
static constexpr auto DSHOT_BITS_PER_FRAME = 16;
static constexpr auto DSHOT_SWITCH_TIME = 30; // Time in us - add some padding to RX - TX switching
static constexpr auto DSHOT_NULL_PACKET = 0b0000000000000000;
static constexpr auto DSHOT_RX_TIMEOUT_MS = 2; // Never reached, just a timeeout
static constexpr auto GCR_BITS_PER_FRAME = 21; // Number of GCR bits in a DShot answer frame (1 start + 16 data + 4 CRC)
static constexpr auto DEFAULT_MOTOR_MAGNET_COUNT = 14;
// RMT Configuration Constants
constexpr auto DSHOT_CLOCK_SRC_DEFAULT = RMT_CLK_SRC_DEFAULT;
constexpr auto DSHOT_RMT_RESOLUTION = 10 * 1000 * 1000; // 10 MHz resolution
constexpr auto RMT_BUFFER_SIZE = DSHOT_BITS_PER_FRAME;
constexpr auto GCR_BITS_PER_FRAME = 21; // Number of GCR bits in a DShot answer frame (1 start + 16 data + 4 CRC)
constexpr auto RMT_BUFFER_SYMBOLS = 64;
constexpr auto RMT_QUEUE_DEPTH = 1;
@ -36,7 +37,7 @@ constexpr auto RMT_QUEUE_DEPTH = 1;
constexpr uint32_t DSHOT_PULSE_MIN = 3000;
constexpr uint32_t DSHOT_PULSE_MAX = 60000;
// DShot Mode Enumeration
// DShot Modes
typedef enum
{
DSHOT_OFF,
@ -46,7 +47,7 @@ typedef enum
DSHOT1200
} dshot_mode_t;
// DShot Packet Structure
// DShot Packet
typedef struct
{
uint16_t throttle_value : 11;
@ -54,7 +55,7 @@ typedef struct
uint16_t checksum : 4;
} dshot_packet_t;
// DShot Timing Configuration Structure
// DShot Timing Configuration
typedef struct
{
uint32_t frame_length_us;
@ -65,25 +66,29 @@ typedef struct
uint16_t ticks_zero_low;
} dshot_timing_t;
// Command execution result structure
// Error handling
typedef struct
{
bool success;
const char *error_message;
const char *msg;
} dshot_result_t;
// DShot telemetry result structure
// DShot telemetry result
typedef struct
{
bool success;
uint16_t erpm;
uint32_t motor_rpm;
const char *error_message;
uint16_t motor_rpm;
const char *msg;
} dshot_telemetry_result_t;
// Naming convention
typedef dshotCommands_e dshot_commands_t;
// --- HELPERS ---
void printDShotResult(dshot_result_t &result, Stream &output = Serial);
void printDShotTelemetry(dshot_telemetry_result_t &result, Stream &output = Serial);
//
class DShotRMT
{
@ -106,21 +111,12 @@ public:
// Send DShot command (0-47)
dshot_result_t sendCommand(uint16_t command);
// Get telemetry data (bidirectional mode only)
dshot_telemetry_result_t getTelemetry(uint8_t magnet_count = 14);
// Get eRPM only (bidirectional mode only)
uint16_t getERPM();
// --- GETTERS ---
gpio_num_t getGPIO() const { return _gpio; }
uint16_t getDShotPacket() const { return _parsed_packet; }
bool is_bidirectional() const { return _is_bidirectional; }
dshot_mode_t getMode() const { return _mode; }
// Get execution statistics
uint32_t getTotalTransmissions() const { return _total_transmissions; }
uint32_t getFailedTransmissions() const { return _failed_transmissions; }
dshot_telemetry_result_t getTelemetry(uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT);
// --- INFO ---
void printDShotInfo(Stream &output = Serial) const;
@ -158,7 +154,6 @@ private:
// --- TIMING & STATE VARIABLES ---
uint64_t _last_transmission_time;
uint16_t _last_erpm;
uint16_t _parsed_packet;
dshot_packet_t _packet;
@ -178,9 +173,9 @@ private:
rmt_receive_config_t _receive_config;
// --- INITS ---
bool _initTXChannel();
bool _initRXChannel();
bool _initDShotEncoder();
dshot_result_t _initTXChannel();
dshot_result_t _initRXChannel();
dshot_result_t _initDShotEncoder();
// --- PACKET MANAGEMENT ---
dshot_packet_t _buildDShotPacket(const uint16_t value);
@ -192,6 +187,9 @@ private:
bool IRAM_ATTR _encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols);
uint16_t _decodeDShotFrame(const rmt_symbol_word_t *symbols);
// --- HELPERS ---
uint16_t _getERPM();
// --- TIMING CONTROL ---
bool IRAM_ATTR _timer_signal();
bool _timer_reset();
@ -204,27 +202,27 @@ private:
// --- DSHOT DEFAULTS ---
static constexpr auto DSHOT_TELEMETRY_INVALID = (0xffff);
// --- ERROR HANDLING & LOGGING ---
void _dshot_log(const char *msg, Stream &output = Serial) const { output.println(msg); }
// --- CONSTANTS & ERROR MESSAGES ---
static constexpr bool DSHOT_OK = 0;
static constexpr bool DSHOT_ERROR = 1;
static constexpr char *NEW_LINE = " ";
static constexpr char *NONE = "";
static constexpr char *UNKNOWN_ERROR = "Unknown Error!";
static constexpr char *TX_INIT_FAILED = "Failed to initialize TX channel!";
static constexpr char *RX_INIT_FAILED = "Failed to initialize RX channel!";
static constexpr char *ENCODER_INIT_FAILED = "Failed to initialize DShot encoder!";
static constexpr char *CRC_CHECK_FAILED = "RX CRC Check failed!";
static constexpr char *THROTTLE_NOT_IN_RANGE = "Throttle value not in range (48 - 2047)!";
static constexpr char *COMMAND_NOT_VALID = "Not a valid DShot Command (0 - 47)!";
static constexpr char *BIDIR_NOT_ENABLED = "Bidirectional DShot support not enabled!";
static constexpr char *RX_RMT_RECEIVER_ERROR = "RX RMT receiver error!";
static constexpr char *PACKET_BUILD_ERROR = "Value too big for DShot Packet!";
static constexpr char *TRANSMITTER_ERROR = "RMT TX Transmitter Error!";
static constexpr char *INIT_SUCCESS = "DShotRMT initialized successfully";
static constexpr char *TELEMETRY_SUCCESS = "Telemetry read successfully";
static constexpr char *TELEMETRY_TIMEOUT = "Telemetry read timeout";
static constexpr char *TRANSMISSION_SUCCESS = "Transmission successful";
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 *RX_BUFFER_FAILED = "RX RMT buffer 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 *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 *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!";
};

View File

@ -37,7 +37,7 @@ void printTelemetryResult(const dshot_telemetry_result_t &result)
}
else
{
USB_SERIAL.printf("Telemetry: FAILED - %s\n", result.error_message);
USB_SERIAL.printf("Telemetry: FAILED - %s\n", result.msg);
}
}
@ -270,7 +270,7 @@ void printResult(const dshot_result_t &result)
}
else
{
USB_SERIAL.printf("FAILED - %s \n", result.error_message);
USB_SERIAL.printf("FAILED - %s \n", result.msg);
}
}

View File

@ -53,7 +53,7 @@ void loop()
static bool continuous_throttle = true;
// Time Measurement
static uint32_t last_stats_print = 0;
static uint64_t last_stats_print = 0;
// Handle serial input
if (USB_SERIAL.available() > 0)
@ -73,23 +73,24 @@ void loop()
motor01.sendThrottle(throttle);
}
// Print motor stats every 5 seconds in continuous mode
if (continuous_throttle && (millis() - last_stats_print >= 5000))
// Print motor stats every 3 seconds in continuous mode
if (continuous_throttle && (esp_timer_get_time() - last_stats_print >= 3000000))
{
motor01.printDShotInfo();
USB_SERIAL.println(" ");
USB_SERIAL.println("Type 'help' to show Menu");
// Get Motor RPM if bidirectional
if (IS_BIDIRECTIONAL)
{
dshot_telemetry_result_t telem_result = motor01.getTelemetry(MOTOR01_MAGNET_COUNT);
printTelemetryResult(telem_result);
printDShotTelemetry(telem_result);
}
USB_SERIAL.println("Type 'help' to show Menu");
// Time Stamp
last_stats_print = millis();
last_stats_print = esp_timer_get_time();
}
}
@ -114,32 +115,6 @@ void printMenu()
USB_SERIAL.println("*******************************************");
}
// Helper to print command results
void printCommandResult(const dshot_result_t &result, const String &operation)
{
if (result.success)
{
USB_SERIAL.printf("%s: SUCCESS\n", operation.c_str());
}
else
{
USB_SERIAL.printf("%s: FAILED - %s\n", operation.c_str(), result.error_message);
}
}
// Helper to print telemetry results
void printTelemetryResult(const dshot_telemetry_result_t &result)
{
if (result.success)
{
USB_SERIAL.printf("Telemetry: eRPM=%u, Motor RPM=%u (%s)\n", result.erpm, result.motor_rpm, result.error_message);
}
else
{
USB_SERIAL.printf("Telemetry: FAILED - %s\n", result.error_message);
}
}
//
void handleSerialInput(const String &input, uint16_t &throttle, bool &continuous_throttle)
{
@ -149,17 +124,16 @@ void handleSerialInput(const String &input, uint16_t &throttle, bool &continuous
throttle = 0;
continuous_throttle = true; // kill motor for sure
dshot_result_t result = motor01.sendCommand(DSHOT_CMD_MOTOR_STOP);
printCommandResult(result, "Stop Motor");
printDShotResult(result);
}
else if (input == "info")
{
continuous_throttle = false;
motor01.printDShotInfo();
}
else if (input == "rpm" && IS_BIDIRECTIONAL)
{
dshot_telemetry_result_t result = motor01.getTelemetry(MOTOR01_MAGNET_COUNT);
printTelemetryResult(result);
printDShotTelemetry(result);
}
else if (input.startsWith("cmd "))
{
@ -171,7 +145,7 @@ void handleSerialInput(const String &input, uint16_t &throttle, bool &continuous
if (cmd_num >= DSHOT_CMD_MOTOR_STOP && cmd_num <= DSHOT_CMD_MAX)
{
dshot_result_t result = motor01.sendCommand(cmd_num);
printCommandResult(result, "DShot Command " + String(cmd_num));
printDShotResult(result);
}
else
{
@ -193,7 +167,7 @@ void handleSerialInput(const String &input, uint16_t &throttle, bool &continuous
continuous_throttle = true;
dshot_result_t result = motor01.sendThrottle(throttle);
printCommandResult(result, "Set Throttle " + String(throttle));
printDShotResult(result);
}
else
{