more simplifications
This commit is contained in:
parent
a763786fbf
commit
30d87aae4f
|
|
@ -6,5 +6,8 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "src/DShotRMT.h"
|
||||
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
123
src/DShotRMT.h
123
src/DShotRMT.h
|
|
@ -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
|
||||
|
|
@ -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};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue