From 34c6f66256a49da3763f401f1b4fe4d58206ecca Mon Sep 17 00:00:00 2001 From: Wastl Kraus Date: Sun, 26 Mar 2023 16:19:54 +0200 Subject: [PATCH] ...updated class to optimize configuration --- .gitignore | 1 + examples/dshot300/dshot300.ino | 7 +- keywords.txt | 2 +- library.properties | 2 +- src/DShotRMT.cpp | 154 +++++++++++++++++---------------- src/DShotRMT.h | 17 ++-- 6 files changed, 90 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index 4a5379a..ae9c024 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ buildCache examples/dshot300/debug.cfg examples/dshot300/esp32.svd examples/dshot300/debug_custom.json +examples/dshot300/debug.svd diff --git a/examples/dshot300/dshot300.ino b/examples/dshot300/dshot300.ino index 07a35de..1498a7a 100644 --- a/examples/dshot300/dshot300.ino +++ b/examples/dshot300/dshot300.ino @@ -9,7 +9,7 @@ constexpr auto USB_SERIAL_BAUD = 115200; #endif // SERIAL -DShotRMT dshot_01(GPIO_NUM_4, RMT_CHANNEL_0); +DShotRMT motor01(GPIO_NUM_4, RMT_CHANNEL_0, DSHOT300, false); volatile uint16_t throttle_value = 0x30; // ...sending "48", the first throttle value constexpr auto FAILSAVE_THROTTLE = 0x3E7; @@ -18,16 +18,13 @@ void setup() { // ...always start the onboard usb support USB_Serial.begin(USB_SERIAL_BAUD); - - // ...start the dshot generation - dshot_01.begin(DSHOT300); } void loop() { read_SerialThrottle(); - dshot_01.send_dshot_value(throttle_value); + motor01.send_dshot_value(throttle_value); // ...print to console USB_Serial.println(throttle_value); diff --git a/keywords.txt b/keywords.txt index 4f46df6..51ef377 100644 --- a/keywords.txt +++ b/keywords.txt @@ -15,7 +15,7 @@ dshot_config_t KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -begin KEYWORD2 +install_dshot_driver KEYWORD2 send_dshot_value KEYWORD2 get_dshot_info KEYWORD2 get_dshot_clock_div KEYWORD2 diff --git a/library.properties b/library.properties index 6814437..65b4409 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=DShotRMT -version=0.2.2 +version=0.2.3 author=derdoktor667 maintainer=derdoktor667 sentence=DShotRMT Library supporting all DShot Types and speeds. Tested with BlHeli_S. diff --git a/src/DShotRMT.cpp b/src/DShotRMT.cpp index 002f5ab..58aa009 100644 --- a/src/DShotRMT.cpp +++ b/src/DShotRMT.cpp @@ -4,9 +4,9 @@ // Author: derdoktor667 // -#include "DShotRMT.h" +#include -DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel) +DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel, dshot_mode_t dshot_mode, bool is_bidirectional) { dshot_config.gpio_num = gpio; dshot_config.pin_num = uint8_t(gpio); @@ -15,9 +15,12 @@ DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel) // ...create empty packet encode_dshot_to_rmt(DSHOT_NULL_PACKET); + + // install the RMT driver with dshot values + install_dshot_driver(dshot_mode, is_bidirectional); } -DShotRMT::DShotRMT(uint8_t pin, uint8_t channel) +DShotRMT::DShotRMT(uint8_t pin, uint8_t channel, dshot_mode_t dshot_mode, bool is_bidirectional) { dshot_config.gpio_num = gpio_num_t(pin); dshot_config.pin_num = pin; @@ -26,6 +29,9 @@ DShotRMT::DShotRMT(uint8_t pin, uint8_t channel) // ...create empty packet encode_dshot_to_rmt(DSHOT_NULL_PACKET); + + // install the RMT driver with dshot values + install_dshot_driver(dshot_mode, is_bidirectional); } DShotRMT::~DShotRMT() @@ -38,77 +44,6 @@ DShotRMT::DShotRMT(DShotRMT const &) // ...write me } -bool DShotRMT::begin(dshot_mode_t dshot_mode, bool is_bidirectional) -{ - dshot_config.mode = dshot_mode; - dshot_config.clk_div = DSHOT_CLK_DIVIDER; - dshot_config.name_str = dshot_mode_name[dshot_mode]; - dshot_config.bidirectional = is_bidirectional; - - switch (dshot_config.mode) - { - case DSHOT150: - dshot_config.ticks_per_bit = 64; // ...Bit Period Time 6.67 us - dshot_config.ticks_zero_high = 24; // ...zero time 2.50 us - dshot_config.ticks_one_high = 48; // ...one time 5.00 us - break; - - case DSHOT300: - dshot_config.ticks_per_bit = 32; // ...Bit Period Time 3.33 us - dshot_config.ticks_zero_high = 12; // ...zero time 1.25 us - dshot_config.ticks_one_high = 24; // ...one time 2.50 us - break; - - case DSHOT600: - dshot_config.ticks_per_bit = 16; // ...Bit Period Time 1.67 us - dshot_config.ticks_zero_high = 6; // ...zero time 0.625 us - dshot_config.ticks_one_high = 12; // ...one time 1.25 us - break; - - case DSHOT1200: - dshot_config.ticks_per_bit = 8; // ...Bit Period Time 0.83 us - dshot_config.ticks_zero_high = 3; // ...zero time 0.313 us - dshot_config.ticks_one_high = 6; // ...one time 0.625 us - break; - - // ...because having a default is "good style" - default: - dshot_config.ticks_per_bit = 0; // ...Bit Period Time endless - dshot_config.ticks_zero_high = 0; // ...no bits, no time - dshot_config.ticks_one_high = 0; // ......no bits, no time - break; - } - - // ...calc low signal timing - dshot_config.ticks_zero_low = (dshot_config.ticks_per_bit - dshot_config.ticks_zero_high); - dshot_config.ticks_one_low = (dshot_config.ticks_per_bit - dshot_config.ticks_one_high); - - dshot_tx_rmt_config.rmt_mode = RMT_MODE_TX; - dshot_tx_rmt_config.channel = dshot_config.rmt_channel; - dshot_tx_rmt_config.gpio_num = dshot_config.gpio_num; - dshot_tx_rmt_config.mem_block_num = dshot_config.mem_block_num; - dshot_tx_rmt_config.clk_div = dshot_config.clk_div; - - dshot_tx_rmt_config.tx_config.loop_en = false; - dshot_tx_rmt_config.tx_config.carrier_en = false; - dshot_tx_rmt_config.tx_config.idle_output_en = true; - - if (dshot_config.bidirectional) - { - dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH; - } - else - { - dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; - } - - // ...setup selected dshot mode - rmt_config(&dshot_tx_rmt_config); - - // ...essential step, return the result - return rmt_driver_install(dshot_tx_rmt_config.channel, 0, 0); -} - // ...the config part is done, now the calculating and sending part void DShotRMT::send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request) { @@ -247,6 +182,77 @@ uint16_t DShotRMT::prepare_rmt_data(const dshot_packet_t &dshot_packet) return prepared_to_encode; } +void DShotRMT::install_dshot_driver(dshot_mode_t dshot_mode, bool is_bidirectional) +{ + dshot_config.mode = dshot_mode; + dshot_config.clk_div = DSHOT_CLK_DIVIDER; + dshot_config.name_str = dshot_mode_name[dshot_mode]; + dshot_config.bidirectional = is_bidirectional; + + switch (dshot_config.mode) + { + case DSHOT150: + dshot_config.ticks_per_bit = 64; // ...Bit Period Time 6.67 us + dshot_config.ticks_zero_high = 24; // ...zero time 2.50 us + dshot_config.ticks_one_high = 48; // ...one time 5.00 us + break; + + case DSHOT300: + dshot_config.ticks_per_bit = 32; // ...Bit Period Time 3.33 us + dshot_config.ticks_zero_high = 12; // ...zero time 1.25 us + dshot_config.ticks_one_high = 24; // ...one time 2.50 us + break; + + case DSHOT600: + dshot_config.ticks_per_bit = 16; // ...Bit Period Time 1.67 us + dshot_config.ticks_zero_high = 6; // ...zero time 0.625 us + dshot_config.ticks_one_high = 12; // ...one time 1.25 us + break; + + case DSHOT1200: + dshot_config.ticks_per_bit = 8; // ...Bit Period Time 0.83 us + dshot_config.ticks_zero_high = 3; // ...zero time 0.313 us + dshot_config.ticks_one_high = 6; // ...one time 0.625 us + break; + + // ...because having a default is "good style" + default: + dshot_config.ticks_per_bit = 0; // ...Bit Period Time endless + dshot_config.ticks_zero_high = 0; // ...no bits, no time + dshot_config.ticks_one_high = 0; // ......no bits, no time + break; + } + + // ...calc low signal timing + dshot_config.ticks_zero_low = (dshot_config.ticks_per_bit - dshot_config.ticks_zero_high); + dshot_config.ticks_one_low = (dshot_config.ticks_per_bit - dshot_config.ticks_one_high); + + dshot_tx_rmt_config.rmt_mode = RMT_MODE_TX; + dshot_tx_rmt_config.channel = dshot_config.rmt_channel; + dshot_tx_rmt_config.gpio_num = dshot_config.gpio_num; + dshot_tx_rmt_config.mem_block_num = dshot_config.mem_block_num; + dshot_tx_rmt_config.clk_div = dshot_config.clk_div; + + dshot_tx_rmt_config.tx_config.loop_en = false; + dshot_tx_rmt_config.tx_config.carrier_en = false; + dshot_tx_rmt_config.tx_config.idle_output_en = true; + + if (dshot_config.bidirectional) + { + dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH; + } + else + { + dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; + } + + // ...setup selected dshot mode + rmt_config(&dshot_tx_rmt_config); + + // ...essential step, install rmt driver + rmt_driver_install(dshot_tx_rmt_config.channel, 0, 0); +} + // ...finally output using ESP32 RMT void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet) { diff --git a/src/DShotRMT.h b/src/DShotRMT.h index 74bd0ae..2e86cdc 100644 --- a/src/DShotRMT.h +++ b/src/DShotRMT.h @@ -4,20 +4,15 @@ // Author: derdoktor667 // -#ifndef _DSHOTRMT_h -#define _DSHOTRMT_h +#pragma once -#if defined(ARDUINO) && ARDUINO >= 100 #include -#else -#include "WProgram.h" -#endif // ...utilizing the RMT Module library for generating the DShot signal #include // ...unify versioning -constexpr auto DSHOT_LIB_VERSION = "0.2.2"; +constexpr auto DSHOT_LIB_VERSION = "0.2.3"; constexpr auto DSHOT_CLK_DIVIDER = 8; // ...slow down RMT clock to 0.1 microseconds / 100 nanoseconds per cycle constexpr auto DSHOT_PACKET_LENGTH = 17; // ...last pack is the pause @@ -94,13 +89,12 @@ typedef struct dshot_config_s class DShotRMT { public: - DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel); - DShotRMT(uint8_t pin, uint8_t channel); + DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel, dshot_mode_t dshot_mode, bool is_bidirectional); + DShotRMT(uint8_t pin, uint8_t channel, dshot_mode_t dshot_mode, bool is_bidirectional); ~DShotRMT(); DShotRMT(DShotRMT const &); // ...safety first ...no parameters, no DShot - bool begin(dshot_mode_t dshot_mode = DSHOT_OFF, bool is_bidirectional = false); void send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request = NO_TELEMETRIC); dshot_config_t *get_dshot_info(); @@ -115,7 +109,6 @@ private: uint16_t calc_dshot_chksum(const dshot_packet_t &dshot_packet); uint16_t prepare_rmt_data(const dshot_packet_t &dshot_packet); + void install_dshot_driver(dshot_mode_t dshot_mode, bool is_bidirectional); void output_rmt_data(const dshot_packet_t &dshot_packet); }; - -#endif