From 84adfe026a6a6a4a29b466b981e36088bd14ad43 Mon Sep 17 00:00:00 2001 From: Wastl Kraus Date: Fri, 13 Jun 2025 13:50:10 +0200 Subject: [PATCH] ...cleaning ...experimental DSHOT1200 support. Who really needs DSHOT1200??? --- DShotRMT.cpp | 28 ++++++++++++++++++++++------ DShotRMT.h | 15 ++++++++++++--- examples/dshot300/dshot300.ino | 18 +++++++++++++----- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/DShotRMT.cpp b/DShotRMT.cpp index 4e8fd4f..680b27b 100644 --- a/DShotRMT.cpp +++ b/DShotRMT.cpp @@ -19,8 +19,8 @@ void DShotRMT::begin() { rmt_rx_channel_config_t rmt_rx_channel_config = { .gpio_num = _gpio, - .clk_src = RMT_CLK_SRC_DEFAULT, - .resolution_hz = DEFAULT_RES_HZ, + .clk_src = DSHOT_CLOCK_SRC_DEFAULT, + .resolution_hz = DSHOT_RMT_RESOLUTION, .mem_block_symbols = 64, .flags = { .invert_in = false, @@ -32,8 +32,8 @@ void DShotRMT::begin() rmt_tx_channel_config_t rmt_tx_channel_config = { .gpio_num = _gpio, - .clk_src = RMT_CLK_SRC_DEFAULT, - .resolution_hz = DEFAULT_RES_HZ, + .clk_src = DSHOT_CLOCK_SRC_DEFAULT, + .resolution_hz = DSHOT_RMT_RESOLUTION, .mem_block_symbols = 64, .trans_queue_depth = 1, .flags = { @@ -88,11 +88,10 @@ void DShotRMT::setThrottle(uint16_t throttle) dshot_packet = (dshot_packet << 4) | crc; // 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; buildFrameSymbols(dshot_packet, symbols, count); - // Reset RMT Signnal loop before sending new value rmt_disable(_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) { + // Always start from the top + count = 0; + + // uint32_t ticks_per_bit = 0; uint32_t ticks_zero_high = 0; uint32_t ticks_one_high = 0; switch (_mode) { + case DSHOT_OFF: + ticks_per_bit = 0; + ticks_zero_high = 0; + ticks_one_high = 0; + break; case DSHOT150: ticks_per_bit = 64; 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_one_high = 12; 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_one_low = ticks_per_bit - ticks_one_high; + // Fill the 16 DShot-Bits Array with selected timings for (int i = 15; i >= 0; i--) { bool bit = (dshot_packet >> i) & 0x01; @@ -140,6 +155,7 @@ void DShotRMT::buildFrameSymbols(uint16_t dshot_packet, rmt_symbol_word_t *symbo count++; } + // Append the Pause Bits symbols[count].level0 = 0; symbols[count].duration0 = ticks_per_bit * PAUSE_BITS; symbols[count].level1 = 0; diff --git a/DShotRMT.h b/DShotRMT.h index f04a253..916cd6e 100644 --- a/DShotRMT.h +++ b/DShotRMT.h @@ -12,20 +12,29 @@ #include #include +// DShot Protocol Constants static constexpr auto DSHOT_THROTTLE_FAILSAVE = 0; static constexpr auto DSHOT_THROTTLE_MIN = 48; 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 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 { + DSHOT_OFF, DSHOT150, DSHOT300, - DSHOT600 + DSHOT600, + DSHOT1200 } dshot_mode_t; +// class DShotRMT { public: @@ -41,7 +50,7 @@ private: gpio_num_t _gpio; dshot_mode_t _mode; bool _isBidirectional; - uint16_t _lastThrottle = 0; + uint16_t _lastThrottle = DSHOT_FULL_PACKET; uint16_t dshot_packet = DSHOT_NULL_PACKET; rmt_channel_handle_t _rmt_tx_channel = nullptr; diff --git a/examples/dshot300/dshot300.ino b/examples/dshot300/dshot300.ino index 6e71efe..c67876f 100644 --- a/examples/dshot300/dshot300.ino +++ b/examples/dshot300/dshot300.ino @@ -17,7 +17,7 @@ constexpr auto USB_SERIAL_BAUD = 115200; constexpr auto MOTOR01_PIN = GPIO_NUM_17; constexpr auto DSHOT_MODE = DSHOT300; -// BiDirectional DShot Support +// BiDirectional DShot Support (default: false) constexpr auto IS_BIDIRECTIONAL = true; // Setup Motor Pin, DShot Mode and optional BiDirectional Support @@ -25,6 +25,7 @@ DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL); void setup() { + // Start the USB Serial Port USB_Serial.begin(USB_SERIAL_BAUD); // Initialize DShot Signal @@ -34,16 +35,23 @@ void setup() motor01.setThrottle(DSHOT_THROTTLE_MIN); // + USB_Serial.println("**********************"); USB_Serial.println("DShotRMT Demo started."); - USB_Serial.println("Enter a throttle value (48–2047):"); + USB_Serial.println("Enter a throttle value (48 – 2047):"); } void loop() { - // Simple as can be + // Read value input from Serial int throttle_input = readSerialThrottle(); + // Now send the value motor01.setThrottle(throttle_input); + + // BiDirectional DShot: print out the received eRPMs + if (IS_BIDIRECTIONAL) + { + } } // Reads throttle value from serial input @@ -63,8 +71,8 @@ int readSerialThrottle() USB_Serial.print("Throttle set to: "); USB_Serial.println(last_throttle); - - USB_Serial.println("Enter a throttle value (48–2047):"); + USB_Serial.println("***********************************"); + USB_Serial.println("Enter a throttle value (48 – 2047):"); } return last_throttle;