Digitální měření lineárních motorů a jejich odchylky
Reklama:Pro měření rychlosti malých lineárních/robotických motorů bez interního enkodéru existují následující možnosti. Rozdělení je provedeno pro měření bez zátěže a se zátěží, s variantami pro různé cenové a přesnostní úrovně.
Měření bez zátěže
1. Nejlevnější varianta: Měření zpětné elektromotorické síly (Back EMF)
- Princip: Využívá napětí indukované v motoru při vypnutém PWM signálu, které je úměrné rychlosti2 13.
- Schéma:
Motor ─┬─ PWM řízení (např. H-můstek)
└─ ADC pin (s děličem napětí pro ochranu)
MicroPython kód:
from machine import ADC, PWM, Pin
import time
motor_pwm = PWM(Pin(15))
adc = ADC(Pin(26))
def measure_speed():
motor_pwm.duty_u16(0) # Vypnutí PWM
time.sleep_us(100) # Čekání na ustálení
emf = adc.read_u16() # Měření napětí
motor_pwm.duty_u16(32768) # Obnovení PWM (50 %)
return emf * 0.0001 # Kalibrační konstanta
# Měření v obou směrech
pwm_values = [32768, 0] # Dopředu, dozadu
for pwm in pwm_values:
motor_pwm.duty_u16(pwm)
print("Rychlost:", measure_speed())
2. Nejpreciznější varianta: Optický enkodér s externím kotoučem
Motor ── Kotouč s otvory ── Optický senzor (např. TCRT5000) ── GPIO
MicroPython kód:
from machine import Pin, Timer
import time
sensor = Pin(16, Pin.IN)
counter = 0
def tick(pin):
global counter
counter += 1
sensor.irq(trigger=Pin.IRQ_RISING, handler=tick)
def calculate_rpm():
global counter
start_time = time.ticks_ms()
time.sleep(1)
rpm = (counter * 60) / 20 # 20 otvorů na kotouči
counter = 0
return rpm
# Test obou směrů
for direction in [1, -1]:
set_motor_direction(direction) # Funkce pro změnu směru
print("RPM:", calculate_rpm())
3. Optimální střed: Hallův senzor s magnetem
- Princip: Magnet na hřídeli aktivuje Hallův senzor při každé otáčce8.
- Schéma:
Motor ── Magnet na hřídeli ── Hallův senzor (A3144) ── GPIO
MicroPython kód:
from machine import Pin, PWM
import time
hall = Pin(17, Pin.IN)
motor_pwm = PWM(Pin(15))
rotations = 0
def count_rotation(pin):
global rotations
rotations += 1
hall.irq(trigger=Pin.IRQ_FALLING, handler=count_rotation)
def measure_speed(duration=1):
global rotations
rotations = 0
time.sleep(duration)
return rotations / duration * 60 # RPM
# Měření pro oba směry
for duty in [32768, 49152]: # 50 % a 75 % výkonu
motor_pwm.duty_u16(duty)
print("RPM:", measure_speed())
- Výhody: Kompromis mezi cenou a přesností (±2 %)8.
- Nevýhody: Vyžaduje montáž magnetu.
Měření se zátěží (robotické vozítko)
1. Nejlevnější varianta: Kalibrace pomocí PWM a času jízdy
- Princip: Měření driftu vozítka při jízdě po definované trati a korekce PWM10 14.
-
Postup:
-
Nastavte oba motory na stejné PWM
- Změřte odchylku dráhy po 1 m
- Upravte PWM poměr:
nové_PWM = původní_PWM ± (odchylka * korekční_koeficient)
Kód pro korekci:
def calibrate_motors():
Kp = 0.1 # Korekční konstanta
base_speed = 30000
left_pwm = base_speed
right_pwm = base_speed
for _ in range(5): # 5 měření
deviation = measure_deviation() # Funkce pro měření odchylky
left_pwm += int(deviation * Kp)
right_pwm -= int(deviation * Kp)
return left_pwm, right_pwm
2. Nejpreciznější varianta: PID regulace s optickými enkodéry
[Optický enkodér] ── GPIO
── PID regulátor ── PWM
PID kód:
from machine import PWM, Pin
import time
class PID:
def __init__(self, Kp, Ki, Kd):
self.Kp, self.Ki, self.Kd = Kp, Ki, Kd
self.integral = 0
self.last_error = 0
def update(self, error):
self.integral += error
derivative = error - self.last_error
output = self.Kp*error + self.Ki*self.integral + self.Kd*derivative
self.last_error = error
return output
pid_left = PID(0.8, 0.05, 0.01)
pid_right = PID(0.8, 0.05, 0.01)
while True:
left_rpm = get_left_rpm() # Z enkodéru
right_rpm = get_right_rpm()
error = left_rpm - right_rpm
correction = pid_left.update(error)
set_pwm(left_motor, base_speed + correction)
set_pwm(right_motor, base_speed - correction)
3. Optimální střed: Hallovy senzory s adaptivním PWM
- Princip: Dynamická úprava PWM na základě rozdílu v počtech impulsů14.
- Kód:
def adaptive_control():
left_count = hall_left.count()
right_count = hall_right.count()
ratio = left_count / (right_count + 1e-6) # Aby nedocházelo k dělení nulou
if ratio > 1.1:
adjust_pwm(right_motor, +5%)
elif ratio < 0.9:
adjust_pwm(left_motor, +5%)
Univerzální měřící skript pro MicroPython
from machine import Pin, PWM, ADC, Timer
import time
# Konfigurace hardwaru
motor_left = PWM(Pin(13))
motor_right = PWM(Pin(14))
sensor_left = Pin(15, Pin.IN)
sensor_right = Pin(16, Pin.IN)
# Proměnné pro měření
count_left, count_right = 0, 0
def count_left(pin):
global count_left
count_left +=1
def count_right(pin):
global count_right
count_right +=1
sensor_left.irq(trigger=Pin.IRQ_RISING, handler=count_left)
sensor_right.irq(trigger=Pin.IRQ_RISING, handler=count_right)
def measure_speed(duration=1):
global count_left, count_right
count_left = count_right = 0
time.sleep(duration)
return (count_left/duration, count_right/duration)
# Testovací sekvence
for speed in [0.3, 0.5, 0.7]:
motor_left.duty_u16(int(65535*speed))
motor_right.duty_u16(int(65535*speed))
left, right = measure_speed()
print(f"Korekce: {left-right} pulses/s")
Toto řešení kombinuje jednoduchost měření s možností kalibrace pro různé provozní podmínky. Pro robotická vozítka doporučujeme implementovat PID regulátor s optickými enkodéry pro maximální přesnost11 12.
-
https://www.iaeng.org/publication/WCE2017/WCE2017_pp371-375.pdf ↩
-
https://www.kevsrobots.com/learn/micropython_gpio/07_motors.html ↩
-
https://orionrobots.co.uk/2023/09/07/worksheet-on-driving-robots-with-micropython.html ↩
-
https://www.electroschematics.com/motor-speed-sensor-module-circuit/ ↩↩
-
https://www.instructables.com/RPM-Measurement-Using-Hall-Sensor-and-Arduino/ ↩↩
-
https://enriquedelsol.com/2017/11/19/motor-selection-for-robots-i/ ↩
-
https://wseas.com/journals/amcse/2021/amcsejournal2021-010.pdf ↩↩
-
https://www.heidenhain.us/resources-and-news/linear-encoders-for-linear-motors-for-direct-drives/ ↩↩
-
http://qa.orientalmotor.com/brushless-dc-motors-gear-motors/technology/speed-control-methods-of-speed-control-motors.html ↩↩
-
https://thetechnicgear.com/2014/06/howto-calibrate-differential-drive-robot/ ↩↩
-
https://dewesoft.com/blog/measure-digital-encoder-and-counter-sensors ↩
-
https://www.nanotec.com/eu/en/products/153-stepper-motors-from-manufacturer ↩
-
https://forum.arduino.cc/t/accurate-turning-without-encoders/138205 ↩
-
https://www.instructables.com/Complete-Motor-Guide-for-Robotics/ ↩
-
https://cw.fel.cvut.cz/old/_media/courses/a3m33iro/060actuatorsforrobots.pdf ↩
-
https://www.sciencedirect.com/science/article/abs/pii/S0263224122000021 ↩
-
https://homepages.dcc.ufmg.br/~doug/cursos/lib/exe/fetch.php?media=cursos%3Aintrorobotica%3Atransparenciasextras%3Afred-03.pdf ↩
-
https://www.sciencedirect.com/science/article/pii/S2666720725000359 ↩
-
https://www.rs-online.com/designspark/how-to-select-a-miniature-motor-technology ↩
-
https://onlinelibrary.wiley.com/doi/full/10.1002/aisy.202100129 ↩
-
https://www.aliexpress.com/w/wholesale-small-engine-tachometer.html ↩
-
https://www.reddit.com/r/drivingUK/comments/17d270q/which_speedometer_should_i_believe/ ↩
-
https://www.edaboard.com/threads/how-to-measure-the-speed-rpm-of-a-small-simple-dc-motor.147916/ ↩
-
https://ev3dev-lang.readthedocs.io/projects/python-ev3dev/en/stable/motors.html ↩
-
https://docs.micropython.org/en/latest/reference/speed_python.html ↩
-
https://stackoverflow.com/questions/73057974/arduino-using-motor-to-control-two-motors-and-measuring-distance-traveled ↩
-
https://forums.raspberrypi.com/viewtopic.php?t=309117\&start=25 ↩
-
https://docs.micropython.org/en/latest/pyboard/tutorial/servo.html ↩
-
https://grobotronics.com/light-and-motor-driver-for-python.html?sl=en ↩
-
https://randomnerdtutorials.com/raspberry-pi-pico-dc-motor-micropython/ ↩
-
https://stackoverflow.com/questions/74571701/getting-motor-speed-from-motor-driver ↩
-
https://github.com/KitronikLtd/Kitronik-Pico-Motor-Driver-Board-MicroPython ↩
-
https://www.pinterest.com/pin/dc-motor-speed-controller-schematic-design--680254718694818055/ ↩
-
https://www.electronicsforu.com/electronics-projects/dc-motor-speed-controller ↩
-
https://rcciit.org.in/students_projects/projects/ee/2019/GR16.pdf ↩
-
https://www.groupvh.com/datasheets_productpdfs/ID_HD_SPEED_CENSOR_RE 95 135_5B04F9D7-B05F-4DBF-8059-ED2EB1723EE7.pdf ↩
-
https://www.homemade-circuits.com/how-to-make-versatile-closed-loop/ ↩
-
https://sites.google.com/site/hobbydebraj/dc-motor-control-using-back-emf-sen ↩
-
https://forum.arduino.cc/t/problems-measuring-shaft-rotating-speed-with-optical-sensor/538508 ↩
-
https://forum.arduino.cc/t/speed-measurement-on-bldc-motor-hall/1216384 ↩
-
https://forum.allaboutcircuits.com/threads/how-to-measure-the-back-emf-of-a-dc-motor.109750/ ↩
-
https://deepbluembedded.com/arduino-motor-encoder-optical-encoder-interfacing/ ↩
-
https://build-its-inprogress.blogspot.com/2016/01/motor-characterization-for-small.html ↩
-
https://forum.pololu.com/t/how-to-make-the-robot-to-move-in-straight-line-using-encoders/22340 ↩
-
http://vigir.missouri.edu/~gdesouza/Research/Conference_CDs/IEEE_ICRA_2008/Haptic Displays and Interfaces/Simultaneous maximum-likelihood calibration of odometry and .pdf ↩
-
https://forum.arduino.cc/t/robot-driving-to-the-left-when-it-should-be-going-straight/689075 ↩
-
https://www.reddit.com/r/arduino/comments/1ic61z0/robot_does_not_go_straight_motor_speeds_are_equal/ ↩
-
https://www.sciencedirect.com/science/article/abs/pii/S0921889022001531 ↩
-
https://electronics.stackexchange.com/questions/185856/making-a-robot-go-straight-using-encoder-motors-and-micro-controller-arduino ↩
-
https://www.digiten.shop/products/senstree-car-motorcycle-4-digital-motor-tachometer-speed-measure-meter-5-9999-rpm-led-red ↩
-
https://digital-speedos.co.uk/digital-gps-speedometer-for-car/ ↩
-
https://www.linkedin.com/pulse/understanding-choosing-right-digital-engine-tachometer ↩
-
https://www.alibaba.com/showroom/small-digital-speedometer.html ↩
-
https://www.autometer.com/3-3-8-speedo-140-mph-gps-carbon-fiber.html ↩
-
https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/modules/motor/README.md ↩
-
https://www.upesy.com/blogs/tutorials/esp32-servo-motor-sg90-on-micropython ↩
-
https://randomnerdtutorials.com/micropython-esp32-esp8266-dc-motor-l298n/ ↩
-
https://wiki.dfrobot.com/Light_and_Motor_Driver_for_Python_SKU_DRI0050 ↩
-
https://www.erasmatazz.com/library/c839b0d2d6b6417787b1/motor-speed-measuring-circu.html ↩
-
https://www.homemade-circuits.com/dc-motor-speed-controller-circuits/ ↩
-
https://acroname.com/blog/all-about-back-emf-motion-control ↩
-
https://www.electroschematics.com/simple-optical-speed-trap/ ↩
-
https://www.celeramotion.com/frameless-motors/support/technical-papers/motor-unit-conversions/ ↩
-
https://www.celeramotion.com/frameless-motors/support/technical-papers/motor-constant-matters/ ↩
-
https://www.reddit.com/r/robotics/comments/18p4q9d/how_do_i_estimate_motor_torque/ ↩
-
https://www.instructables.com/How-to-Make-a-Robot-Car-Drive-Straight-and-Turn-Ex/ ↩