TGViewer
Семён сохраняет полезное_) Семён сохраняет полезное_) @pole_sam · 685 subscribers
Post #397 921
На днях завершил разработку контроллера для сервоприводов с обратной связью. В своих проектах я часто использую сервоприводы MG90S для перемещения стрелок и блендеров в различных приборах. Эти устройства привлекают внимание металлическим редуктором и весьма привлекательной ценой — за 10 штук вы платите примерно как за упаковку сыра.

Однако при встраивании сервопривода в прибор возникает существенная сложность: отсутствует возможность оперативно определить, зажат ли механизм или вышел из строя сам привод. Решением проблемы становится внедрение обратной связи. К сожалению, стандартные MG90S не оснащены такой функцией, поэтому приходится модифицировать устройство: снимать крышку и припаивать провод к среднему контакту встроенного потенциометра.

Сигнал с потенциометра через схему повторителя на операционном усилителе направляется на микроконтроллер. Программное управление сервоприводом осуществляется с помощью ШИМ-сигналов, а считывание положения происходит через встроенный АЦП. Важно отметить: для повышения точности измерений рекомендуется считывать сразу 5 значений и вычислять их среднее арифметическое.

Для демонстрации принципа работы я подготовил упрощённый пример кода на Python, который включает только базовые функции управления и считывания положения. Код специально сделан максимально понятным для удобства восприятия. Пример кода будет представлен ниже.
import serial
import re
import time

SERIAL_PORT = "/dev/ttyACM0"
BAUD_RATE = 115200
start_calib = 55
stop_calib = 530

def open_serial():
try:
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
time.sleep(1)
return ser
except serial.SerialException as e:
print(f"Ошибка открытия порта: {e}")
return None

def send_command(ser, command):
if ser is None:
print("Ошибка: порт не открыт")
return []

ser.reset_input_buffer()
ser.write((command + "\n").encode())
time.sleep(0.01)

response = []
start_time = time.time()
while time.time() - start_time < 1:
if ser.in_waiting > 0:
line = ser.readline().decode().strip()
if line:
response.append(line)

return response

def set_servo_angle(ser, num_servo, angle):
response = send_command(ser, f"0xAB{num_servo}gg{angle}0xFF")
if response:
pass
else:
print("Нет ответа от платы на установку угла")

def read_analog_values(ser, num_servo):
response = send_command(ser, f"0xAB{num_servo}rr0xFF")
if response:
pass
else:
print("Not data")
return response


def chew_angle(num_servo, angle):
ser = open_serial()
if ser:
set_servo_angle(ser,str(num_servo), str(angle))
time.sleep(0.1)

data = read_analog_values(ser, num_servo)
if isinstance(data, list):
data = " ".join(data)


numbers = list(map(int, re.findall(r"\d+", data)))
print("Извлечённые числа:", numbers)

if numbers:
avg = sum(numbers) / len(numbers)
# При 0° -> 55, при 180° -> 585, т.е. масштаб: (585-55)/180 = 530/180
computed_angle = (avg - start_calib) * (180 / stop_calib)
if abs(angle - computed_angle) < 1:
pass
else:
print("Угол не совпадает")
if abs(angle - computed_angle) > 1:
ang = computed_angle - 30
if ang < 20:
set_servo_angle(ser, str(num_servo), str(0))
else:
set_servo_angle(ser, str(num_servo), str(ang))
chew_angle(num_servo, angle)
else:
print("Не удалось извлечь числа из данных")
ser.close()

num_servo = 1
angle = 20
time.sleep(3)
chew_angle(num_servo, angle)
angle = 160
time.sleep(3)
chew_angle(num_servo, angle)

P.S Мне сказали что нужен интерактив. Напишите в комментариях почему лучше не подключать среднюю точку потенциометра напрямую к АЦП МК?
  • 🔥 10
More from @pole_sam
  1. Oct 2, 2026Всем привет. Сегодня написал Bring-up прошивку для платы. Первая ревизия запустилась без п…
  2. Sep 27, 2026Всем привет! Сделал свой форк pysim для удобного вывода информации. https://telegra.ph/For…
  3. Sep 27, 2026Приехала плата PTP грандмастера
  4. Sep 25, 2026Всем привет! Приехала сегодня отладка от Qualcomm что по всей видимости в своё время вынес…
  5. Sep 23, 2026Всем привет! Платы PTP-грандмастера приехали наконец-то в РФ. Скоро приступлю к bring-up п…
  6. Sep 20, 2026Всем привет! Вышла заметка о том как я сделал себе управляемый коммутатор из медиаконверте…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →