Unresponsive polling from FPV Racing 4-in-1 ESC
-
Hello,
I'm calibrating the FPV Racing 4-in-1 ESC on the VOXL2 itself (not connected directly to the ESC via FTDI). When performing either the calibration (
./voxl-esc-calibrate.py --id 2 --pwm-min 10 --pwm-max 95
) or the power ramp test (./voxl-esc-spin.py --id 2 --power 100 --ramp-time 3.0 --timeout 5.0 --enable-plot 1 --cmd-rate 250
), there are several instances were the y-values do not change for secondsThe behavior is more readily seen in the power ramp test, since commanded values are continuous, whereas in the calibration test, a specific value is commanded for a given time period. Still, you can see in the calibration results that y value doesn't change any for far longer than the default step duration of 0.5 seconds
Looking at the calibrate script, seems that the returned values from:
esc.get_current()
esc.get_power()
esc.get_rpm()
esc.get_voltage()
esc.get_temperature()
are directly print to terminal, and not some other variable hanging around that maybe doesn't update.
@Alex-Kushleyev has this behavior been seen? Any recommendations? It is difficult to tune commutation when values are not updated. The interesting pattern showing itself through repeated runs of the script is that the "duration unresponsiveness" increases as commanded power increases
The following is output from
voxl-esc scan
:voxl2:/usr/share/modalai/voxl-esc-tools$ voxl-esc scan enabling bridge bridge enabled Detected Python version : 3.6.9 (default, Mar 10 2023, 16:46:00) [GCC 8.4.0] Found voxl-esc tools bin version: 1.9 VOXL Platform: M0054 Detected RB5 Flight, VOXL2 M0054 or M0104! INFO: Scanning for ESC firmware: /dev/slpi-uart-2, baud: 2000000 Sending library name request: libslpi_qrb5165_io.so Sending initialization request INFO: ESC(s) detected on port: /dev/slpi-uart-2, baud rate: 2000000, protocol: firmware INFO: ESC Information: INFO: --------------------- ID : 0 Board : version 42: ModalAi 4-in-1 ESC (M0138-1) UID : 0x20373835464757130049002F Firmware : version 39.20, hash 9c6233d6 Bootloader : version 184, hash e1c038de ID : 1 Board : version 42: ModalAi 4-in-1 ESC (M0138-1) UID : 0x203738354647571300420025 Firmware : version 39.20, hash 9c6233d6 Bootloader : version 184, hash e1c038de ID : 2 Board : version 42: ModalAi 4-in-1 ESC (M0138-1) UID : 0x20373835464757130049002A Firmware : version 39.20, hash 9c6233d6 Bootloader : version 184, hash e1c038de ID : 3 Board : version 42: ModalAi 4-in-1 ESC (M0138-1) UID : 0x20373835464757130042002A Firmware : version 39.20, hash 9c6233d6 Bootloader : version 184, hash e1c038de --------------------- successfully pinged ESCs disabling bridge Sending kill slpi command! bridge disabled
I've also included the xml, calibration_results.html, and spin_results.html
The motor is a Hobbyking CM X6 SE 280KV, a low KV motor.
I am following the steps outlined in:
- calibration.md
- low_kv_motor_tuning.md
- and guidance from this thread
Here is my XML
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2025 ModalAI Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 4. The Software is used solely in conjunction with devices provided by ModalAI Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. For a license to use on non-ModalAI hardware, please contact license@modalai.com --> <EscParameters> <IdParams> <param name="id" value="127"/> <!-- ID assignment is fixed. Do not change --> <param name="dir" value="2"/> <!-- 0=fwd, 1=rev, 2=fwd id-based, 3=rev id-based --> </IdParams> <UartParams> <param name="protocol_version" value="2"/> <!-- reserved for future use --> <param name="input_mode" value="0"/> <!-- reserved for future use --> <param name="baud_rate" value="2000000"/> <!-- communication bit rate --> <param name="char_timeout_ns" value="0"/> <!-- not used --> <param name="cmd_timeout_ns" value="100000000"/> <!-- timeout for incoming commands before ESC will stop the motor --> </UartParams> <TuneParams> <param name="pwm_frequency" value="48000"/> <!-- 24Khz is the only option for Tmotor board to reduce Mosfet switching losses --> <param name="vbat_nominal_mv" value="22200"/> <!-- used for sanity checking and limiting of voltage-dependent funcions --> <param name="num_cycles_per_rev" value="14"/> <!-- number of pole pairs in the motor. used for converting electrical frequency to mechanical rpm --> <param name="min_rpm" value="577"/> <!-- minimum RPM that will be attempted, otherwise capped --> <param name="max_rpm" value="4626"/> <!-- maximum RPM that will be attempted, otherwise capped --> <param name="min_pwm" value="100"/> <!-- cap for minimum power to be ever applied. max is 999 --> <param name="max_pwm" value="999"/> <!-- cap for maximum power to be ever applied. max is 999 --> <param name="pwm_vs_rpm_curve_a0" value="784.739381143"/> <!-- this is actually motor_voltage vs rpm curve.. using legacy naming --> <param name="pwm_vs_rpm_curve_a1" value="2.77418758498"/> <!-- --> <param name="pwm_vs_rpm_curve_a2" value="0.000345512059078"/> <param name="kp" value="50"/> <!-- 100... RPM controller proportional gain --> <param name="ki" value="10"/> <!-- 10.. RPM controller proportional gain --> <param name="max_kpe" value="100"/> <!-- maximum proportional erorr term (max is 999) --> <param name="max_kie" value="50"/> <!-- maximum integral error term (max is 999) --> <param name="max_rpm_delta" value="5000"/> <!-- cap for maximum rpm error used in RPM controller --> <param name="spinup_type" value="1"/> <!-- 0: traditional, 1: sinusoidal . Sinusoidal is not yet implemented on this board--> <param name="spinup_power" value="150"/> <!-- power used to during spin-up procedure (out of 999)--> <param name="latch_power" value="120"/> <!-- power used during latching stage of spin-up (out of 999)--> <param name="spinup_power_ramp" value="8"/> <!-- it will take ( 4096 / (spinup_power_ramp*10000) ) seconds to ramp sinusoidal start-up power from 0 to spinup_power. Not yet implemented. --> <param name="spinup_rpm_target" value="800"/> <!-- Desired RPM at the end of the sinusoidal spin-up procedure. Not yet implemented. --> <param name="spinup_time_ms" value="1000"/> <!-- Duration of the sinusoidal spin-up procedure. Not yet implemented. --> <param name="spinup_bemf_comp" value="1"/> <!-- 0: disable, 1:enable back-emf compensation in sinusoidal spin-up procedure. --> <param name="motor_kv" value="280"/> <!-- kV value of the motor. used in back-emf compensation during spin-up. --> <param name="min_num_cross_for_closed_loop" value="50"/> <!-- exit latching mode of fixed power after this number of zero crossings --> <param name="protection_stall_check_rpm" value="500"/> <!-- if motor spins below this RPM, stall check will trigger and stop / restart the motor --> <param name="protection_current_soft_limit_a" value="0"/> <!-- over-current soft limit (will limit power to try to stay under the current limit). Only applicable to ESCs with individual current sensing --> <param name="protection_trip_current_a" value="0"/> <!-- over-current hard limit (will stop the motor) after 100ms. Only applicable to ESCs with individual current sensing --> <param name="brake_to_stop" value="0"/> <!-- apply brake when stopping motor (or not) --> <param name="stall_timeout_ns" value="20000000"/> <!-- after spin-up, if no zero crossing is not detected for this amount of time, motor is considered stalled --> <param name="require_reset_if_stalled" value="0"/> <!-- require sending an array of zero commands to reset before next spin-up, if motor stalled --> <!--one beep--> <param name="tone_freqs" value="[200, 200,240, 200, 0,0,0,0, 0,0,0,0]"/> <!-- 200 is 2000Hz, max 255 --> <param name="tone_durations" value="[20, 0, 20, 0, 0,0,0,0, 0,0,0,0]"/> <!-- duration of each tone in units of 10 milli-seconds. Poor naming!!! --> <param name="tone_powers" value="[50, 0, 50, 0, 0,0,0,0, 0,0,0,0]"/> <!-- max is 255 --> <param name="dt_threshold_ns" value="150000"/> <!-- during start up, ignore inter-commutation times less than this val, probably noise --> <param name="max_dt_ns" value="2500000"/> <!-- min and max values for time between two commutations. these are used as caps --> <param name="min_dt_ns" value="50000"/> <param name="dt_bootstrap_ns" value="2000000"/> <!-- filter bootstrap value for commutation dt during start up --> <param name="spinup_stall_dt_ns" value="6000000"/> <!-- during spin-up, if no zero crossing is not detected for this amount of time, motor is considered stalled --> <param name="spinup_stall_check_ns" value="30000000"/> <!-- time after beginning of spinup to start checking for spinup stall --> <param name="alignment_time_ns" value="0"/> <!-- alignment time before spin-up. not really needed --> <param name="timing_advance" value="60"/> <!-- positive value -> earlier commutation. helps avoid de-syncs if demag time is long. default: 60. absolute maximum is 90 --> <param name="sense_advance" value="10"/> <!-- positive value -> delayed zero crossing sensing. default: 20. absolute maximum is 45 (not recommended above 20)--> <param name="demag_timing" value="1"/> <!-- zero crossing timing tweak. default: 0. set to 1 for low kV (< 500kV) motors to reduce chance of de-sync. do not set to 1 if RPM can exceed 100K eRPM --> </TuneParams> </EscParameters>
-
@shawn_ricardo , your issue looks identical to this one : https://forum.modalai.com/topic/4476/esc-calibration-help
When the values seem to be "stuck" and don't change for seconds, does the actual motor behavior also reflect that? in other words, does the motor RPM also get stuck? You would definitely hear the uneven transitions during the calibration procedure.
I have not had a chance to look at it, but there must be something up when running this script on VOXL2.
Can you please try the same calibration script after setting the voxl2 cpu to perf mode?
voxl-set-cpu-mode perf
. I will also try it.Do you have a chance to try the calibration procedure while connecting the ESC to a Linux PC?
Alex