Pause platformio support

...user reports PlatformIO is not nupporting at the moment. Paused support.

hotfix 0.8.7
This commit is contained in:
Wastl Kraus 2025-09-30 20:37:25 +02:00
parent 1a1bbcd7f3
commit 274fc727b2
4 changed files with 52 additions and 62 deletions

View File

@ -2,7 +2,9 @@
[![Arduino CI](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml/badge.svg)](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml) [![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`). 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. An Arduino IDElibrary 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 ### DShot300 Example Output
@ -16,8 +18,8 @@ Here's an example of the output from the `dshot300` example sketch:
- **Bidirectional DShot Support:** Implemented, but note that official support is limited due to potential instability and external hardware requirements. Use with caution. - **Bidirectional DShot Support:** Implemented, but note that official support is limited due to potential instability and external hardware requirements. Use with caution.
- **Hardware-Timed Signals:** Precise signal generation using the ESP32 RMT peripheral, ensuring stable and reliable motor control. - **Hardware-Timed Signals:** Precise signal generation using the ESP32 RMT peripheral, ensuring stable and reliable motor control.
- **Simple API:** Easy-to-use C++ class with intuitive methods like `sendThrottlePercent()`. - **Simple API:** Easy-to-use C++ class with intuitive methods like `sendThrottlePercent()`.
- **Robust Error Handling:** Provides detailed feedback on operation success or failure via `dshot_result_t`. - **Error Handling:** Provides detailed feedback on operation success or failure via `dshot_result_t`.
- **Efficient and Lightweight:** The core library has no external dependencies. - **Lightweight:** The core library has no external dependencies.
- **Arduino and ESP-IDF Compatible:** Can be used in both Arduino and ESP-IDF projects. - **Arduino and ESP-IDF Compatible:** Can be used in both Arduino and ESP-IDF projects.
## ⏱️ DShot Timing Information ## ⏱️ DShot Timing Information
@ -39,18 +41,9 @@ The DShot protocol defines specific timing characteristics for each mode. The fo
2. Search for "DShotRMT" and click "Install". 2. Search for "DShotRMT" and click "Install".
3. Alternatively, you can clone this repository or download it as a ZIP file and place it in your Arduino libraries folder (`~/Arduino/libraries/DShotRMT/`). 3. Alternatively, you can clone this repository or download it as a ZIP file and place it in your Arduino libraries folder (`~/Arduino/libraries/DShotRMT/`).
### PlatformIO
Add the following to your `platformio.ini` file:
```ini
lib_deps =
https://github.com/derdoktor667/DShotRMT.git
```
## ⚡ Quick Start ## ⚡ Quick Start
Here's a basic example of how to use the `DShotRMT` library to control a motor: Here's a basic example of how to use the `DShotRMT` library to control a motor. Please use example sketches for more detailes:
```cpp ```cpp
#include <Arduino.h> #include <Arduino.h>
@ -73,6 +66,9 @@ void setup() {
Serial.println("Motor initialized. Ramping up to 25% throttle..."); Serial.println("Motor initialized. Ramping up to 25% throttle...");
}
void loop() {
// Ramp up to 25% throttle over 2.5 seconds // Ramp up to 25% throttle over 2.5 seconds
for (int i = 0; i <= 25; i++) { for (int i = 0; i <= 25; i++) {
motor.sendThrottlePercent(i); motor.sendThrottlePercent(i);
@ -85,10 +81,6 @@ void setup() {
// Print DShot Info // Print DShot Info
DShotRMT::printDShotInfo(motor, Serial); DShotRMT::printDShotInfo(motor, Serial);
} }
void loop() {
// Your main code here
}
``` ```
## 🎮 Examples ## 🎮 Examples

View File

@ -1,5 +1,5 @@
name=DShotRMT name=DShotRMT
version=0.8.6 version=0.8.7
author=Wastl Kraus <wir-sind-die-matrix.de> author=Wastl Kraus <wir-sind-die-matrix.de>
maintainer=Wastl Kraus <wir-sind-die-matrix.de> maintainer=Wastl Kraus <wir-sind-die-matrix.de>
license=MIT license=MIT

View File

@ -24,7 +24,7 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional, ui
_encoded_frame_value(0), _encoded_frame_value(0),
_packet{0}, _packet{0},
_pulse_level(1), // DShot standard: signal is idle-low, so pulses start by going HIGH _pulse_level(1), // DShot standard: signal is idle-low, so pulses start by going HIGH
_idle_level(0), // DShot standard: signal returns to LOW after the high pulse _idle_level(0), // DShot standard: signal returns to LOW after the high pulse
_rmt_tx_channel(nullptr), _rmt_tx_channel(nullptr),
_rmt_rx_channel(nullptr), _rmt_rx_channel(nullptr),
_dshot_encoder(nullptr), _dshot_encoder(nullptr),

View File

@ -41,7 +41,7 @@ typedef struct rmt_ticks
uint16_t t0l_ticks; // Low 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; } rmt_ticks_t;
// Enum class for specific error and success codes returned by DShotRMT functions. // Enum class for specific error and success codes
enum class dshot_msg_code_t enum class dshot_msg_code_t
{ {
DSHOT_NONE = 0, DSHOT_NONE = 0,
@ -76,11 +76,11 @@ typedef struct dshot_result
{ {
bool success; bool success;
dshot_msg_code_t result_code; // Specific error or success code. dshot_msg_code_t result_code; // Specific error or success code.
uint16_t erpm; // Electrical RPM (eRPM) if telemetry is successful. 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. uint16_t motor_rpm; // Motor RPM if telemetry is successful and magnet count is known.
} dshot_result_t; } dshot_result_t;
// Standard DShot commands (regular enum for easier handling as per project conventions). // Standard DShot commands by "betaflight"
enum dshotCommands_e enum dshotCommands_e
{ {
DSHOT_CMD_MOTOR_STOP = 0, DSHOT_CMD_MOTOR_STOP = 0,
@ -113,53 +113,51 @@ enum dshotCommands_e
DSHOT_CMD_MAX = 47 DSHOT_CMD_MAX = 47
}; };
// --- Type-Safe Constants ---
// DShot Protocol Constants // DShot Protocol Constants
static constexpr uint16_t DSHOT_THROTTLE_FAILSAFE = 0; static constexpr auto DSHOT_THROTTLE_FAILSAFE = 0;
static constexpr uint16_t DSHOT_THROTTLE_MIN = 48; static constexpr auto DSHOT_THROTTLE_MIN = 48;
static constexpr uint16_t DSHOT_THROTTLE_MAX = 2047; static constexpr auto DSHOT_THROTTLE_MAX = 2047;
static constexpr uint16_t DSHOT_BITS_PER_FRAME = 16; static constexpr auto DSHOT_BITS_PER_FRAME = 16;
static constexpr uint16_t DEFAULT_MOTOR_MAGNET_COUNT = 14; static constexpr auto DEFAULT_MOTOR_MAGNET_COUNT = 14;
// Custom status codes // Custom status codes
static constexpr int DSHOT_OK = 0; static constexpr int DSHOT_OK = 0;
static constexpr int DSHOT_ERROR = 1; static constexpr int DSHOT_ERROR = 1;
// Configuration Constants // Configuration Constants
static constexpr uint16_t DSHOT_NULL_PACKET = 0b0000000000000000; static constexpr auto DSHOT_NULL_PACKET = 0b0000000000000000;
static constexpr uint16_t DSHOT_FULL_PACKET = 0b1111111111111111; static constexpr auto DSHOT_FULL_PACKET = 0b1111111111111111;
static constexpr uint16_t DSHOT_CRC_MASK = 0b0000000000001111; static constexpr auto DSHOT_CRC_MASK = 0b0000000000001111;
static constexpr rmt_clock_source_t DSHOT_CLOCK_SRC_DEFAULT = RMT_CLK_SRC_DEFAULT; static constexpr auto DSHOT_CLOCK_SRC_DEFAULT = RMT_CLK_SRC_DEFAULT;
static constexpr uint32_t DSHOT_RMT_RESOLUTION = 8000000; // 8 MHz resolution static constexpr auto DSHOT_RMT_RESOLUTION = 8000000; // 8 MHz resolution
static constexpr uint16_t RMT_TICKS_PER_US = DSHOT_RMT_RESOLUTION / 1000000; // RMT Ticks per microsecond static constexpr auto RMT_TICKS_PER_US = DSHOT_RMT_RESOLUTION / 1000000; // RMT Ticks per microsecond
static constexpr uint16_t DSHOT_RX_TIMEOUT_MS = 2; static constexpr auto DSHOT_RX_TIMEOUT_MS = 2;
static constexpr uint16_t DSHOT_PADDING_US = 20; // Pause between frames static constexpr auto DSHOT_PADDING_US = 20; // Pause between frames
static constexpr uint16_t RMT_BUFFER_SYMBOLS = 64; static constexpr auto RMT_BUFFER_SYMBOLS = 64;
static constexpr uint16_t RMT_QUEUE_DEPTH = 1; static constexpr auto RMT_QUEUE_DEPTH = 1;
static constexpr uint16_t GCR_BITS_PER_FRAME = 21; // GCR bits in a DShot answer frame static constexpr auto GCR_BITS_PER_FRAME = 21; // GCR bits in a DShot answer frame
static constexpr uint16_t POLE_PAIRS_MIN = 1; static constexpr auto POLE_PAIRS_MIN = 1;
static constexpr uint16_t MAGNETS_PER_POLE_PAIR = 2; static constexpr auto MAGNETS_PER_POLE_PAIR = 2;
static constexpr uint16_t NO_DSHOT_TELEMETRY = 0; static constexpr auto NO_DSHOT_TELEMETRY = 0;
static constexpr uint16_t DSHOT_PULSE_MIN_NS = 800; // 0.8us minimum pulse static constexpr auto DSHOT_PULSE_MIN_NS = 800; // 0.8us minimum pulse
static constexpr uint16_t DSHOT_PULSE_MAX_NS = 8000; // 8.0us maximum pulse static constexpr auto DSHOT_PULSE_MAX_NS = 8000; // 8.0us maximum pulse
static constexpr uint16_t DSHOT_TELEMETRY_INVALID = DSHOT_THROTTLE_MAX; static constexpr auto DSHOT_TELEMETRY_INVALID = DSHOT_THROTTLE_MAX;
static constexpr uint16_t DSHOT_TELEMETRY_BIT_POSITION = 11; static constexpr auto DSHOT_TELEMETRY_BIT_POSITION = 11;
static constexpr uint16_t DSHOT_CRC_BIT_SHIFT = 4; static constexpr auto DSHOT_CRC_BIT_SHIFT = 4;
// Command Constants // Command Constants
static constexpr uint16_t DEFAULT_CMD_DELAY_US = 10; static constexpr auto DEFAULT_CMD_DELAY_US = 10;
static constexpr uint16_t DEFAULT_CMD_REPEAT_COUNT = 1; static constexpr auto DEFAULT_CMD_REPEAT_COUNT = 1;
static constexpr uint16_t SETTINGS_COMMAND_REPEATS = 10; static constexpr auto SETTINGS_COMMAND_REPEATS = 10;
static constexpr uint16_t SETTINGS_COMMAND_DELAY_US = 5; static constexpr auto SETTINGS_COMMAND_DELAY_US = 5;
// Timing parameters for each DShot mode // Timing parameters for each DShot mode
const dshot_timing_us_t DSHOT_TIMING_US[] = { const dshot_timing_us_t DSHOT_TIMING_US[] = {
{0.00, 0.00}, // DSHOT_OFF {0.00, 0.00}, // DSHOT_OFF
{6.67, 5.00}, // DSHOT150 {6.67, 5.00}, // DSHOT150
{3.33, 2.50}, // DSHOT300 {3.33, 2.50}, // DSHOT300
{1.67, 1.25}, // DSHOT600 {1.67, 1.25}, // DSHOT600
{0.83, 0.67} // DSHOT1200 {0.83, 0.67} // DSHOT1200
}; };
// Error Messages // Error Messages
@ -190,7 +188,7 @@ static constexpr char INVALID_COMMAND[] = "Invalid command!";
static constexpr char COMMAND_SUCCESS[] = "DShot command sent successfully"; static constexpr char COMMAND_SUCCESS[] = "DShot command sent successfully";
// Helper to get result code string // Helper to get result code string
inline const char* _get_result_code_str(dshot_msg_code_t code) inline const char *_get_result_code_str(dshot_msg_code_t code)
{ {
switch (code) switch (code)
{ {
@ -249,7 +247,7 @@ inline const char* _get_result_code_str(dshot_msg_code_t code)
} }
} }
// Helpers // Helper to quick print DShot result codes
inline void printDShotResult(dshot_result_t &result, Stream &output = Serial) inline void printDShotResult(dshot_result_t &result, Stream &output = Serial)
{ {
output.printf("Status: %s - %s", result.success ? "SUCCESS" : "FAILED", _get_result_code_str(result.result_code)); output.printf("Status: %s - %s", result.success ? "SUCCESS" : "FAILED", _get_result_code_str(result.result_code));