remove command_manager

This commit is contained in:
Wastl Kraus 2025-09-18 16:10:59 +02:00
parent 39207abe6e
commit 874a22aea2
9 changed files with 565 additions and 849 deletions

14
.gitignore vendored
View File

@ -1,16 +1,24 @@
.vs
.vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code # Local History for Visual Studio Code
.history/ .history/
# Built Visual Studio Code Extensions # Built Visual Studio Code Extensions
*.vsix *.vsix
# Builds # Caching ESP32 Builds
*.code-workspace
buildCache buildCache
build build
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 examples/dshot300/debug.svd
.vscode/ /build
.vscode/c_cpp_properties.json .vscode/c_cpp_properties.json

View File

@ -450,6 +450,450 @@
"RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB", "RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB",
"USBCON" "USBCON"
] ]
},
{
"name": "Arduino",
"compilerPath": "/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/bin/xtensa-esp32-elf-g++",
"compilerArgs": [
"-MMD",
"-w",
"-Werror=return-type",
"-iprefix"
],
"intelliSenseMode": "gcc-x64",
"includePath": [
"/home/derdoktor667/Github/DShotRMT/examples/dshot300",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.5-b66b5448-v1/esp32/qio_qspi/include",
"/home/derdoktor667/.arduino15/packages/esp32/hardware/esp32/3.3.0/cores/esp32",
"/home/derdoktor667/.arduino15/packages/esp32/hardware/esp32/3.3.0/variants/esp32",
"/home/derdoktor667/Arduino/libraries/DShotRMT/src",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/xtensa-esp-elf/include/c++/14.2.0",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/xtensa-esp-elf/include/c++/14.2.0/xtensa-esp-elf/esp32",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/xtensa-esp-elf/include/c++/14.2.0/backward",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/lib/gcc/xtensa-esp-elf/14.2.0/include",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/lib/gcc/xtensa-esp-elf/14.2.0/include-fixed",
"/home/derdoktor667/.arduino15/packages/esp32/tools/esp-x32/2411/xtensa-esp-elf/include"
],
"forcedInclude": [
"/home/derdoktor667/.arduino15/packages/esp32/hardware/esp32/3.3.0/cores/esp32/Arduino.h"
],
"cStandard": "c11",
"cppStandard": "c++11",
"defines": [
"F_CPU=240000000L",
"ARDUINO=10607",
"ARDUINO_ESP32_DEV",
"ARDUINO_ARCH_ESP32",
"ARDUINO_BOARD=\"ESP32_DEV\"",
"ARDUINO_VARIANT=\"esp32\"",
"ARDUINO_PARTITION_default",
"ARDUINO_HOST_OS=\"linux\"",
"ARDUINO_FQBN=\"esp32:esp32:esp32:JTAGAdapter=default,PSRAM=disabled,PartitionScheme=default,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,LoopCore=1,EventsCore=1,DebugLevel=none,EraseFlash=all,ZigbeeMode=default\"",
"ESP32=ESP32",
"CORE_DEBUG_LEVEL=0",
"ARDUINO_RUNNING_CORE=1",
"ARDUINO_EVENT_RUNNING_CORE=1",
"ARDUINO_USB_CDC_ON_BOOT=0",
"__DBL_MIN_EXP__=(-1021)",
"__XCHAL_HAVE_FP=1",
"__cpp_nontype_template_parameter_auto=201606L",
"__UINT_LEAST16_MAX__=0xffff",
"__ATOMIC_ACQUIRE=2",
"__FLT_MIN__=1.1754943508222875e-38F",
"__GCC_IEC_559_COMPLEX=0",
"__XCHAL_HAVE_PREDICTED_BRANCHES=0",
"__cpp_aggregate_nsdmi=201304L",
"__UINT_LEAST8_TYPE__=unsigned char",
"__INTMAX_C(c)=c ## LL",
"__XCHAL_HAVE_ADDX=1",
"__CHAR_BIT__=8",
"__XCHAL_DCACHE_LINESIZE=16",
"__XTENSA_MARCH_EARLIEST=260003",
"__XCHAL_DCACHE_LINEWIDTH=4",
"__UINT8_MAX__=0xff",
"__WINT_MAX__=0xffffffffU",
"__FLT32_MIN_EXP__=(-125)",
"__cpp_static_assert=201411L",
"__ORDER_LITTLE_ENDIAN__=1234",
"__SIZE_MAX__=0xffffffffU",
"__WCHAR_MAX__=0xffff",
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1",
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1",
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1",
"__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
"__GCC_ATOMIC_CHAR_LOCK_FREE=2",
"__GCC_IEC_559=0",
"__FLT32X_DECIMAL_DIG__=17",
"__FLT_EVAL_METHOD__=0",
"__cpp_binary_literals=201304L",
"__FLT64_DECIMAL_DIG__=17",
"__cpp_noexcept_function_type=201510L",
"__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2",
"__cpp_variadic_templates=200704L",
"__UINT_FAST64_MAX__=0xffffffffffffffffULL",
"__SIG_ATOMIC_TYPE__=int",
"__DBL_MIN_10_EXP__=(-307)",
"__FINITE_MATH_ONLY__=0",
"__cpp_variable_templates=201304L",
"__XCHAL_HAVE_L32R=1",
"__FLT32X_MAX_EXP__=1024",
"__GNUC_PATCHLEVEL__=0",
"__FLT32_HAS_DENORM__=1",
"__UINT_FAST8_MAX__=0xffffffffU",
"__cpp_rvalue_reference=200610L",
"__XCHAL_HAVE_LOOPS=1",
"__cpp_nested_namespace_definitions=201411L",
"__XCHAL_DEBUGLEVEL=6",
"__INT8_C(c)=c",
"__XCHAL_HAVE_DFP_RECIP=0",
"__INT_LEAST8_WIDTH__=8",
"__cpp_variadic_using=201611L",
"__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
"__INT_LEAST8_MAX__=0x7f",
"__cpp_attributes=200809L",
"__cpp_capture_star_this=201603L",
"__SHRT_MAX__=0x7fff",
"__LDBL_MAX__=1.7976931348623157e+308L",
"__cpp_if_constexpr=201606L",
"__XCHAL_ICACHE_LINESIZE=16",
"__LDBL_IS_IEC_60559__=1",
"__UINT_LEAST8_MAX__=0xff",
"__GCC_ATOMIC_BOOL_LOCK_FREE=2",
"__UINTMAX_TYPE__=long long unsigned int",
"__cpp_nsdmi=200809L",
"__FLT_EVAL_METHOD_TS_18661_3__=0",
"__UINT32_MAX__=0xffffffffUL",
"__GXX_EXPERIMENTAL_CXX0X__=1",
"__LDBL_MAX_EXP__=1024",
"__WINT_MIN__=0U",
"__FLT32X_IS_IEC_60559__=1",
"__XCHAL_HAVE_THREADPTR=1",
"__INT_LEAST16_WIDTH__=16",
"__SCHAR_MAX__=0x7f",
"__WCHAR_MIN__=0",
"__XCHAL_ICACHE_LINEWIDTH=4",
"__INT64_C(c)=c ## LL",
"__GCC_ATOMIC_POINTER_LOCK_FREE=2",
"__ATOMIC_SEQ_CST=5",
"__SIZEOF_INT__=4",
"__FLT32X_MANT_DIG__=53",
"__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2",
"__cpp_aligned_new=201606L",
"__XCHAL_HAVE_FP_RECIP=1",
"__FLT32_MAX_10_EXP__=38",
"__STDC_HOSTED__=1",
"__XCHAL_HAVE_MUL32=1",
"__XTENSA_EL__=1",
"__cpp_decltype_auto=201304L",
"__DBL_DIG__=15",
"__XCHAL_HAVE_MUL16=1",
"__FLT_EPSILON__=1.1920928955078125e-7F",
"__GXX_WEAK__=1",
"__SHRT_WIDTH__=16",
"__FLT32_IS_IEC_60559__=1",
"__LDBL_MIN__=2.2250738585072014e-308L",
"__DBL_IS_IEC_60559__=1",
"__cpp_threadsafe_static_init=200806L",
"__cpp_enumerator_attributes=201411L",
"__XCHAL_HAVE_MMU=0",
"__FLT32X_HAS_INFINITY__=1",
"__INT32_MAX__=0x7fffffffL",
"__XCHAL_HAVE_DIV32=1",
"__INT_WIDTH__=32",
"__XTENSA_MARCH_LATEST=260003",
"__DECIMAL_DIG__=17",
"__FLT64_EPSILON__=2.2204460492503131e-16F64",
"__INT16_MAX__=0x7fff",
"__FLT64_MIN_EXP__=(-1021)",
"__XCHAL_DCACHE_SIZE=0",
"__LDBL_HAS_QUIET_NAN__=1",
"__cpp_return_type_deduction=201304L",
"__XCHAL_HAVE_BOOLEANS=1",
"__FLT64_MANT_DIG__=53",
"__XTHAL_ABI_WINDOWED=0",
"__GNUC__=14",
"__GXX_RTTI=1",
"__FLT_HAS_DENORM__=1",
"__SIZEOF_LONG_DOUBLE__=8",
"__XCHAL_HAVE_CONST16=0",
"__BIGGEST_ALIGNMENT__=16",
"__STDC_UTF_16__=1",
"__FLT64_MAX_10_EXP__=308",
"__cpp_delegating_constructors=200604L",
"__DBL_MAX__=double(1.7976931348623157e+308L)",
"__cpp_raw_strings=200710L",
"__INT_FAST32_MAX__=0x7fffffff",
"__DBL_HAS_INFINITY__=1",
"__cpp_deduction_guides=201703L",
"__HAVE_SPECULATION_SAFE_VALUE=1",
"__cpp_fold_expressions=201603L",
"__INTPTR_WIDTH__=32",
"__UINT_LEAST32_MAX__=0xffffffffUL",
"__FLT32X_HAS_DENORM__=1",
"__INT_FAST16_TYPE__=int",
"__XCHAL_HAVE_RELEASE_SYNC=1",
"__LDBL_HAS_DENORM__=1",
"__cplusplus=201703L",
"__cpp_ref_qualifiers=200710L",
"__INT_LEAST32_MAX__=0x7fffffffL",
"__DEPRECATED=1",
"__cpp_rvalue_references=200610L",
"__DBL_MAX_EXP__=1024",
"__WCHAR_WIDTH__=16",
"__FLT32_MAX__=3.4028234663852886e+38F32",
"__GCC_ATOMIC_LONG_LOCK_FREE=2",
"__PTRDIFF_MAX__=0x7fffffff",
"__FLT32_HAS_QUIET_NAN__=1",
"__GNUG__=14",
"__LONG_LONG_MAX__=0x7fffffffffffffffLL",
"__SIZEOF_SIZE_T__=4",
"__SIZEOF_WINT_T__=4",
"__FLT32X_DIG__=15",
"__LONG_LONG_WIDTH__=64",
"__cpp_initializer_lists=200806L",
"__FLT32_MAX_EXP__=128",
"__XCHAL_HAVE_MINMAX=1",
"__cpp_hex_float=201603L",
"__XCHAL_NUM_IBREAK=2",
"__GXX_ABI_VERSION=1019",
"__FLT_MIN_EXP__=(-125)",
"__cpp_lambdas=200907L",
"__INT_FAST64_TYPE__=long long int",
"__FP_FAST_FMAF=1",
"__FLT64_DENORM_MIN__=4.9406564584124654e-324F64",
"__DBL_MIN__=double(2.2250738585072014e-308L)",
"__SIZEOF_POINTER__=4",
"__DBL_HAS_QUIET_NAN__=1",
"__FLT32X_EPSILON__=2.2204460492503131e-16F32x",
"__XSHAL_HAVE_TEXT_SECTION_LITERALS=1",
"__FLT64_MIN_10_EXP__=(-307)",
"__REGISTER_PREFIX__",
"__UINT16_MAX__=0xffff",
"__XSHAL_USE_ABSOLUTE_LITERALS=0",
"__LDBL_HAS_INFINITY__=1",
"__FLT32_MIN__=1.1754943508222875e-38F32",
"__UINT8_TYPE__=unsigned char",
"__FLT_DIG__=6",
"__NO_INLINE__=1",
"__DEC_EVAL_METHOD__=2",
"__FLT_MANT_DIG__=24",
"__LDBL_DECIMAL_DIG__=17",
"__VERSION__=\"14.2.0\"",
"__UINT64_C(c)=c ## ULL",
"__XCHAL_NUM_AREGS=64",
"__cpp_unicode_characters=201411L",
"__XCHAL_HAVE_XEA3=0",
"__GCC_ATOMIC_INT_LOCK_FREE=2",
"__XCHAL_HAVE_DENSITY=1",
"__FLT32_MANT_DIG__=24",
"__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
"__XCHAL_HAVE_CLAMPS=0",
"__XCHAL_HAVE_DFP_RSQRT=0",
"__cpp_aggregate_bases=201603L",
"__XCHAL_HAVE_NSA=1",
"__XCHAL_HAVE_WINDOWED=1",
"__SCHAR_WIDTH__=8",
"__INT32_C(c)=c ## L",
"__ORDER_PDP_ENDIAN__=3412",
"__INT_FAST32_TYPE__=int",
"__UINT_LEAST16_TYPE__=short unsigned int",
"__DBL_HAS_DENORM__=1",
"__XCHAL_HAVE_DEBUG=1",
"__cpp_rtti=199711L",
"__SIZE_TYPE__=unsigned int",
"__UINT64_MAX__=0xffffffffffffffffULL",
"__FLT_IS_IEC_60559__=1",
"__GNUC_WIDE_EXECUTION_CHARSET_NAME=\"UTF-16LE\"",
"__INT8_TYPE__=signed char",
"__cpp_digit_separators=201309L",
"__ELF__=1",
"__XSHAL_ABI=0",
"__xtensa__=1",
"__FLT_RADIX__=2",
"__INT_LEAST16_TYPE__=short int",
"__LDBL_EPSILON__=2.2204460492503131e-16L",
"__UINTMAX_C(c)=c ## ULL",
"__FLT32X_MIN__=2.2250738585072014e-308F32x",
"__XCHAL_HAVE_DFP_SQRT=0",
"__SIG_ATOMIC_MAX__=0x7fffffff",
"__XCHAL_HAVE_MAC16=1",
"__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2",
"__USER_LABEL_PREFIX__",
"__SIZEOF_PTRDIFF_T__=4",
"__XCHAL_MMU_MIN_PTE_PAGE_SIZE=1",
"__XCHAL_DCACHE_IS_WRITEBACK=0",
"__SIZEOF_LONG__=4",
"__LDBL_DIG__=15",
"__FLT64_IS_IEC_60559__=1",
"__XCHAL_MAX_INSTRUCTION_SIZE=3",
"__FLT32X_MIN_EXP__=(-1021)",
"__INT_FAST16_MAX__=0x7fffffff",
"__GCC_CONSTRUCTIVE_SIZE=32",
"__FLT64_DIG__=15",
"__UINT_FAST32_MAX__=0xffffffffU",
"__UINT_LEAST64_TYPE__=long long unsigned int",
"__FLT_HAS_QUIET_NAN__=1",
"__FLT_MAX_10_EXP__=38",
"__FLT_HAS_INFINITY__=1",
"__GNUC_EXECUTION_CHARSET_NAME=\"UTF-8\"",
"__CHAR_UNSIGNED__=1",
"__cpp_unicode_literals=200710L",
"__UINT_FAST16_TYPE__=unsigned int",
"__INT_FAST32_WIDTH__=32",
"__CHAR16_TYPE__=short unsigned int",
"__PRAGMA_REDEFINE_EXTNAME=1",
"__SIZE_WIDTH__=32",
"__INT_LEAST16_MAX__=0x7fff",
"__INT64_MAX__=0x7fffffffffffffffLL",
"__FLT32_DENORM_MIN__=1.4012984643248171e-45F32",
"__SIG_ATOMIC_WIDTH__=32",
"__INT_LEAST64_TYPE__=long long int",
"__INT16_TYPE__=short int",
"__INT_LEAST8_TYPE__=signed char",
"__cpp_structured_bindings=201606L",
"__INT_FAST8_MAX__=0x7fffffff",
"__INTPTR_MAX__=0x7fffffff",
"__cpp_sized_deallocation=201309L",
"__cpp_guaranteed_copy_elision=201606L",
"__FLT64_HAS_QUIET_NAN__=1",
"__FLT32_MIN_10_EXP__=(-37)",
"__EXCEPTIONS=1",
"__UINT16_C(c)=c",
"__XCHAL_M_STAGE=3",
"__PTRDIFF_WIDTH__=32",
"__LDBL_MANT_DIG__=53",
"__cpp_range_based_for=201603L",
"__FLT64_HAS_INFINITY__=1",
"__STDCPP_DEFAULT_NEW_ALIGNMENT__=8",
"__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
"__XCHAL_ICACHE_SIZE=0",
"__cpp_nontype_template_args=201411L",
"__INTPTR_TYPE__=int",
"__UINT16_TYPE__=short unsigned int",
"__WCHAR_TYPE__=short unsigned int",
"__XCHAL_HAVE_DEPBITS=0",
"__SIZEOF_FLOAT__=4",
"__UINTPTR_MAX__=0xffffffffU",
"__INT_FAST64_WIDTH__=64",
"__cpp_decltype=200707L",
"__FLT32_DECIMAL_DIG__=9",
"__INT_FAST64_MAX__=0x7fffffffffffffffLL",
"__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
"__FLT_NORM_MAX__=3.4028234663852886e+38F",
"__XCHAL_HAVE_DFP=0",
"__FLT32_HAS_INFINITY__=1",
"__UINT_FAST64_TYPE__=long long unsigned int",
"__cpp_inline_variables=201606L",
"__INT_MAX__=0x7fffffff",
"__XCHAL_HAVE_EXCLUSIVE=0",
"__STDCPP_THREADS__=1",
"__INT64_TYPE__=long long int",
"__XCHAL_HAVE_DFP_DIV=0",
"__FLT_MAX_EXP__=128",
"__XCHAL_INST_FETCH_WIDTH=4",
"__DBL_MANT_DIG__=53",
"__cpp_inheriting_constructors=201511L",
"__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
"__FP_FAST_FMAF32=1",
"__WINT_TYPE__=unsigned int",
"__UINT_LEAST32_TYPE__=long unsigned int",
"__SIZEOF_SHORT__=2",
"__FLT32_NORM_MAX__=3.4028234663852886e+38F32",
"__LDBL_MIN_EXP__=(-1021)",
"__XCHAL_HAVE_S32C1I=1",
"__FLT64_MAX__=1.7976931348623157e+308F64",
"__WINT_WIDTH__=32",
"__cpp_template_auto=201606L",
"__INT_LEAST64_WIDTH__=64",
"__FLT32X_MAX_10_EXP__=308",
"__cpp_namespace_attributes=201411L",
"__WCHAR_UNSIGNED__=1",
"__LDBL_MAX_10_EXP__=308",
"__ATOMIC_RELAXED=0",
"__DBL_EPSILON__=double(2.2204460492503131e-16L)",
"__XCHAL_HAVE_SEXT=1",
"__INT_LEAST32_TYPE__=long int",
"__XTENSA_WINDOWED_ABI__=1",
"__UINT8_C(c)=c",
"__FLT64_MAX_EXP__=1024",
"__SIZEOF_WCHAR_T__=2",
"__XCHAL_HAVE_FP_POSTINC=1",
"__FLT64_NORM_MAX__=1.7976931348623157e+308F64",
"__INTMAX_MAX__=0x7fffffffffffffffLL",
"__INT_FAST8_TYPE__=int",
"__XCHAL_HAVE_MUL32_HIGH=1",
"__GNUC_STDC_INLINE__=1",
"__FLT64_HAS_DENORM__=1",
"__FLT32_EPSILON__=1.1920928955078125e-7F32",
"__DBL_DECIMAL_DIG__=17",
"__STDC_UTF_32__=1",
"__XCHAL_HAVE_FP_DIV=1",
"__INT_FAST8_WIDTH__=32",
"__FLT32X_MAX__=1.7976931348623157e+308F32x",
"__DBL_NORM_MAX__=double(1.7976931348623157e+308L)",
"__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
"__GCC_DESTRUCTIVE_SIZE=32",
"__XTENSA__=1",
"__INTMAX_WIDTH__=64",
"__ORDER_BIG_ENDIAN__=4321",
"__XTHAL_ABI_CALL0=1",
"__cpp_runtime_arrays=198712L",
"__FLT32_DIG__=6",
"__UINT64_TYPE__=long long unsigned int",
"__UINT32_C(c)=c ## UL",
"__cpp_alias_templates=200704L",
"__FLT_DENORM_MIN__=1.4012984643248171e-45F",
"__INT8_MAX__=0x7f",
"__LONG_WIDTH__=32",
"__UINT_FAST32_TYPE__=unsigned int",
"__FLT32X_NORM_MAX__=1.7976931348623157e+308F32x",
"__CHAR32_TYPE__=long unsigned int",
"__FLT_MAX__=3.4028234663852886e+38F",
"__cpp_constexpr=201603L",
"__XCHAL_HAVE_FP_RSQRT=1",
"__INT32_TYPE__=long int",
"__SIZEOF_DOUBLE__=8",
"__cpp_exceptions=199711L",
"__FLT_MIN_10_EXP__=(-37)",
"__FLT64_MIN__=2.2250738585072014e-308F64",
"__INT_LEAST32_WIDTH__=32",
"__INTMAX_TYPE__=long long int",
"__XCHAL_HAVE_ABS=1",
"__FLT32X_HAS_QUIET_NAN__=1",
"__ATOMIC_CONSUME=1",
"__XCHAL_NUM_DBREAK=2",
"__XCHAL_HAVE_WIDE_BRANCHES=0",
"__GNUC_MINOR__=2",
"__INT_FAST16_WIDTH__=32",
"__UINTMAX_MAX__=0xffffffffffffffffULL",
"__FLT32X_DENORM_MIN__=4.9406564584124654e-324F32x",
"__cpp_template_template_args=201611L",
"__DBL_MAX_10_EXP__=308",
"__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
"__INT16_C(c)=c",
"__STDC__=1",
"__PTRDIFF_TYPE__=int",
"__LONG_MAX__=0x7fffffffL",
"__XCHAL_HAVE_FP_SQRT=1",
"__UINT32_TYPE__=long unsigned int",
"__FLT32X_MIN_10_EXP__=(-307)",
"__UINTPTR_TYPE__=unsigned int",
"__LDBL_MIN_10_EXP__=(-307)",
"__cpp_generic_lambdas=201304L",
"__SIZEOF_LONG_LONG__=8",
"__cpp_user_defined_literals=200809L",
"__GCC_ATOMIC_LLONG_LOCK_FREE=1",
"__FLT_DECIMAL_DIG__=9",
"__UINT_FAST16_MAX__=0xffffffffU",
"__LDBL_NORM_MAX__=1.7976931348623157e+308L",
"__GCC_ATOMIC_SHORT_LOCK_FREE=2",
"__XCHAL_HAVE_BE=0",
"__UINT_FAST8_TYPE__=unsigned int",
"__cpp_init_captures=201304L",
"__ATOMIC_ACQ_REL=4",
"__ATOMIC_RELEASE=3",
"USBCON"
]
} }
] ]
} }

View File

@ -16,7 +16,6 @@ Supports all standard DShot modes (150, 300, 600, 1200) and features signal gene
- **All DShot Modes:** DSHOT150, DSHOT300 (default), DSHOT600, DSHOT1200 - **All DShot Modes:** DSHOT150, DSHOT300 (default), DSHOT600, DSHOT1200
- **BiDirectional DShot:** Full support for RPM telemetry feedback - **BiDirectional DShot:** Full support for RPM telemetry feedback
- **Web Control Interface:** Modern responsive web UI with WiFi access point - **Web Control Interface:** Modern responsive web UI with WiFi access point
- **Advanced Command Manager:** High-level API for ESC configuration and control
- **Safety Features:** Arming/disarming system with motor lockout protection - **Safety Features:** Arming/disarming system with motor lockout protection
- **Dual Control Options:** Web interface and serial console control - **Dual Control Options:** Web interface and serial console control
- **Real-time Telemetry:** Live RPM monitoring and data display - **Real-time Telemetry:** Live RPM monitoring and data display
@ -118,11 +117,9 @@ Make sure you are using these libraries for [ESPAsyncWebServer](https://github.c
--- ---
## 📚 Examples ## 📚 Extras
The library includes comprehensive examples: ### Basic DShot Control with Web Interface (`web_control.ino`)
### 1. Basic DShot Control with Web Interface (`web_control.ino`)
- **Web Control Interface:** Modern responsive web UI accessible at `http://10.10.10.1` - **Web Control Interface:** Modern responsive web UI accessible at `http://10.10.10.1`
- **WiFi Access Point:** Creates hotspot "DShotRMT Control" for wireless control - **WiFi Access Point:** Creates hotspot "DShotRMT Control" for wireless control
- **Safety Features:** Arming/disarming system with motor safety lockout - **Safety Features:** Arming/disarming system with motor safety lockout
@ -137,25 +134,6 @@ The library includes comprehensive examples:
- Live RPM monitoring display - Live RPM monitoring display
- Automatic reconnection on connection loss - Automatic reconnection on connection loss
### 2. Advanced Command Management (`command_manager.ino`)
Interactive ESC control with full menu system:
```
=== DShot Command Manager Menu ===
1 - Stop Motor
2 - Activate Beacon 1
3 - Set Normal Spin Direction
4 - Set Reversed Spin Direction
5 - Get ESC Info
6 - Turn LED 0 ON
7 - Turn LED 0 OFF
0 - Emergency Stop
Advanced Commands:
cmd <number> - Send DShot command (0 - 47)
throttle <value> - Set throttle (48 - 2047)
repeat cmd <num> count <count> - Repeat command
```
--- ---
## 🔧 Hardware Configuration ## 🔧 Hardware Configuration

View File

@ -1,345 +0,0 @@
/*
* command_manager.ino
* Example sketch for DShotCommandManager
* Author: Wastl Kraus
* Date: 2025-09-04
* License: MIT
*/
#include <Arduino.h>
#include <DShotRMT.h>
#include <DShotCommandManager.h>
// USB serial port settings
static constexpr auto &USB_SERIAL = Serial0;
static constexpr auto USB_SERIAL_BAUD = 115200;
// Motor configuration
static constexpr auto MOTOR01_PIN = 17;
static constexpr auto IS_BIDIRECTIONAL = false;
// Motor magnet count for RPM calculation
static constexpr auto MOTOR01_MAGNET_COUNT = 14;
// Create motor and command manager instances
DShotRMT motor01(MOTOR01_PIN, DSHOT300, IS_BIDIRECTIONAL);
DShotCommandManager commandManager(motor01);
// Global variable to store the desired continuous throttle value
static volatile uint16_t throttle_now = 0;
// Helper function to print telemetry results
void printTelemetryResult(const dshot_result_t &result)
{
if (result.success && (result.erpm > 0 || result.motor_rpm > 0))
{
USB_SERIAL.printf("Telemetry: eRPM=%u, Motor RPM=%u\n", result.erpm, result.motor_rpm);
}
else
{
USB_SERIAL.printf("Telemetry: FAILED - %s\n", result.msg);
}
}
//
void setup()
{
// Start USB Serial Port
USB_SERIAL.begin(USB_SERIAL_BAUD);
// Initialize DShot
motor01.begin();
// Init Command Manager
commandManager.begin();
// Print Menu
printMenu();
}
//
void loop()
{
// Time Measurement
static uint64_t last_stats_print = 0;
// Check for serial input
if (USB_SERIAL.available() > 0)
{
String input = USB_SERIAL.readStringUntil('\n');
input.trim();
handleUserInput(input);
}
// Continuously send the stored throttle value
if (throttle_now != 0)
{
dshot_result_t result = motor01.sendThrottle(throttle_now);
// Only print errors to avoid spam
if (!result.success)
{
printResult(result);
}
// Print motor stats every 2 seconds
if (esp_timer_get_time() - last_stats_print >= 2000000)
{
motor01.printDShotInfo();
// Get Motor RPM
if (IS_BIDIRECTIONAL)
{
dshot_result_t telem_result = motor01.getTelemetry(MOTOR01_MAGNET_COUNT);
printTelemetryResult(telem_result);
}
// Time Stamp
last_stats_print = esp_timer_get_time();
}
}
}
//
void handleUserInput(const String &input)
{
dshot_result_t cmd_result;
if (input == "1")
{
// Stop motor command should also reset the continuous throttle value
throttle_now = 0;
USB_SERIAL.print("Stopping motor... ");
cmd_result = commandManager.stopMotor();
printResult(cmd_result);
return;
}
if (input == "2")
{
USB_SERIAL.print("Activating beacon 1... ");
cmd_result = commandManager.activateBeacon(1);
printResult(cmd_result);
return;
}
if (input == "3")
{
USB_SERIAL.print("Setting normal spin direction... ");
cmd_result = commandManager.setSpinDirection(false);
printResult(cmd_result);
return;
}
if (input == "4")
{
USB_SERIAL.print("Setting reversed spin direction... ");
cmd_result = commandManager.setSpinDirection(true);
printResult(cmd_result);
return;
}
if (input == "5")
{
USB_SERIAL.print("Getting ESC Info... ");
cmd_result = commandManager.requestESCInfo();
printResult(cmd_result);
return;
}
if (input == "6")
{
USB_SERIAL.print("Turning LED 0 ON... ");
cmd_result = commandManager.setLED(0, true);
printResult(cmd_result);
return;
}
if (input == "7")
{
USB_SERIAL.print("Turning LED 0 OFF... ");
cmd_result = commandManager.setLED(0, false);
printResult(cmd_result);
return;
}
if (input == "h" || input == "help")
{
printMenu();
return;
}
if (input == "info")
{
motor01.printDShotInfo();
return;
}
if (input == "rpm" && IS_BIDIRECTIONAL)
{
dshot_result_t result = motor01.getTelemetry(MOTOR01_MAGNET_COUNT);
printTelemetryResult(result);
return;
}
if (input.startsWith("cmd "))
{
// Direct command execution: "cmd 5" sends command 5
int cmd_num = input.substring(4).toInt();
if (DShotCommandManager::isValidCommand(static_cast<dshot_commands_t>(cmd_num)))
{
USB_SERIAL.printf("Sending command %d (%s)... ", cmd_num,
DShotCommandManager::getCommandName(static_cast<dshot_commands_t>(cmd_num)));
cmd_result = commandManager.sendCommand(static_cast<dshot_commands_t>(cmd_num));
printResult(cmd_result);
}
else
{
USB_SERIAL.printf("Invalid command number: %d (valid range: 0 - %d)\n", cmd_num, DSHOT_CMD_MAX);
}
return;
}
if (input.startsWith("throttle "))
{
// Throttle control: "throttle 1000" sets throttle to 1000
int throttle_value = input.substring(9).toInt();
if (throttle_value >= DSHOT_THROTTLE_MIN && throttle_value <= DSHOT_THROTTLE_MAX)
{
throttle_now = throttle_value;
USB_SERIAL.printf("Setting continuous throttle to %d\n", throttle_now);
// Send first throttle command and show result
dshot_result_t result = motor01.sendThrottle(throttle_now);
printResult(result);
if (result.success)
{
USB_SERIAL.println("Continuous throttle mode enabled. Send '0' or 'throttle 0' to stop.");
}
return;
}
if (throttle_value == 0)
{
throttle_now = 0;
USB_SERIAL.println("Continuous throttle stopped.");
// Send stop command
dshot_result_t result = motor01.sendCommand(DSHOT_CMD_MOTOR_STOP);
printResult(result);
return;
}
USB_SERIAL.printf("Invalid throttle value: %d (valid range: %d-%d, use 0 to stop)\n",
throttle_value, DSHOT_THROTTLE_MIN, DSHOT_THROTTLE_MAX);
return;
}
if (input == "0")
{
// Quick stop
throttle_now = 0;
USB_SERIAL.print("Emergency stop... ");
dshot_result_t result = motor01.sendCommand(DSHOT_CMD_MOTOR_STOP);
printResult(result);
return;
}
if (input.startsWith("repeat "))
{
// Repeat command: "repeat cmd 5 count 10" - sends command 5 ten times
String params = input.substring(7);
if (!params.startsWith("cmd "))
{
USB_SERIAL.println("Usage: repeat cmd <number> count <repeat_count>");
return;
}
int space_pos = params.indexOf(' ', 4);
if (space_pos <= 0 || !params.substring(space_pos + 1).startsWith("count "))
{
USB_SERIAL.println("Usage: repeat cmd <number> count <repeat_count>");
return;
}
int cmd_num = params.substring(4, space_pos).toInt();
int repeat_count = params.substring(space_pos + 7).toInt();
if (!DShotCommandManager::isValidCommand(static_cast<dshot_commands_t>(cmd_num)) ||
repeat_count <= 0 || repeat_count > 100)
{
USB_SERIAL.println("Invalid command or repeat count (1-100)");
return;
}
USB_SERIAL.printf("Sending command %d (%s) %d times... ", cmd_num,
DShotCommandManager::getCommandName(static_cast<dshot_commands_t>(cmd_num)),
repeat_count);
cmd_result = commandManager.sendCommand(static_cast<dshot_commands_t>(cmd_num), repeat_count);
printResult(cmd_result);
return;
}
// Unknown command
USB_SERIAL.printf("Unknown command: '%s'. Type 'h' or 'help' for help.\n", input.c_str());
}
//
void printResult(const dshot_result_t &result)
{
if (result.success)
{
USB_SERIAL.printf("SUCCESS\n");
}
else
{
USB_SERIAL.printf("FAILED - %s \n", result.msg);
}
}
//
void printSystemStatus()
{
USB_SERIAL.println("\n=== System Status ===");
USB_SERIAL.printf("Current throttle: %u\n", throttle_now);
USB_SERIAL.printf("Continuous mode: %s\n", throttle_now > 0 ? "ACTIVE" : "INACTIVE");
USB_SERIAL.printf("Free heap: %u bytes\n", ESP.getFreeHeap());
USB_SERIAL.printf("Uptime: %lu seconds\n", millis() / 1000);
}
//
void printMenu()
{
USB_SERIAL.println("**********************************************");
USB_SERIAL.println(" DShot Command Manager Menu ");
USB_SERIAL.println("**********************************************");
USB_SERIAL.println(" 1 - Stop Motor");
USB_SERIAL.println(" 2 - Activate Beacon 1");
USB_SERIAL.println(" 3 - Set Normal Spin");
USB_SERIAL.println(" 4 - Set Reversed Spin");
USB_SERIAL.println(" 5 - Get ESC Info");
USB_SERIAL.println(" 6 - Turn LED 0 ON");
USB_SERIAL.println(" 7 - Turn LED 0 OFF");
USB_SERIAL.println(" 0 - Emergency Stop");
USB_SERIAL.println("**********************************************");
USB_SERIAL.println(" cmd <number> - Send Command (0 - 47)");
USB_SERIAL.println(" throttle <value> - Set throttle (48 - 2047)");
USB_SERIAL.println("**********************************************");
USB_SERIAL.println(" info - Show DShot signal info");
USB_SERIAL.println(" status - Show system status");
if (IS_BIDIRECTIONAL)
{
USB_SERIAL.println(" rpm - Get telemetry data");
}
USB_SERIAL.println(" h / help - Show this Menu");
USB_SERIAL.println("**********************************************");
USB_SERIAL.println("EXAMPLE INPUT:");
USB_SERIAL.println(" cmd 5 - Get ESC Info");
USB_SERIAL.println(" throttle 1000 - Set throttle to 1000");
USB_SERIAL.println("**********************************************");
}

View File

@ -8,4 +8,4 @@ paragraph=This library can control a BlHeli_S by using encoded DShot commands. F
category=Signal Input/Output category=Signal Input/Output
url=https://github.com/derdoktor667/DShotRMT url=https://github.com/derdoktor667/DShotRMT
architectures=esp32 architectures=esp32
provides_includes=DShotRMT.h, DShotCommandManager.h, dshot_commands.h, web_content.h, ota_update.h provides_includes=DShotRMT.h, dshot_commands.h, web_content.h, ota_update.h

View File

@ -1,347 +0,0 @@
/*
* DShotCommandManager.cpp
* Advanced DShot command management for DShotRMT library
* Author: Wastl Kraus
* Date: 2025-09-04
* License: MIT
*/
#include <DShotCommandManager.h>
// Constructor
DShotCommandManager::DShotCommandManager(DShotRMT &dshot_instance)
: _dshot(dshot_instance),
_total_commands_sent(0),
_failed_commands(0),
_last_command_timestamp(0)
{
}
// Init command manager
dshot_result_t DShotCommandManager::begin()
{
dshot_result_t result;
result.success = true;
result.msg = "Success";
return result;
}
// --- BASIC COMMAND METHODS ---
dshot_result_t DShotCommandManager::sendCommand(dshot_commands_t command, uint16_t repeat_count)
{
return sendCommandWithDelay(command, repeat_count, DEFAULT_COMMAND_DELAY_MS);
}
//
dshot_result_t DShotCommandManager::sendCommandWithDelay(dshot_commands_t command, uint16_t repeat_count, uint32_t delay_ms)
{
dshot_result_t result = {false, "Unknown error"};
if (!isValidCommand(command))
{
result.msg = "Invalid command";
return result;
}
bool all_successful = true;
// Send command multiple times with delay
for (uint16_t i = 0; i < repeat_count; i++)
{
dshot_result_t single_result = _executeCommand(command);
if (!single_result.success)
{
all_successful = false;
result.msg = single_result.msg;
break;
}
// Add delay between repetitions (except for last repetition)
if (i < repeat_count - 1)
{
_delay_ms(delay_ms);
}
}
//
result.success = all_successful;
if (result.success)
{
result.msg = "Success";
}
return result;
}
// --- MOTOR CONTROL COMMANDS ---
dshot_result_t DShotCommandManager::stopMotor()
{
return sendCommand(DSHOT_CMD_MOTOR_STOP);
}
//
dshot_result_t DShotCommandManager::set3DMode(bool enable)
{
dshot_commands_t command = enable ? DSHOT_CMD_3D_MODE_ON : DSHOT_CMD_3D_MODE_OFF;
return sendCommandWithDelay(command, SETTINGS_COMMAND_REPEATS, SETTINGS_COMMAND_DELAY_MS);
}
//
dshot_result_t DShotCommandManager::setSpinDirection(bool reversed)
{
dshot_commands_t command = reversed ? DSHOT_CMD_SPIN_DIRECTION_REVERSED : DSHOT_CMD_SPIN_DIRECTION_NORMAL;
return sendCommandWithDelay(command, SETTINGS_COMMAND_REPEATS, SETTINGS_COMMAND_DELAY_MS);
}
//
dshot_result_t DShotCommandManager::saveSettings()
{
return sendCommandWithDelay(DSHOT_CMD_SAVE_SETTINGS, SETTINGS_COMMAND_REPEATS, SETTINGS_COMMAND_DELAY_MS);
}
// --- TELEMETRY COMMANDS ---
dshot_result_t DShotCommandManager::setExtendedTelemetry(bool enable)
{
dshot_commands_t command = enable ? DSHOT_CMD_EXTENDED_TELEMETRY_ENABLE : DSHOT_CMD_EXTENDED_TELEMETRY_DISABLE;
return sendCommand(command);
}
//
dshot_result_t DShotCommandManager::requestESCInfo()
{
return sendCommand(DSHOT_CMD_ESC_INFO);
}
// --- LED CONTROL COMMANDS ---
dshot_result_t DShotCommandManager::setLED(uint8_t led_number, bool state)
{
if (led_number > 3)
{
dshot_result_t result = {false, "Invalid LED number (0-3)"};
return result;
}
dshot_commands_t command;
if (state)
{
// LED ON commands
switch (led_number)
{
case 0:
command = DSHOT_CMD_LED0_ON;
break;
case 1:
command = DSHOT_CMD_LED1_ON;
break;
case 2:
command = DSHOT_CMD_LED2_ON;
break;
case 3:
command = DSHOT_CMD_LED3_ON;
break;
}
}
else
{
// LED OFF commands
switch (led_number)
{
case 0:
command = DSHOT_CMD_LED0_OFF;
break;
case 1:
command = DSHOT_CMD_LED1_OFF;
break;
case 2:
command = DSHOT_CMD_LED2_OFF;
break;
case 3:
command = DSHOT_CMD_LED3_OFF;
break;
}
}
return sendCommand(command);
}
// --- BEACON COMMANDS ---
dshot_result_t DShotCommandManager::activateBeacon(uint8_t beacon_number)
{
if (beacon_number < 1 || beacon_number > 5)
{
dshot_result_t result = {false, "Invalid beacon number (1-5)"};
return result;
}
dshot_commands_t command = static_cast<dshot_commands_t>(DSHOT_CMD_BEACON1 + beacon_number - 1);
return sendCommand(command);
}
// --- KISS ESC SPECIFIC COMMANDS ---
dshot_result_t DShotCommandManager::setAudioStreamMode(bool enable)
{
// KISS audio stream mode is a toggle command
return sendCommand(DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF);
}
//
dshot_result_t DShotCommandManager::setSilentMode(bool enable)
{
// KISS silent mode is a toggle command
return sendCommand(DSHOT_CMD_SILENT_MODE_ON_OFF);
}
// --- SEQUENCE COMMANDS ---
dshot_result_t DShotCommandManager::executeSequence(const dshot_commandmanager_item_t *sequence, size_t sequence_length)
{
dshot_result_t result = {true, "Success"};
uint64_t total_start_time = esp_timer_get_time();
for (size_t i = 0; i < sequence_length; i++)
{
dshot_result_t item_result = sendCommandWithDelay(
sequence[i].command,
sequence[i].repeat_count,
DEFAULT_COMMAND_DELAY_MS);
if (!item_result.success)
{
result.success = false;
result.msg = item_result.msg;
break;
}
// Add delay after command if specified
if (sequence[i].delay_ms > 0)
{
_delay_ms(sequence[i].delay_ms);
}
}
uint64_t total_end_time = esp_timer_get_time();
return result;
}
//
dshot_result_t DShotCommandManager::executeInitSequence()
{
// Basic ESC initialization sequence
dshot_commandmanager_item_t init_sequence[] = {
{DSHOT_CMD_MOTOR_STOP, 5, 100}, // Stop motor, repeat 5 times, wait 100ms
{DSHOT_CMD_EXTENDED_TELEMETRY_ENABLE, 1, 50}, // Enable telemetry, wait 50ms
{DSHOT_CMD_ESC_INFO, 1, 100} // Request ESC info, wait 100ms
};
return executeSequence(init_sequence, sizeof(init_sequence) / sizeof(init_sequence[0]));
}
//
dshot_result_t DShotCommandManager::executeCalibrationSequence()
{
// Basic ESC calibration sequence
dshot_commandmanager_item_t calibration_sequence[] = {
{DSHOT_CMD_MOTOR_STOP, 10, 500}, // Ensure motor is stopped
{DSHOT_CMD_SPIN_DIRECTION_NORMAL, 10, 100}, // Set normal spin direction
{DSHOT_CMD_3D_MODE_OFF, 10, 100}, // Disable 3D mode
{DSHOT_CMD_SAVE_SETTINGS, 10, 1000}, // Save settings
{DSHOT_CMD_MOTOR_STOP, 5, 100} // Final stop
};
return executeSequence(calibration_sequence, sizeof(calibration_sequence) / sizeof(calibration_sequence[0]));
}
// --- UTILITY METHODS ---
const char *DShotCommandManager::getCommandName(dshot_commands_t command)
{
switch (command)
{
case DSHOT_CMD_MOTOR_STOP:
return "MOTOR_STOP";
case DSHOT_CMD_BEACON1:
return "BEACON1";
case DSHOT_CMD_BEACON2:
return "BEACON2";
case DSHOT_CMD_BEACON3:
return "BEACON3";
case DSHOT_CMD_BEACON4:
return "BEACON4";
case DSHOT_CMD_BEACON5:
return "BEACON5";
case DSHOT_CMD_ESC_INFO:
return "ESC_INFO";
case DSHOT_CMD_SPIN_DIRECTION_1:
return "SPIN_DIRECTION_1";
case DSHOT_CMD_SPIN_DIRECTION_2:
return "SPIN_DIRECTION_2";
case DSHOT_CMD_3D_MODE_OFF:
return "3D_MODE_OFF";
case DSHOT_CMD_3D_MODE_ON:
return "3D_MODE_ON";
case DSHOT_CMD_SETTINGS_REQUEST:
return "SETTINGS_REQUEST";
case DSHOT_CMD_SAVE_SETTINGS:
return "SAVE_SETTINGS";
case DSHOT_CMD_EXTENDED_TELEMETRY_ENABLE:
return "EXTENDED_TELEMETRY_ENABLE";
case DSHOT_CMD_EXTENDED_TELEMETRY_DISABLE:
return "EXTENDED_TELEMETRY_DISABLE";
case DSHOT_CMD_SPIN_DIRECTION_NORMAL:
return "SPIN_DIRECTION_NORMAL";
case DSHOT_CMD_SPIN_DIRECTION_REVERSED:
return "SPIN_DIRECTION_REVERSED";
case DSHOT_CMD_LED0_ON:
return "LED0_ON";
case DSHOT_CMD_LED1_ON:
return "LED1_ON";
case DSHOT_CMD_LED2_ON:
return "LED2_ON";
case DSHOT_CMD_LED3_ON:
return "LED3_ON";
case DSHOT_CMD_LED0_OFF:
return "LED0_OFF";
case DSHOT_CMD_LED1_OFF:
return "LED1_OFF";
case DSHOT_CMD_LED2_OFF:
return "LED2_OFF";
case DSHOT_CMD_LED3_OFF:
return "LED3_OFF";
case DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF:
return "AUDIO_STREAM_MODE_ON_OFF";
case DSHOT_CMD_SILENT_MODE_ON_OFF:
return "SILENT_MODE_ON_OFF";
default:
return "UNKNOWN";
}
}
//
bool DShotCommandManager::isValidCommand(dshot_commands_t command)
{
return (command >= DSHOT_CMD_MOTOR_STOP && command <= DSHOT_CMD_MAX);
}
// --- PRIVATE METHODS ---
dshot_result_t DShotCommandManager::_executeCommand(dshot_commands_t command)
{
uint64_t start_time = esp_timer_get_time();
// Execute the command using the DShotRMT instance
dshot_result_t result = _dshot.sendCommand(static_cast<uint16_t>(command));
uint64_t end_time = esp_timer_get_time();
_last_command_timestamp = end_time;
return result;
}
//
void DShotCommandManager::_delay_ms(uint32_t delay_ms)
{
if (delay_ms > 0)
{
delay(delay_ms);
}
}

View File

@ -1,123 +0,0 @@
/*
* DShotCommandManager.h
* Advanced DShot command management for DShotRMT library
* Author: Wastl Kraus
* Date: 2025-09-04
* License: MIT
*/
#pragma once
#include <Arduino.h>
#include <DShotRMT.h>
// Command item
typedef struct
{
dshot_commands_t command;
uint16_t repeat_count;
uint32_t delay_ms;
} dshot_commandmanager_item_t;
// Advanced DShot command manager class
class DShotCommandManager
{
public:
// Constructor
explicit DShotCommandManager(DShotRMT &dshot_instance);
// Initialize command manager
dshot_result_t begin();
void handleMenuInput(const String &input, Stream &output = Serial);
// Send a single DShot command
dshot_result_t sendCommand(dshot_commands_t command, uint16_t repeat_count = 1);
// Send command with specified delay between repetitions
dshot_result_t sendCommandWithDelay(dshot_commands_t command, uint16_t repeat_count, uint32_t delay_ms);
// --- MOTOR CONTROL COMMANDS ---
// Stop motor (send MOTOR_STOP command)
dshot_result_t stopMotor();
// Enable/disable 3D mode
dshot_result_t set3DMode(bool enable);
// Set motor spin direction
dshot_result_t setSpinDirection(bool reversed);
// Save current settings to ESC
dshot_result_t saveSettings();
// --- TELEMETRY COMMANDS ---
// Enable/disable extended telemetry
dshot_result_t setExtendedTelemetry(bool enable);
// Request ESC information
dshot_result_t requestESCInfo();
// --- LED CONTROL COMMANDS (BLHeli32 only) ---
// Control ESC LEDs (BLHeli32 only)
dshot_result_t setLED(uint8_t led_number, bool state);
// --- BEACON COMMANDS ---
// Activate beacon (motor beeping)
dshot_result_t activateBeacon(uint8_t beacon_number);
// --- KISS ESC SPECIFIC COMMANDS ---
// Enable/disable audio stream mode (KISS ESCs)
dshot_result_t setAudioStreamMode(bool enable);
// Enable/disable silent mode (KISS ESCs)
dshot_result_t setSilentMode(bool enable);
// --- SEQUENCE COMMANDS ---
// Execute a sequence of DShot commands
dshot_result_t executeSequence(const dshot_commandmanager_item_t *sequence, size_t sequence_length);
// Execute ESC initialization sequence
dshot_result_t executeInitSequence();
// Execute ESC calibration sequence
dshot_result_t executeCalibrationSequence();
// --- UTILITY METHODS ---
// Get command name as string
static const char *getCommandName(dshot_commands_t command);
// Check if command is valid
static bool isValidCommand(dshot_commands_t command);
// --- GETTERS ---
// Get total number of commands sent
uint32_t getTotalCommandCount() const { return _total_commands_sent; }
// Get number of failed commands
uint32_t getFailedCommandCount() const { return _failed_commands; }
// Get reference to underlying DShotRMT instance
DShotRMT &getDShotRMT() { return _dshot; }
const DShotRMT &getDShotRMT() const { return _dshot; }
private:
// --- PRIVATE MEMBERS ---
DShotRMT &_dshot; // Reference to DShotRMT instance
uint32_t _total_commands_sent; // Total commands sent counter
uint32_t _failed_commands; // Failed commands counter
uint64_t _last_command_timestamp; // Timestamp of last command
// --- PRIVATE METHODS ---
// Execute single command with timing
dshot_result_t _executeCommand(dshot_commands_t command);
// Wait for specified delay
void _delay_ms(uint32_t delay_ms);
// --- CONSTANTS ---
static constexpr uint32_t DEFAULT_COMMAND_DELAY_MS = 10;
static constexpr uint16_t DEFAULT_REPEAT_COUNT = 1;
static constexpr uint16_t SETTINGS_COMMAND_REPEATS = 10; // Settings commands need 10 repeats
static constexpr uint32_t SETTINGS_COMMAND_DELAY_MS = 5;
};

View File

@ -42,6 +42,7 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional)
_rmt_ticks{0}, _rmt_ticks{0},
_last_throttle(DSHOT_CMD_MOTOR_STOP), _last_throttle(DSHOT_CMD_MOTOR_STOP),
_last_transmission_time_us(0), _last_transmission_time_us(0),
_last_command_timestamp(0),
_parsed_packet(0), _parsed_packet(0),
_packet{0}, _packet{0},
_bitPositions{0}, _bitPositions{0},
@ -154,6 +155,49 @@ dshot_result_t DShotRMT::sendCommand(uint16_t command)
return _sendDShotFrame(_packet); return _sendDShotFrame(_packet);
} }
// Send full DShot commands for setup etc
dshot_result_t DShotRMT::sendCommand(dshot_commands_t dshot_command, uint16_t repeat_count, uint16_t delay_us)
{
dshot_result_t result = {false, UNKNOWN_ERROR};
if (!_isValidCommand(dshot_command))
{
result.msg = INVALID_COMMAND;
return result;
}
bool all_successful = true;
// Send command multiple times with delay
for (uint16_t i = 0; i < repeat_count; i++)
{
dshot_result_t single_result = _executeCommand(dshot_command);
if (!single_result.success)
{
all_successful = false;
result.msg = single_result.msg;
break;
}
// Add delay between repetitions (except for last repetition)
if (i < repeat_count - 1)
{
delayMicroseconds(delay_us);
}
}
//
result.success = all_successful;
if (result.success)
{
result.msg = COMMAND_SUCCESS;
}
return result;
}
// Get telemetry data // Get telemetry data
dshot_result_t DShotRMT::getTelemetry(uint16_t magnet_count) dshot_result_t DShotRMT::getTelemetry(uint16_t magnet_count)
{ {
@ -187,6 +231,26 @@ dshot_result_t DShotRMT::getTelemetry(uint16_t magnet_count)
return result; return result;
} }
// Reverse motor direction directly
dshot_result_t DShotRMT::setMotorSpinDirection(bool reversed)
{
// Use command as a yes / no switch
dshot_commands_t command = reversed ? DSHOT_CMD_SPIN_DIRECTION_REVERSED : DSHOT_CMD_SPIN_DIRECTION_NORMAL;
return sendCommand(command, SETTINGS_COMMAND_REPEATS, SETTINGS_COMMAND_DELAY_US);
}
dshot_result_t DShotRMT::getESCInfo()
{
return sendCommand(DSHOT_CMD_ESC_INFO);
}
// Use with caution
dshot_result_t DShotRMT::saveESCSettings()
{
return sendCommand(DSHOT_CMD_SAVE_SETTINGS, SETTINGS_COMMAND_REPEATS, SETTINGS_COMMAND_DELAY_US);
}
// Public Info & Debug Functions // Public Info & Debug Functions
void DShotRMT::printDShotInfo(Stream &output) const void DShotRMT::printDShotInfo(Stream &output) const
{ {
@ -218,6 +282,26 @@ void DShotRMT::printCpuInfo(Stream &output) const
output.printf("APB Freq = %lu Hz\n", getApbFrequency()); output.printf("APB Freq = %lu Hz\n", getApbFrequency());
} }
// Simple check
bool DShotRMT::_isValidCommand(dshot_commands_t command)
{
return (command >= DSHOT_CMD_MOTOR_STOP && command <= DSHOT_CMD_MAX);
}
//
dshot_result_t DShotRMT::_executeCommand(dshot_commands_t command)
{
uint64_t start_time = esp_timer_get_time();
// Execute the command using the DShotRMT instance
dshot_result_t result = sendCommand(static_cast<uint16_t>(command));
uint64_t end_time = esp_timer_get_time();
_last_command_timestamp = end_time;
return result;
}
// Private Initialization Functions // Private Initialization Functions
dshot_result_t DShotRMT::_initTXChannel() dshot_result_t DShotRMT::_initTXChannel()
{ {
@ -371,7 +455,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
// Ensure enough time has passed since the last transmission // Ensure enough time has passed since the last transmission
if (!_timer_signal()) if (!_timer_signal())
{ {
return {false, TIMING_CORRECTION}; return {true, NONE};
} }
rmt_symbol_word_t tx_symbols[DSHOT_BITS_PER_FRAME]; rmt_symbol_word_t tx_symbols[DSHOT_BITS_PER_FRAME];

View File

@ -91,9 +91,13 @@ public:
dshot_result_t begin(); dshot_result_t begin();
dshot_result_t sendThrottle(uint16_t throttle); dshot_result_t sendThrottle(uint16_t throttle);
dshot_result_t sendCommand(uint16_t command); dshot_result_t sendCommand(uint16_t command);
dshot_result_t sendCommand(dshot_commands_t dshot_command, uint16_t repeat_count = DEFAULT_CMD_REPEAT_COUNT, uint16_t delay_us = DEFAULT_CMD_DELAY_US);
dshot_result_t getTelemetry(uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT); dshot_result_t getTelemetry(uint16_t magnet_count = DEFAULT_MOTOR_MAGNET_COUNT);
dshot_result_t getESCInfo();
dshot_result_t setMotorSpinDirection(bool reversed);
dshot_result_t saveESCSettings();
// Public Info & Debug Functions // Public Utility & Info Functions
void printDShotInfo(Stream &output = Serial) const; void printDShotInfo(Stream &output = Serial) const;
void printCpuInfo(Stream &output = Serial) const; void printCpuInfo(Stream &output = Serial) const;
@ -129,14 +133,14 @@ private:
static constexpr auto const RMT_TICKS_PER_US = DSHOT_RMT_RESOLUTION / (1 * 1000 * 1000); // RMT Ticks per microsecond static constexpr auto const RMT_TICKS_PER_US = DSHOT_RMT_RESOLUTION / (1 * 1000 * 1000); // RMT Ticks per microsecond
static constexpr auto const DSHOT_RX_TIMEOUT_MS = 2; static constexpr auto const DSHOT_RX_TIMEOUT_MS = 2;
static constexpr auto const DSHOT_PADDING_US = 20; // Add to pause between frames for compatibility static constexpr auto const DSHOT_PADDING_US = 20; // Add to pause between frames for compatibility
static constexpr auto const RMT_BUFFER_SYMBOLS = 192; static constexpr auto const RMT_BUFFER_SYMBOLS = 128;
static constexpr auto const RMT_QUEUE_DEPTH = 4; static constexpr auto const RMT_QUEUE_DEPTH = 1;
static constexpr auto const GCR_BITS_PER_FRAME = 21; // Number of GCR bits in a DShot answer frame static constexpr auto const GCR_BITS_PER_FRAME = 21; // Number of GCR bits in a DShot answer frame
static constexpr auto const POLE_PAIRS_MIN = 1; static constexpr auto const POLE_PAIRS_MIN = 1;
static constexpr auto const MAGNETS_PER_POLE_PAIR = 2; static constexpr auto const MAGNETS_PER_POLE_PAIR = 2;
static constexpr auto const NO_DSHOT_TELEMETRY = 0; static constexpr auto const NO_DSHOT_TELEMETRY = 0;
static constexpr auto const DSHOT_PULSE_MIN = 1000; // 1.0us minimum pulse static constexpr auto const DSHOT_PULSE_MIN = 800; // 0.8us minimum pulse
static constexpr auto const DSHOT_PULSE_MAX = 8000; // 10.0us maximum pulse static constexpr auto const DSHOT_PULSE_MAX = 8000; // 8.0us maximum pulse
static constexpr auto const DSHOT_TELEMETRY_INVALID = DSHOT_THROTTLE_MAX; static constexpr auto const DSHOT_TELEMETRY_INVALID = DSHOT_THROTTLE_MAX;
// Error Messages // Error Messages
@ -162,6 +166,12 @@ private:
static constexpr char const *INVALID_MAGNET_COUNT = "Invalid motor magnet count!"; static constexpr char const *INVALID_MAGNET_COUNT = "Invalid motor magnet count!";
static constexpr char const *TIMING_CORRECTION = "Timing correction!"; static constexpr char const *TIMING_CORRECTION = "Timing correction!";
static constexpr char const *CALLBACK_REGISTERING_FAILED = "RMT RX Callback registering failed!"; static constexpr char const *CALLBACK_REGISTERING_FAILED = "RMT RX Callback registering failed!";
static constexpr char const *INVALID_COMMAND = "Invalid command!";
static constexpr char const *COMMAND_SUCCESS = "DShot command sent successfully";
// --- UTILITY METHODS ---
bool _isValidCommand(dshot_commands_t command);
dshot_result_t _executeCommand(dshot_commands_t command);
// Core Configuration Variables // Core Configuration Variables
gpio_num_t _gpio; gpio_num_t _gpio;
@ -174,6 +184,7 @@ private:
rmt_ticks_t _rmt_ticks; rmt_ticks_t _rmt_ticks;
uint16_t _last_throttle; uint16_t _last_throttle;
uint64_t _last_transmission_time_us; uint64_t _last_transmission_time_us;
uint64_t _last_command_timestamp;
uint16_t _parsed_packet; uint16_t _parsed_packet;
dshot_packet_t _packet; dshot_packet_t _packet;
uint8_t _bitPositions[DSHOT_BITS_PER_FRAME]; uint8_t _bitPositions[DSHOT_BITS_PER_FRAME];
@ -219,4 +230,10 @@ private:
// Static Callback Functions // Static Callback Functions
static bool _on_rx_done(rmt_channel_handle_t rmt_rx_channel, const rmt_rx_done_event_data_t *edata, void *user_data); static bool _on_rx_done(rmt_channel_handle_t rmt_rx_channel, const rmt_rx_done_event_data_t *edata, void *user_data);
// Command Constants
static constexpr auto DEFAULT_CMD_DELAY_US = 10;
static constexpr auto DEFAULT_CMD_REPEAT_COUNT = 1;
static constexpr auto SETTINGS_COMMAND_REPEATS = 10; // Settings commands need 10 repeats
static constexpr auto SETTINGS_COMMAND_DELAY_US = 5;
}; };