...cleaning

...experimental DSHOT1200 support. Who really needs DSHOT1200???
This commit is contained in:
Wastl Kraus 2025-06-13 13:50:10 +02:00
parent 64fd2edfba
commit 84adfe026a
3 changed files with 47 additions and 14 deletions

View File

@ -19,8 +19,8 @@ void DShotRMT::begin()
{ {
rmt_rx_channel_config_t rmt_rx_channel_config = { rmt_rx_channel_config_t rmt_rx_channel_config = {
.gpio_num = _gpio, .gpio_num = _gpio,
.clk_src = RMT_CLK_SRC_DEFAULT, .clk_src = DSHOT_CLOCK_SRC_DEFAULT,
.resolution_hz = DEFAULT_RES_HZ, .resolution_hz = DSHOT_RMT_RESOLUTION,
.mem_block_symbols = 64, .mem_block_symbols = 64,
.flags = { .flags = {
.invert_in = false, .invert_in = false,
@ -32,8 +32,8 @@ void DShotRMT::begin()
rmt_tx_channel_config_t rmt_tx_channel_config = { rmt_tx_channel_config_t rmt_tx_channel_config = {
.gpio_num = _gpio, .gpio_num = _gpio,
.clk_src = RMT_CLK_SRC_DEFAULT, .clk_src = DSHOT_CLOCK_SRC_DEFAULT,
.resolution_hz = DEFAULT_RES_HZ, .resolution_hz = DSHOT_RMT_RESOLUTION,
.mem_block_symbols = 64, .mem_block_symbols = 64,
.trans_queue_depth = 1, .trans_queue_depth = 1,
.flags = { .flags = {
@ -88,11 +88,10 @@ void DShotRMT::setThrottle(uint16_t throttle)
dshot_packet = (dshot_packet << 4) | crc; dshot_packet = (dshot_packet << 4) | crc;
// Encode DShot Paket // Encode DShot Paket
rmt_symbol_word_t symbols[32] = {}; rmt_symbol_word_t symbols[DSHOT_BITS_PER_FRAME] = {}; // 16 DShot Bits + Pause Bit
size_t count = 0; size_t count = 0;
buildFrameSymbols(dshot_packet, symbols, count); buildFrameSymbols(dshot_packet, symbols, count);
// Reset RMT Signnal loop before sending new value // Reset RMT Signnal loop before sending new value
rmt_disable(_rmt_tx_channel); rmt_disable(_rmt_tx_channel);
rmt_enable(_rmt_tx_channel); rmt_enable(_rmt_tx_channel);
@ -104,12 +103,21 @@ void DShotRMT::setThrottle(uint16_t throttle)
// //
void DShotRMT::buildFrameSymbols(uint16_t dshot_packet, rmt_symbol_word_t *symbols, size_t &count) void DShotRMT::buildFrameSymbols(uint16_t dshot_packet, rmt_symbol_word_t *symbols, size_t &count)
{ {
// Always start from the top
count = 0;
//
uint32_t ticks_per_bit = 0; uint32_t ticks_per_bit = 0;
uint32_t ticks_zero_high = 0; uint32_t ticks_zero_high = 0;
uint32_t ticks_one_high = 0; uint32_t ticks_one_high = 0;
switch (_mode) switch (_mode)
{ {
case DSHOT_OFF:
ticks_per_bit = 0;
ticks_zero_high = 0;
ticks_one_high = 0;
break;
case DSHOT150: case DSHOT150:
ticks_per_bit = 64; ticks_per_bit = 64;
ticks_zero_high = 24; ticks_zero_high = 24;
@ -125,11 +133,18 @@ void DShotRMT::buildFrameSymbols(uint16_t dshot_packet, rmt_symbol_word_t *symbo
ticks_zero_high = 6; ticks_zero_high = 6;
ticks_one_high = 12; ticks_one_high = 12;
break; break;
case DSHOT1200:
ticks_per_bit = 8;
ticks_zero_high = 3;
ticks_one_high = 6;
break;
} }
//
uint32_t ticks_zero_low = ticks_per_bit - ticks_zero_high; uint32_t ticks_zero_low = ticks_per_bit - ticks_zero_high;
uint32_t ticks_one_low = ticks_per_bit - ticks_one_high; uint32_t ticks_one_low = ticks_per_bit - ticks_one_high;
// Fill the 16 DShot-Bits Array with selected timings
for (int i = 15; i >= 0; i--) for (int i = 15; i >= 0; i--)
{ {
bool bit = (dshot_packet >> i) & 0x01; bool bit = (dshot_packet >> i) & 0x01;
@ -140,6 +155,7 @@ void DShotRMT::buildFrameSymbols(uint16_t dshot_packet, rmt_symbol_word_t *symbo
count++; count++;
} }
// Append the Pause Bits
symbols[count].level0 = 0; symbols[count].level0 = 0;
symbols[count].duration0 = ticks_per_bit * PAUSE_BITS; symbols[count].duration0 = ticks_per_bit * PAUSE_BITS;
symbols[count].level1 = 0; symbols[count].level1 = 0;

View File

@ -12,20 +12,29 @@
#include <driver/rmt_tx.h> #include <driver/rmt_tx.h>
#include <driver/rmt_rx.h> #include <driver/rmt_rx.h>
// DShot Protocol Constants
static constexpr auto DSHOT_THROTTLE_FAILSAVE = 0; static constexpr auto DSHOT_THROTTLE_FAILSAVE = 0;
static constexpr auto DSHOT_THROTTLE_MIN = 48; static constexpr auto DSHOT_THROTTLE_MIN = 48;
static constexpr auto DSHOT_THROTTLE_MAX = 2047; static constexpr auto DSHOT_THROTTLE_MAX = 2047;
static constexpr auto DEFAULT_RES_HZ = 10 * 1000 * 1000; // 10 MHz static constexpr auto DSHOT_BITS_PER_FRAME = 17;
static constexpr auto PAUSE_BITS = 21; static constexpr auto PAUSE_BITS = 21;
static constexpr auto DSHOT_NULL_PACKET = 0b0000000000000000; static constexpr auto DSHOT_NULL_PACKET = 0b0000000000000000;
static constexpr auto DSHOT_FULL_PACKET = 0b1111111111111111;
static constexpr auto NO_ERPM_SIGNAL = 0;
static constexpr auto DSHOT_CLOCK_SRC_DEFAULT = RMT_CLK_SRC_DEFAULT;
static constexpr auto DSHOT_RMT_RESOLUTION = 10 * 1000 * 1000; // set 10 MHz RMT Resolution
// DShot Mode Selection
typedef enum dshot_mode_e typedef enum dshot_mode_e
{ {
DSHOT_OFF,
DSHOT150, DSHOT150,
DSHOT300, DSHOT300,
DSHOT600 DSHOT600,
DSHOT1200
} dshot_mode_t; } dshot_mode_t;
//
class DShotRMT class DShotRMT
{ {
public: public:
@ -41,7 +50,7 @@ private:
gpio_num_t _gpio; gpio_num_t _gpio;
dshot_mode_t _mode; dshot_mode_t _mode;
bool _isBidirectional; bool _isBidirectional;
uint16_t _lastThrottle = 0; uint16_t _lastThrottle = DSHOT_FULL_PACKET;
uint16_t dshot_packet = DSHOT_NULL_PACKET; uint16_t dshot_packet = DSHOT_NULL_PACKET;
rmt_channel_handle_t _rmt_tx_channel = nullptr; rmt_channel_handle_t _rmt_tx_channel = nullptr;

View File

@ -17,7 +17,7 @@ constexpr auto USB_SERIAL_BAUD = 115200;
constexpr auto MOTOR01_PIN = GPIO_NUM_17; constexpr auto MOTOR01_PIN = GPIO_NUM_17;
constexpr auto DSHOT_MODE = DSHOT300; constexpr auto DSHOT_MODE = DSHOT300;
// BiDirectional DShot Support // BiDirectional DShot Support (default: false)
constexpr auto IS_BIDIRECTIONAL = true; constexpr auto IS_BIDIRECTIONAL = true;
// Setup Motor Pin, DShot Mode and optional BiDirectional Support // Setup Motor Pin, DShot Mode and optional BiDirectional Support
@ -25,6 +25,7 @@ DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL);
void setup() void setup()
{ {
// Start the USB Serial Port
USB_Serial.begin(USB_SERIAL_BAUD); USB_Serial.begin(USB_SERIAL_BAUD);
// Initialize DShot Signal // Initialize DShot Signal
@ -34,16 +35,23 @@ void setup()
motor01.setThrottle(DSHOT_THROTTLE_MIN); motor01.setThrottle(DSHOT_THROTTLE_MIN);
// //
USB_Serial.println("**********************");
USB_Serial.println("DShotRMT Demo started."); USB_Serial.println("DShotRMT Demo started.");
USB_Serial.println("Enter a throttle value (482047):"); USB_Serial.println("Enter a throttle value (48 2047):");
} }
void loop() void loop()
{ {
// Simple as can be // Read value input from Serial
int throttle_input = readSerialThrottle(); int throttle_input = readSerialThrottle();
// Now send the value
motor01.setThrottle(throttle_input); motor01.setThrottle(throttle_input);
// BiDirectional DShot: print out the received eRPMs
if (IS_BIDIRECTIONAL)
{
}
} }
// Reads throttle value from serial input // Reads throttle value from serial input
@ -63,8 +71,8 @@ int readSerialThrottle()
USB_Serial.print("Throttle set to: "); USB_Serial.print("Throttle set to: ");
USB_Serial.println(last_throttle); USB_Serial.println(last_throttle);
USB_Serial.println("***********************************");
USB_Serial.println("Enter a throttle value (482047):"); USB_Serial.println("Enter a throttle value (48 2047):");
} }
return last_throttle; return last_throttle;