prepare release 0.8.6

This commit is contained in:
Wastl Kraus 2025-09-27 14:59:23 +02:00
parent d899ba1471
commit eb5b469dd0
5 changed files with 88 additions and 177 deletions

View File

@ -2,7 +2,13 @@
[![Arduino CI](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml/badge.svg)](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml)
A C++ library for generating DShot signals on ESP32 microcontrollers using the **modern ESP-IDF 5 RMT encoder API** (`rmt_tx.h` / `rmt_rx.h`). It leverages the standard `rmt_bytes_encoder` to ensure an efficient, hardware-timed, and maintainable implementation. **Note:** A byte-swapping fix has been implemented to address endianness differences when using `rmt_bytes_encoder` on ESP32. The library provides a simple way to control brushless motors in both Arduino and ESP-IDF projects. The legacy version using the old `rmt.h` API is available in the `oldAPI` branch.
A C++ library for generating DShot signals on ESP32 microcontrollers using the **modern ESP-IDF 5 RMT encoder API** (`rmt_tx.h` / `rmt_rx.h`). This library specifically leverages the official `rmt_bytes_encoder` API for an efficient, hardware-timed, and maintainable implementation. It provides a simple way to control brushless motors in both Arduino and ESP-IDF projects. The legacy version using the old `rmt.h` API is available in the `oldAPI` branch.
### DShot300 Example Output
Here's an example of the output from the `dshot300` example sketch:
![DShot300 Example Output](img/dshot300.png)
## 🚀 Core Features
@ -14,6 +20,17 @@ A C++ library for generating DShot signals on ESP32 microcontrollers using the *
- **Efficient and Lightweight:** The core library has no external dependencies.
- **Arduino and ESP-IDF Compatible:** Can be used in both Arduino and ESP-IDF projects.
## ⏱️ DShot Timing Information
The DShot protocol defines specific timing characteristics for each mode. The following table outlines the bit length, T1H (high time for a '1' bit), T0H (high time for a '0' bit), and frame length for the supported DShot modes:
| DShot Mode | Bit Length (µs) | T1H Length (µs) | T0H Length (µs) | Frame Length (µs) |
| :--------- | :-------------- | :-------------- | :-------------- | :---------------- |
| DSHOT150 | 6.67 | 5.00 | 2.50 | 106.72 |
| DSHOT300 | 3.33 | 2.50 | 1.25 | 53.28 |
| DSHOT600 | 1.67 | 1.25 | 0.625 | 26.72 |
| DSHOT1200 | 0.83 | 0.67 | 0.335 | 13.28 |
## 📦 Installation
### Arduino IDE
@ -105,15 +122,24 @@ lib_deps =
The main class is `DShotRMT`. Here are the most important methods:
- `DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional = false, uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT)`: Constructor to create a new DShotRMT instance. (Note: Bidirectional DShot is currently not officially supported.)
- `begin()`: Initializes the RMT peripheral and the DShot encoder.
- `sendThrottlePercent(float percent)`: Sends a throttle value as a percentage (0.0-100.0).
- `sendThrottle(uint16_t throttle)`: Sends a raw throttle value (48-2047) to the motor.
- `sendCommand(uint16_t command)`: Sends a DShot command (0-47) to the motor.
- `getTelemetry(uint16_t magnet_count)`: Receives and parses telemetry data from the motor (for bidirectional DShot, which is currently not officially supported).
- `printDShotResult(dshot_result_t &result, Stream &output = Serial)`: Helper function to print DShot operation results and telemetry to a specified serial output.
- `DShotRMT::printDShotInfo(const DShotRMT &dshot_rmt, Stream &output = Serial)`: Static helper function to print detailed DShot signal information for a given DShotRMT instance.
- `DShotRMT::printCpuInfo(Stream &output = Serial)`: Static helper function to print detailed CPU information.
- `DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional = false, uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT)`: Constructor to create a new DShotRMT instance.
- `begin()`: Initializes the DShot RMT channels and encoder.
- `sendThrottlePercent(float percent)`: Sends a throttle value as a percentage (0.0-100.0) to the ESC.
- `sendThrottle(uint16_t throttle)`: Sends a raw throttle value (48-2047) to the ESC. A value of 0 sends a motor stop command.
- `sendCommand(uint16_t command)`: Sends a single DShot command (0-47) to the ESC.
- `sendCommand(dshotCommands_e dshot_command, uint16_t repeat_count = DEFAULT_CMD_REPEAT_COUNT, uint16_t delay_us = DEFAULT_CMD_DELAY_US)`: Sends a DShot command multiple times with a delay between repetitions. This is a blocking function.
- `getTelemetry(uint16_t magnet_count = 0)`: Retrieves telemetry data from the ESC. If `magnet_count` is 0, uses the stored motor magnet count.
- `getESCInfo()`: Sends a command to the ESC to request ESC information.
- `setMotorSpinDirection(bool reversed)`: Sets the motor spin direction. `true` for reversed, `false` for normal.
- `saveESCSettings()`: Sends a command to the ESC to save its current settings. Use with caution as this writes to ESC's non-volatile memory.
- `printDShotResult(dshot_result_t &result, Stream &output = Serial)`: Prints the result of a DShot operation to the specified output stream.
- `DShotRMT::printDShotInfo(const DShotRMT &dshot_rmt, Stream &output = Serial)`: Prints detailed DShot signal information for a given DShotRMT instance.
- `DShotRMT::printCpuInfo(Stream &output = Serial)`: Prints detailed CPU information.
- `setMotorMagnetCount(uint16_t magnet_count)`: Sets the motor magnet count for RPM calculation.
- `getMode()`: Gets the current DShot mode.
- `isBidirectional()`: Checks if bidirectional DShot is enabled.
- `getEncodedFrameValue()`: Gets the last encoded DShot frame value.
- `getThrottleValue()`: Gets the last transmitted throttle value.
## 🤝 Contributing

View File

@ -15,153 +15,75 @@
#include <driver/rmt_rx.h>
#include <atomic>
/**
* @brief DShotRMT Main Class for DShot signal generation and reception.
*
* This class provides an interface to generate DShot signals for Electronic Speed Controllers (ESCs)
* and to receive telemetry data using the ESP32's RMT peripheral.
*/
// Main class for DShot signal generation and reception.
// This class provides an interface to generate DShot signals for Electronic Speed Controllers (ESCs)
// and to receive telemetry data using the ESP32's RMT peripheral.
class DShotRMT
{
public:
/**
* @brief Constructor for DShotRMT with GPIO number.
* @param gpio The GPIO pin number to use for DShot communication.
* @param mode The DShot mode (e.g., DSHOT150, DSHOT300, DSHOT600).
* @param is_bidirectional True if bidirectional DShot is enabled, false otherwise.
* @param magnet_count The number of magnets in the motor for RPM calculation.
*/
// Constructor for DShotRMT with GPIO number.
explicit DShotRMT(gpio_num_t gpio = GPIO_NUM_16, dshot_mode_t mode = dshot_mode_t::DSHOT300, bool is_bidirectional = false, uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT);
/**
* @brief Constructor for DShotRMT with Arduino pin number.
* @param pin_nr The Arduino pin number to use for DShot communication.
* @param mode The DShot mode (e.g., DSHOT150, DSHOT300, DSHOT600).
* @param is_bidirectional True if bidirectional DShot is enabled, false otherwise.
* @param magnet_count The number of magnets in the motor for RPM calculation.
*/
// 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);
/**
* @brief Destructor for DShotRMT.
* Cleans up RMT channels and encoder resources.
*/
// Destructor for DShotRMT.
// Cleans up RMT channels and encoder resources.
~DShotRMT();
// Public Core Functions
/**
* @brief Initializes the DShot RMT channels and encoder.
* @return dshot_result_t indicating success or failure of the initialization.
*/
// Initializes the DShot RMT channels and encoder.
dshot_result_t begin();
/**
* @brief Sends a DShot throttle value to the ESC.
* @param throttle The throttle value (48-2047). A value of 0 sends a motor stop command.
* @return dshot_result_t indicating success or failure of the transmission.
*/
// Sends a DShot throttle value to the ESC.
dshot_result_t sendThrottle(uint16_t throttle);
/**
* @brief Sends a DShot throttle value as a percentage to the ESC.
* @param percent The throttle percentage (0.0f - 100.0f).
* @return dshot_result_t indicating success or failure of the transmission.
*/
// Sends a DShot throttle value as a percentage to the ESC.
dshot_result_t sendThrottlePercent(float percent);
/**
* @brief Sends a single DShot command to the ESC.
* @param command The DShot command value (0-47).
* @return dshot_result_t indicating success or failure of the transmission.
*/
// Sends a single DShot command to the ESC.
dshot_result_t sendCommand(uint16_t command);
/**
* @brief Sends a DShot command multiple times with a delay between repetitions. This is a blocking function.
* @param dshot_command The DShot command to send.
* @param repeat_count The number of times to repeat the command.
* @param delay_us The delay in microseconds between repetitions.
* @return dshot_result_t indicating success or failure of the transmission.
*/
// Sends a DShot command multiple times with a delay between repetitions. This is a blocking function.
dshot_result_t sendCommand(dshotCommands_e dshot_command, uint16_t repeat_count = DEFAULT_CMD_REPEAT_COUNT, uint16_t delay_us = DEFAULT_CMD_DELAY_US);
/**
* @brief Retrieves telemetry data from the ESC.
* @param magnet_count The number of magnets in the motor. If 0, uses the stored motor_magnet_count.
* @return dshot_result_t containing telemetry data (eRPM, motor RPM) if successful.
*/
// Retrieves telemetry data from the ESC.
dshot_result_t getTelemetry(uint16_t magnet_count = 0);
/**
* @brief Sends a command to the ESC to request ESC information.
* @return dshot_result_t indicating success or failure of the command transmission.
*/
// Sends a command to the ESC to request ESC information.
dshot_result_t getESCInfo();
/**
* @brief Sets the motor spin direction.
* @param reversed True for reversed direction, false for normal.
* @return dshot_result_t indicating success or failure of the command transmission.
*/
// Sets the motor spin direction.
dshot_result_t setMotorSpinDirection(bool reversed);
/**
* @brief Sends a command to the ESC to save its current settings.
* Use with caution as this writes to ESC's non-volatile memory.
* @return dshot_result_t indicating success or failure of the command transmission.
*/
// Sends a command to the ESC to save its current settings.
// Use with caution as this writes to ESC's non-volatile memory.
dshot_result_t saveESCSettings();
// Public Utility & Info Functions
/**
* @brief Prints detailed DShot signal information for a given DShotRMT instance.
* @param dshot_rmt The DShotRMT instance to get information from.
* @param output The output stream (e.g., Serial) to print to. Defaults to Serial.
*/
// Prints detailed DShot signal information for a given DShotRMT instance.
static void printDShotInfo(const DShotRMT &dshot_rmt, Stream &output = Serial);
/**
* @brief Prints detailed CPU information.
* @param output The output stream (e.g., Serial) to print to. Defaults to Serial.
*/
// Prints detailed CPU information.
static void printCpuInfo(Stream &output = Serial);
/**
* @brief Sets the motor magnet count for RPM calculation.
* @param magnet_count The number of magnets in the motor.
*/
// Sets the motor magnet count for RPM calculation.
void setMotorMagnetCount(uint16_t magnet_count);
/**
* @brief Gets the current DShot mode.
* @return The current dshot_mode_t.
*/
// Gets the current DShot mode.
dshot_mode_t getMode() const { return _mode; }
/**
* @brief Checks if bidirectional DShot is enabled.
* @return True if bidirectional DShot is enabled, false otherwise.
*/
// Checks if bidirectional DShot is enabled.
bool isBidirectional() const { return _is_bidirectional; }
/**
* @brief Gets the last encoded DShot frame value.
* @return The 16-bit encoded DShot frame value.
*/
// Gets the last encoded DShot frame value.
uint16_t getEncodedFrameValue() const { return _encoded_frame_value; }
/**
* @brief Gets the last transmitted throttle value.
* @return The last transmitted throttle value.
*/
// Gets the last transmitted throttle value.
uint16_t getThrottleValue() const { return _packet.throttle_value; }
// Deprecated Methods
/**
* @brief Deprecated. Use sendThrottle() instead.
* @param throttle The throttle value.
* @return True on success, false on failure.
*/
// Deprecated. Use sendThrottle() instead.
[[deprecated("Use sendThrottle() instead")]]
bool setThrottle(uint16_t throttle)
{
@ -169,11 +91,7 @@ public:
return result.success;
}
/**
* @brief Deprecated. Use sendCommand() instead.
* @param command The DShot command.
* @return True on success, false on failure.
*/
// Deprecated. Use sendCommand() instead.
[[deprecated("Use sendCommand() instead")]]
bool sendDShotCommand(uint16_t command)
{
@ -181,11 +99,7 @@ public:
return result.success;
}
/**
* @brief Deprecated. Use getTelemetry() instead.
* @param magnet_count The number of magnets in the motor.
* @return The motor RPM.
*/
// Deprecated. Use getTelemetry() instead.
[[deprecated("Use getTelemetry() instead")]]
uint32_t getMotorRPM(uint8_t magnet_count)
{

View File

@ -6,10 +6,7 @@
#include <driver/rmt_rx.h>
#include <atomic> // Added for std::atomic
/**
* @brief DShot Modes
* Defines the available DShot communication speeds.
*/
// Defines the available DShot communication speeds.
enum class dshot_mode_t
{
DSHOT_OFF,
@ -19,44 +16,32 @@ enum class dshot_mode_t
DSHOT1200
};
/**
* @brief DShot Packet Structure
* Represents the 16-bit DShot data packet sent to the ESC.
*/
// Represents the 16-bit DShot data packet sent to the ESC.
typedef struct dshot_packet
{
uint16_t throttle_value : 11; ///< 11-bit throttle value or command.
bool telemetric_request : 1; ///< 1-bit telemetry request flag.
uint16_t checksum : 4; ///< 4-bit CRC checksum.
uint16_t throttle_value : 11; // 11-bit throttle value or command.
bool telemetric_request : 1; // 1-bit telemetry request flag.
uint16_t checksum : 4; // 4-bit CRC checksum.
} dshot_packet_t;
/**
* @brief DShot Timing Configuration
* Defines the bit length and high time for a '1' bit in microseconds for each DShot mode.
*/
// Defines the bit length and high time for a '1' bit in microseconds for each DShot mode.
typedef struct dshot_timing
{
double bit_length_us; ///< Total duration of one bit in microseconds.
double t1h_lenght_us; ///< High time duration for a '1' bit in microseconds.
double bit_length_us; // Total duration of one bit in microseconds.
double t1h_lenght_us; // High time duration for a '1' bit in microseconds.
} dshot_timing_us_t;
/**
* @brief RMT Timing Configuration
* Stores pre-calculated timing values in RMT ticks for efficient signal generation.
*/
// Stores pre-calculated timing values in RMT ticks for efficient signal generation.
typedef struct rmt_ticks
{
uint16_t bit_length_ticks; ///< Total duration of one bit in RMT ticks.
uint16_t t1h_ticks; ///< High time duration for a '1' bit in RMT ticks.
uint16_t t1l_ticks; ///< Low time duration for a '1' bit in RMT ticks.
uint16_t t0h_ticks; ///< High time duration for a '0' bit in RMT ticks.
uint16_t t0l_ticks; ///< Low time duration for a '0' bit in RMT ticks.
uint16_t bit_length_ticks; // Total duration of one bit in RMT ticks.
uint16_t t1h_ticks; // High time duration for a '1' bit in RMT ticks.
uint16_t t1l_ticks; // Low time duration for a '1' bit in RMT ticks.
uint16_t t0h_ticks; // High time duration for a '0' bit in RMT ticks.
uint16_t t0l_ticks; // Low time duration for a '0' bit in RMT ticks.
} rmt_ticks_t;
/**
* @brief DShot Error Codes
* Enum class for specific error and success codes returned by DShotRMT functions.
*/
// Enum class for specific error and success codes returned by DShotRMT functions.
enum class dshot_msg_code_t
{
DSHOT_ERROR_NONE = 0,
@ -86,22 +71,16 @@ enum class dshot_msg_code_t
DSHOT_ERROR_COMMAND_SUCCESS
};
/**
* @brief Unified DShot Result Structure
* Contains the success status, an error code, and optional telemetry data.
*/
// Contains the success status, an error code, and optional telemetry data.
typedef struct dshot_result
{
bool success;
dshot_msg_code_t error_code; ///< Specific error or success code.
uint16_t erpm; ///< Electrical RPM (eRPM) if telemetry is successful.
uint16_t motor_rpm; ///< Motor RPM if telemetry is successful and magnet count is known.
dshot_msg_code_t error_code; // Specific error or success code.
uint16_t erpm; // Electrical RPM (eRPM) if telemetry is successful.
uint16_t motor_rpm; // Motor RPM if telemetry is successful and magnet count is known.
} dshot_result_t;
/**
* @brief DShot Commands
* Enum class for standard DShot commands that can be sent to an ESC.
*/
// Enum class for standard DShot commands that can be sent to an ESC.
enum dshotCommands_e
{
DSHOT_CMD_MOTOR_STOP = 0,
@ -134,14 +113,11 @@ enum dshotCommands_e
DSHOT_CMD_MAX = 47
};
/**
* @brief DShot Command Type Enum
* Defines how DShot commands are sent.
*/
// Defines how DShot commands are sent.
enum class dshotCommandType_e
{
DSHOT_CMD_TYPE_INLINE = 0, ///< Commands sent inline with motor signal (motors must be enabled).
DSHOT_CMD_TYPE_BLOCKING ///< Commands sent in blocking method (motors must be disabled).
DSHOT_CMD_TYPE_INLINE = 0, // Commands sent inline with motor signal (motors must be enabled).
DSHOT_CMD_TYPE_BLOCKING // Commands sent in blocking method (motors must be disabled).
};
// DShot Protocol Constants
@ -219,11 +195,6 @@ const char *const INVALID_COMMAND = "Invalid command!";
const char *const COMMAND_SUCCESS = "DShot command sent successfully";
// Helper Functions
/**
* @brief Prints the result of a DShot operation to the specified output stream.
* @param result The dshot_result_t structure containing the operation's outcome.
* @param output The output stream (e.g., Serial) to print to. Defaults to Serial.
*/
inline void printDShotResult(dshot_result_t &result, Stream &output = Serial)
{
const char *msg_str;

View File

@ -9,7 +9,7 @@
#pragma once
// Web Site Content
static constexpr char index_html[] = R"rawliteral(
const char *index_html = R"rawliteral(
<!DOCTYPE html>
<html lang="de">