Further optimizing
This commit is contained in:
parent
5c976e2cc9
commit
24d3ab700f
14
README.md
14
README.md
|
|
@ -2,16 +2,15 @@
|
||||||
|
|
||||||
[](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml)
|
[](https://github.com/derdoktor667/DShotRMT/actions/workflows/ci.yml)
|
||||||
|
|
||||||
A C++ library for generating DShot signals on ESP32 microcontrollers using the RMT (Remote Control) peripheral. It's designed for both Arduino and ESP-IDF projects, providing a simple and efficient way to control brushless motors.
|
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 provides a simple, efficient, and hardware-timed 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.
|
||||||
|
|
||||||
This library is a rewrite using the modern ESP-IDF 5 RMT encoder API (`rmt_tx.h` / `rmt_rx.h`) for improved performance and flexibility. The legacy version using the old `rmt.h` API is available in the `oldAPI` branch.
|
|
||||||
|
|
||||||
## 🚀 Core Features
|
## 🚀 Core Features
|
||||||
|
|
||||||
- **Multiple DShot Modes:** Supports DSHOT150, DSHOT300, DSHOT600, and DSHOT1200.
|
- **Multiple DShot Modes:** Supports DSHOT150, DSHOT300, DSHOT600, and DSHOT1200.
|
||||||
- **Bidirectional DShot:** Implemented, but currently not officially supported due to instability and external hardware requirements.
|
- **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`.
|
||||||
- **Efficient and Lightweight:** The core library has no external dependencies.
|
- **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.
|
- **Arduino and ESP-IDF Compatible:** Can be used in both Arduino and ESP-IDF projects.
|
||||||
|
|
||||||
|
|
@ -38,7 +37,7 @@ Here's a basic example of how to use the `DShotRMT` library to control a motor:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <DShotRMT.h>
|
#include <DShotRMT.h> // Include the DShotRMT library
|
||||||
|
|
||||||
// Define the GPIO pin connected to the motor ESC
|
// Define the GPIO pin connected to the motor ESC
|
||||||
const gpio_num_t MOTOR_PIN = GPIO_NUM_27;
|
const gpio_num_t MOTOR_PIN = GPIO_NUM_27;
|
||||||
|
|
@ -100,14 +99,13 @@ lib_deps =
|
||||||
|
|
||||||
The main class is `DShotRMT`. Here are the most important methods:
|
The main class is `DShotRMT`. Here are the most important methods:
|
||||||
|
|
||||||
- `DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional = false)`: Constructor to create a new DShotRMT instance. (Note: Bidirectional DShot is currently not officially supported.)
|
- `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.
|
- `begin()`: Initializes the RMT peripheral and the DShot encoder.
|
||||||
- `sendThrottlePercent(float percent)`: Sends a throttle value as a percentage (0.0-100.0).
|
- `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.
|
- `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.
|
- `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).
|
- `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.
|
||||||
For more details, please refer to the `DShotRMT.h` header file.
|
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional, ui
|
||||||
_last_throttle(DSHOT_CMD_MOTOR_STOP),
|
_last_throttle(DSHOT_CMD_MOTOR_STOP),
|
||||||
_last_transmission_time_us(0),
|
_last_transmission_time_us(0),
|
||||||
_last_command_timestamp(0),
|
_last_command_timestamp(0),
|
||||||
_parsed_packet(0),
|
_encoded_frame_value(0),
|
||||||
_packet{0},
|
_packet{0},
|
||||||
_bitPositions{0},
|
_bitPositions{0},
|
||||||
_level0(1), // DShot standard: signal is idle-low, so pulses start by going HIGH
|
_level0(1), // DShot standard: signal is idle-low, so pulses start by going HIGH
|
||||||
|
|
@ -306,7 +306,7 @@ void DShotRMT::printDShotInfo(Stream &output) const
|
||||||
|
|
||||||
for (int i = DSHOT_BITS_PER_FRAME - 1; i >= 0; --i)
|
for (int i = DSHOT_BITS_PER_FRAME - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
output.print((_parsed_packet >> i) & 1);
|
output.print((_encoded_frame_value >> i) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.printf("\nCurrent Value: %u\n", _packet.throttle_value);
|
output.printf("\nCurrent Value: %u\n", _packet.throttle_value);
|
||||||
|
|
@ -520,12 +520,12 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
|
||||||
// This function needs to be fast, as it generates the RMT symbols just before sending
|
// This function needs to be fast, as it generates the RMT symbols just before sending
|
||||||
dshot_result_t IRAM_ATTR DShotRMT::_encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols)
|
dshot_result_t IRAM_ATTR DShotRMT::_encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols)
|
||||||
{
|
{
|
||||||
_parsed_packet = _parseDShotPacket(packet);
|
_encoded_frame_value = _parseDShotPacket(packet);
|
||||||
|
|
||||||
for (int i = 0; i < DSHOT_BITS_PER_FRAME; ++i)
|
for (int i = 0; i < DSHOT_BITS_PER_FRAME; ++i)
|
||||||
{
|
{
|
||||||
int bit_position = _bitPositions[i];
|
int bit_position = _bitPositions[i];
|
||||||
bool bit = (_parsed_packet >> bit_position) & 1;
|
bool bit = (_encoded_frame_value >> bit_position) & 1;
|
||||||
|
|
||||||
// A '1' bit has a longer high-time, a '0' bit has a shorter high-time
|
// A '1' bit has a longer high-time, a '0' bit has a shorter high-time
|
||||||
symbols[i].level0 = _level0; // Go HIGH
|
symbols[i].level0 = _level0; // Go HIGH
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ private:
|
||||||
uint16_t _last_throttle;
|
uint16_t _last_throttle;
|
||||||
uint64_t _last_transmission_time_us;
|
uint64_t _last_transmission_time_us;
|
||||||
uint64_t _last_command_timestamp;
|
uint64_t _last_command_timestamp;
|
||||||
uint16_t _parsed_packet;
|
uint16_t _encoded_frame_value;
|
||||||
dshot_packet_t _packet;
|
dshot_packet_t _packet;
|
||||||
uint8_t _bitPositions[DSHOT_BITS_PER_FRAME];
|
uint8_t _bitPositions[DSHOT_BITS_PER_FRAME];
|
||||||
uint16_t _level0; // Signal level for the first part of a pulse (always HIGH for DShot)
|
uint16_t _level0; // Signal level for the first part of a pulse (always HIGH for DShot)
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define DSHOT_MAX_COMMAND 47
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
DshotSettingRequest (KISS24). Spin direction, 3d and save Settings require 10 requests.. and the TLM Byte must always be high if 1-47 are used to send settings
|
DshotSettingRequest (KISS24). Spin direction, 3d and save Settings require 10 requests.. and the TLM Byte must always be high if 1-47 are used to send settings
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue