Telemetry Test of the Xcross BLHeli32 160A
Results
- Voltage and temperature readings are quite accurate.
- RPM measurements seem reliable, at least at lower RPMs. As I understand it, this RPM represents the actual motor speed measured by the ESC using back EMF.
- Current readings only appeared above 3A, and the multiplier varied, making the readings unreliable.
- Current consumption remained at zero throughout the test.
Setup
Connection: Connect the ESC TX pin to the UART RX pin of a microcontroller.
To increase the current, the motor was mounted on a mast, and pressure was applied using a cloth.
Micropython code for esp32-c3 supermini board:
from machine import Pin, reset, ADC,UART
import machine
import time
import network
import socket
import _thread
import json
import struct
led = Pin(8, Pin.OUT)
led.on()
is_blinking = True
def led_turn_on():
led.off()
def led_turn_off():
led.on()
import time
uart = UART(115200, bits=8, parity=None, stop=1, rx=20, tx=21)
def update_crc8(crc, crc_seed):
crc_u = crc ^ crc_seed
for i in range(8):
crc_u = (0x7 ^ (crc_u << 1)) if (crc_u & 0x80) else (crc_u << 1)
return crc_u & 0xFF
def get_crc8(buf, buflen):
crc = 0
for i in range(buflen):
crc = update_crc8(buf[i], crc)
return crc
def parse_kiss_telemetry(data):
if data and len(data) >= 10:
try:
# Verify CRC
received_crc = data[9]
calculated_crc = get_crc8(data[:9], 9)
if received_crc != calculated_crc:
print(f"CRC mismatch: received {received_crc}, calculated {calculated_crc}")
return None
temperature = data[0] # °C
voltage = (data[1] << 8 | data[2]) / 100.0 # Volts
current = (data[3] << 8 | data[4]) / 100.0 # Amps
consumption = (data[5] << 8 | data[6]) # mAh
erpm = (data[7] << 8 | data[8]) * 100 # Electrical RPM
rpm = erpm // (12//2) # For a 12-pole motor
return f"V:{voltage:06.2f} I:{current:06.1f} RPM:{rpm:06d} CON:{consumption:06d} T:{temperature:03d}C"
except Exception as e:
print(f"Error: {e}")
return None
return None
while True:
led.value(not led.value())
if uart.any():
data = uart.read()
telemetry = parse_kiss_telemetry(data)
print(telemetry)
time.sleep(1)