From b0373190bbbd3b290235e8cacfbbb7158cc88eb0 Mon Sep 17 00:00:00 2001 From: Wastl Kraus Date: Wed, 6 Aug 2025 23:57:26 +0200 Subject: [PATCH] ...more simplifications --- DShotRMT.cpp | 47 +++++++++++++----- DShotRMT.h | 13 +++-- examples/dshot300/dshot300.ino | 91 ++++++++++++++++------------------ 3 files changed, 87 insertions(+), 64 deletions(-) diff --git a/DShotRMT.cpp b/DShotRMT.cpp index e460863..e6ce32f 100644 --- a/DShotRMT.cpp +++ b/DShotRMT.cpp @@ -18,7 +18,7 @@ constexpr dshot_timing_t DSHOT_TIMINGS[] = { {16, 8, 6, 3, 5, 2} // DSHOT1200 }; -// +// --- DShot Config --- DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional): _gpio(gpio), _mode(mode), @@ -28,8 +28,9 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional): _rmt_rx_channel(nullptr), _dshot_encoder(nullptr), _last_erpm(0), - _last_transmission_time(0), - _current_packet(0) + _current_packet(0), + _packet{0}, + _last_transmission_time(0) { // Double up frame time for bidirectional mode if (_is_bidirectional) @@ -41,6 +42,14 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional): _frame_time_us = _timing_config.frame_length_us + DSHOT_SWITCH_TIME; } +// Easy Constructor +DShotRMT::DShotRMT(uint16_t pin_nr, dshot_mode_t mode, bool is_bidirectional): + DShotRMT((gpio_num_t)pin_nr, + mode, + is_bidirectional) +{ +} + // Init DShotRMT bool DShotRMT::begin() { @@ -69,36 +78,50 @@ bool DShotRMT::begin() return DSHOT_OK; } -// +// Deprecated, use "sendThrottle() instead" bool DShotRMT::setThrottle(uint16_t throttle) { + return sendThrottle(throttle); +} + +// Sends a valid throttle value +bool DShotRMT::sendThrottle(uint16_t throttle) +{ + static uint16_t last_throttle = DSHOT_THROTTLE_MIN; + // Precheck throttle value if (throttle < DSHOT_THROTTLE_MIN || throttle > DSHOT_THROTTLE_MAX) { Serial.println(DSHOT_MSG_06); return DSHOT_ERROR; + } else { + last_throttle = throttle; } - // - dshot_packet_t packet = _buildDShotPacket(throttle); + // Converts throttle value to dshot packet + _packet = _buildDShotPacket(last_throttle); - return (_sendDShotFrame(packet)); + return (_sendDShotFrame(_packet)); } -// +// Deprecated, use "sendCommand() instead" bool DShotRMT::sendDShotCommand(uint16_t command) { - // Precheck command value + return sendCommand(command); +} + +bool DShotRMT::sendCommand(uint16_t command) +{ + // Check for valid command if (command < DSHOT_CMD_MOTOR_STOP || command > DSHOT_CMD_MAX) { Serial.println(DSHOT_MSG_07); return DSHOT_ERROR; } - // - dshot_packet_t packet = _buildDShotPacket(command); + _packet = _buildDShotPacket(command); - return (_sendDShotFrame(packet)); + return (_sendDShotFrame(_packet)); } // diff --git a/DShotRMT.h b/DShotRMT.h index 6fb1290..84482b6 100644 --- a/DShotRMT.h +++ b/DShotRMT.h @@ -59,24 +59,26 @@ typedef struct dshot_timing_s uint16_t ticks_one_low; } dshot_timing_t; -// --- DShot Timing Config --- extern const dshot_timing_t DSHOT_TIMINGS[]; -// +// --- DShotRMT Class --- class DShotRMT { public: - // + // --- DShot Config --- DShotRMT(gpio_num_t gpio, dshot_mode_t mode = DSHOT300, bool is_bidirectional = false); + DShotRMT(uint16_t pin_nr, dshot_mode_t mode, bool is_bidirectional); // --- Init RMT Module --- bool begin(); // Sets the throttle value and transmits - bool setThrottle(uint16_t throttle); + bool setThrottle(uint16_t throttle); // deprecated + bool sendThrottle(uint16_t throttle); // Sends a DShot Command - bool sendDShotCommand(uint16_t command); + bool sendDShotCommand(uint16_t command); // deprecated + bool sendCommand(uint16_t command); // Gets eRPM from ESC telemetry uint16_t getERPM(); @@ -117,6 +119,7 @@ private: // --- Buffers --- uint16_t _last_erpm; uint16_t _current_packet; + dshot_packet_t _packet; unsigned long _last_transmission_time; // diff --git a/examples/dshot300/dshot300.ino b/examples/dshot300/dshot300.ino index c11ce22..bcda260 100644 --- a/examples/dshot300/dshot300.ino +++ b/examples/dshot300/dshot300.ino @@ -14,7 +14,8 @@ static constexpr HardwareSerial &USB_SERIAL = Serial0; static constexpr uint32_t USB_SERIAL_BAUD = 115200; // Motor configuration -static constexpr gpio_num_t MOTOR01_PIN = GPIO_NUM_17; +// static constexpr gpio_num_t MOTOR01_PIN = GPIO_NUM_17; +static constexpr uint16_t MOTOR01_PIN = 17; static constexpr dshot_mode_t DSHOT_MODE = DSHOT300; // BiDirectional DShot Support (default: false) @@ -26,14 +27,14 @@ static constexpr uint8_t MOTOR01_MAGNET_COUNT = 14; // Setup Motor Pin, DShot Mode and optional BiDirectional Support DShotRMT motor01(MOTOR01_PIN, DSHOT_MODE, IS_BIDIRECTIONAL); -// Prints RPM and throttle every 2 seconds if BiDirectional is enabled -void printRPMPeriodically(uint16_t throttle); +// Prints RPM if BiDirectional is enabled every ms +void printRPMPeriodically(uint16_t timer_ms); // Reads throttle value from serial input -uint16_t readSerialThrottle(); +uint16_t readSerialThrottle(HardwareSerial &serial); -// Prints out the dshot packet bitwise (Debug) -void printPacket(); +// Prints out the dshot packet bitwise every ms (Debug) +void printTXPacket(uint16_t timer_ms); // void setup() @@ -45,10 +46,10 @@ void setup() motor01.begin(); // Arm ESC with minimum throttle - motor01.setThrottle(DSHOT_THROTTLE_MIN); + // motor01.sendThrottle(DSHOT_THROTTLE_MIN); - USB_SERIAL.println("**********************"); - USB_SERIAL.println("DShotRMT Demo started."); + USB_SERIAL.println("***********************************"); + USB_SERIAL.println(" === DShotRMT Demo started. === "); USB_SERIAL.println("Enter a throttle value (48 – 2047):"); } @@ -56,78 +57,74 @@ void setup() void loop() { // Read value input from Serial - uint16_t throttle_input = readSerialThrottle(); + uint16_t throttle_input = readSerialThrottle(USB_SERIAL); // Send the value to the ESC - motor01.setThrottle(throttle_input); + motor01.sendThrottle(throttle_input); - // Print RPM if BiDirectional DShot is enabled - if (IS_BIDIRECTIONAL) - { - printRPMPeriodically(throttle_input); - } + // Prints RPM every 2 if BiDirectional DShot is enabled + printRPMPeriodically(2000); - // Prints out "raw" DShot packet - // printPacket(); + // Prints out "raw" DShot packet every 2 seconds + // printTXPacket(2000); } // Reads throttle value from serial input -uint16_t readSerialThrottle() +uint16_t readSerialThrottle(HardwareSerial &serial) { static uint16_t last_throttle = DSHOT_THROTTLE_MIN; - if (USB_SERIAL.available() > 0) + if (serial.available() > NULL) { - String input = USB_SERIAL.readStringUntil('\n'); - int throttle_input = input.toInt(); + // Reads a value + uint16_t throttle = (serial.readStringUntil('\n').toInt()); - if (throttle_input < DSHOT_THROTTLE_MIN || throttle_input > DSHOT_THROTTLE_MAX) + // Check for valid throttle value + if (throttle < DSHOT_THROTTLE_MIN || throttle > DSHOT_THROTTLE_MAX) { - USB_SERIAL.println("Invalid input. Please enter a value between 48 and 2047."); + USB_SERIAL.println("Throttle value not in range (48 - 2047)!"); return last_throttle; } - else - { - last_throttle = throttle_input; - USB_SERIAL.print("Throttle set to: "); - USB_SERIAL.println(last_throttle); - } - USB_SERIAL.println("*********************************"); - USB_SERIAL.println("Enter a throttle value (48 – 2047):"); + last_throttle = throttle; + + USB_SERIAL.println("*********************"); + USB_SERIAL.print("Throttle set to: "); + USB_SERIAL.println(last_throttle); } return last_throttle; } -// Prints RPM and throttle every 2 seconds -void printRPMPeriodically(uint16_t throttle) +// Prints RPM every ms +void printRPMPeriodically(uint16_t timer_ms) { - static unsigned long last_print_time = 0; - - if (millis() - last_print_time >= 2000) + if (IS_BIDIRECTIONAL) { - uint32_t rpm = motor01.getMotorRPM(MOTOR01_MAGNET_COUNT); + static unsigned long last_print_time = 0; - USB_SERIAL.print("Throttle: "); - USB_SERIAL.print(throttle); - USB_SERIAL.print(" | RPM: "); - USB_SERIAL.println(rpm); + if (millis() - last_print_time >= timer_ms) + { + uint32_t rpm = motor01.getMotorRPM(MOTOR01_MAGNET_COUNT); - last_print_time = millis(); + USB_SERIAL.print("RPM: "); + USB_SERIAL.println(rpm); + + last_print_time = millis(); + } } } -// -void printPacket() +// Prints "raw" packet every ms +void printTXPacket(uint16_t timer_ms) { static unsigned long last_print_time = 0; - if (millis() - last_print_time >= 2000) + if (millis() - last_print_time >= timer_ms) { - // Prints out actual DShot Packet bitwise uint16_t packet = motor01.getDShotPacket(); + // Print bit by bit for (int i = 15; i >= 0; --i) { if ((packet >> i) & 1)