...updated class to optimize configuration

This commit is contained in:
Wastl Kraus 2023-03-26 16:19:54 +02:00
parent d7e8386129
commit 34c6f66256
6 changed files with 90 additions and 93 deletions

1
.gitignore vendored
View File

@ -18,3 +18,4 @@ buildCache
examples/dshot300/debug.cfg examples/dshot300/debug.cfg
examples/dshot300/esp32.svd examples/dshot300/esp32.svd
examples/dshot300/debug_custom.json examples/dshot300/debug_custom.json
examples/dshot300/debug.svd

View File

@ -9,7 +9,7 @@
constexpr auto USB_SERIAL_BAUD = 115200; constexpr auto USB_SERIAL_BAUD = 115200;
#endif // SERIAL #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 volatile uint16_t throttle_value = 0x30; // ...sending "48", the first throttle value
constexpr auto FAILSAVE_THROTTLE = 0x3E7; constexpr auto FAILSAVE_THROTTLE = 0x3E7;
@ -18,16 +18,13 @@ void setup()
{ {
// ...always start the onboard usb support // ...always start the onboard usb support
USB_Serial.begin(USB_SERIAL_BAUD); USB_Serial.begin(USB_SERIAL_BAUD);
// ...start the dshot generation
dshot_01.begin(DSHOT300);
} }
void loop() void loop()
{ {
read_SerialThrottle(); read_SerialThrottle();
dshot_01.send_dshot_value(throttle_value); motor01.send_dshot_value(throttle_value);
// ...print to console // ...print to console
USB_Serial.println(throttle_value); USB_Serial.println(throttle_value);

View File

@ -15,7 +15,7 @@ dshot_config_t KEYWORD1
####################################### #######################################
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
####################################### #######################################
begin KEYWORD2 install_dshot_driver KEYWORD2
send_dshot_value KEYWORD2 send_dshot_value KEYWORD2
get_dshot_info KEYWORD2 get_dshot_info KEYWORD2
get_dshot_clock_div KEYWORD2 get_dshot_clock_div KEYWORD2

View File

@ -1,5 +1,5 @@
name=DShotRMT name=DShotRMT
version=0.2.2 version=0.2.3
author=derdoktor667 author=derdoktor667
maintainer=derdoktor667 maintainer=derdoktor667
sentence=DShotRMT Library supporting all DShot Types and speeds. Tested with BlHeli_S. sentence=DShotRMT Library supporting all DShot Types and speeds. Tested with BlHeli_S.

View File

@ -4,9 +4,9 @@
// Author: derdoktor667 // Author: derdoktor667
// //
#include "DShotRMT.h" #include <DShotRMT.h>
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.gpio_num = gpio;
dshot_config.pin_num = uint8_t(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 // ...create empty packet
encode_dshot_to_rmt(DSHOT_NULL_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.gpio_num = gpio_num_t(pin);
dshot_config.pin_num = pin; dshot_config.pin_num = pin;
@ -26,6 +29,9 @@ DShotRMT::DShotRMT(uint8_t pin, uint8_t channel)
// ...create empty packet // ...create empty packet
encode_dshot_to_rmt(DSHOT_NULL_PACKET); encode_dshot_to_rmt(DSHOT_NULL_PACKET);
// install the RMT driver with dshot values
install_dshot_driver(dshot_mode, is_bidirectional);
} }
DShotRMT::~DShotRMT() DShotRMT::~DShotRMT()
@ -38,77 +44,6 @@ DShotRMT::DShotRMT(DShotRMT const &)
// ...write me // ...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 // ...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) 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; 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 // ...finally output using ESP32 RMT
void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet) void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet)
{ {

View File

@ -4,20 +4,15 @@
// Author: derdoktor667 // Author: derdoktor667
// //
#ifndef _DSHOTRMT_h #pragma once
#define _DSHOTRMT_h
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h> #include <Arduino.h>
#else
#include "WProgram.h"
#endif
// ...utilizing the RMT Module library for generating the DShot signal // ...utilizing the RMT Module library for generating the DShot signal
#include <driver/rmt.h> #include <driver/rmt.h>
// ...unify versioning // ...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_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 constexpr auto DSHOT_PACKET_LENGTH = 17; // ...last pack is the pause
@ -94,13 +89,12 @@ typedef struct dshot_config_s
class DShotRMT class DShotRMT
{ {
public: public:
DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel); DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel, dshot_mode_t dshot_mode, bool is_bidirectional);
DShotRMT(uint8_t pin, uint8_t channel); DShotRMT(uint8_t pin, uint8_t channel, dshot_mode_t dshot_mode, bool is_bidirectional);
~DShotRMT(); ~DShotRMT();
DShotRMT(DShotRMT const &); DShotRMT(DShotRMT const &);
// ...safety first ...no parameters, no DShot // ...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); void send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request = NO_TELEMETRIC);
dshot_config_t *get_dshot_info(); dshot_config_t *get_dshot_info();
@ -115,7 +109,6 @@ private:
uint16_t calc_dshot_chksum(const dshot_packet_t &dshot_packet); uint16_t calc_dshot_chksum(const dshot_packet_t &dshot_packet);
uint16_t prepare_rmt_data(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); void output_rmt_data(const dshot_packet_t &dshot_packet);
}; };
#endif