Урок 1. Серво: угол числом

В картинках

После этого урока на холсте серво — моторчик с рычагом, который встаёт на заданный угол и держит его. Угол ты задаёшь числом на четырёх тумблерах: 0 — рычаг на 0°, 8 — на 90°, 15 — почти на 170°. Из таких серво в следующем уроке соберём руку.


1.1. Идея: угол — это длина импульса

Серво слушает одну ногу PWM. На неё приходят короткие импульсы, один за другим. Серво меряет, сколько длится каждый импульс, и поворачивает рычаг:

  • импульс 0,5 мс — 0°;
  • импульс 1,5 мс — 90°;
  • импульс 2,5 мс — 180°.

Между импульсами — пауза; её длина не важна, лишь бы импульсы шли постоянно. Так управляют серво в авиамоделях, роботах и 3D-принтерах: один провод, а угол — любой.

окошко012345678910111213141516171819…PWM1число 04 окошек = 0,5 мс0°PWM1число 812 окошек = 1,5 мс90°PWM1число 1519 окошек = 2,375 мс169°кадр — 256 окошек = 32 мс, дальше всё снова
Окошко — 0,125 мс (генератор 8 кГц). Импульс горит, пока номер окошка меньше «число + 4»: число 0 — 4 окошка, 0,5 мс, рычаг на 0°; 8 — 12 окошек, 1,5 мс, 90°; 15 — 19 окошек, ≈ 169°.

1.2. Идея: нарезать время на окошки

Длину импульса будем мерить окошками. Генератор 8 кГц тикает каждые 0,125 мс — это одно окошко. Два счётчика CD4029 цепочкой считают окошки от 0 до 255 и начинают снова. 256 окошек — это кадр длиной 32 мс: в каждом кадре — один импульс.

Что хотим. Импульс горит в начале кадра, пока счёт ещё маленький, и гаснет на нужном окошке:

  • PWM1 = 1, пока счёт меньше, чем длина импульса в окошках.

Сравнивать два числа «меньше — больше» умеет CD4585 — компаратор на 4 бита. Счёт у нас 8-битный, поэтому компараторов два, цепочкой: младший сравнивает младшие 4 бита и передаёт старшему «меньше» и «равно», а старший решает по своим битам, а если они равны — по ответу младшего. Так сравнивают многозначные числа и на бумаге: сначала старшие разряды, при равенстве — младшие.

1.3. Идея: «число + 4»

Число на тумблерах — от 0 до 15, а импульс нужен от 4 окошек (0,5 мс = 0°). Значит, длина импульса — число + 4 окошка:

  • 0 → 4 окошка = 0,5 мс = 0°;
  • каждая следующая единица — ещё одно окошко, 0,125 мс, а это 11,25°;
  • 15 → 19 окошек = 2,375 мс ≈ 169°.

Прибавить 4 — значит прибавить единицу к биту 2. Биты 0 и 1 не меняются, а бит 2 и перенос дальше считаются как в столбик:

A3 A2W2W3W4Пример
0 01000 + 4 = 4
0 10104 + 4 = 8
1 01108 + 4 = 12
1 100112 + 4 = 16
  • W2 = НЕ A2 — бит 2 переворачивается: инвертор CD4069.
  • W3 = A3 ИСКЛ-ИЛИ A2 — бит 3 меняется, если из бита 2 пришёл перенос: CD4070.
  • W4 = A3 И A2 — перенос дальше, в бит 4: CD4081.

Получилось число W4 W3 W2 A1 A0 — оно и идёт на компараторы. Три вентиля вместо целого сумматора: прибавляем всегда одно и то же, поэтому от сумматора остаётся только то, что нужно для четвёрки.

A3A2A1A0W3W4W2A1A0CD4070CD4081CD4069CD4585 ×2счёт < число + 4W4 W3 W2 A1 A0
«+4» — прибавить единицу к биту 2. Бит 2 переворачивается (NOT), бит 3 меняется, если из бита 2 пришёл перенос (XOR), а перенос дальше, в бит 4, — когда оба бита 1 (AND). Биты 0 и 1 идут как есть.

1.4. Сборка

Новый проект. Микросхемы — готовые, из файла набора arm-chips.json; на ногах у них — метки (двойной клик по ноге). Собирать и запускать в Fast (кнопка движка вверху).

Шаг 0. Микросхемы в библиотеку

Если в библиотеке ещё нет папки Arm: в библиотеке кнопка импорта → файл arm-chips.json. Встанет папка Arm — десять микросхем на весь набор (и детали, из которых они собраны внутри).

Шаг 1. Источники

ДетальНастройкаМетка
Power (питание)VCC
Ground (земля)GND
Clock8kHzCK
Button (кнопка)RESET
Input (тумблер)A0
Input (тумблер)A1
Input (тумблер)A2
Input (тумблер)A3

Шаг 2. Счётчик окошек: два CD4029

Clock — щелчок по корпусу до 8kHz. Ноги PE обоих счётчиков — на RESET: по кнопке они встают в 0.

ДетальНогаМетка
TI CD4029BCLOCK
CI
BD
UD
PE
J1
J2
J3
J4
Q1
Q2
Q3
Q4
CO
CK
GND
VCC
VCC
RESET
GND
GND
GND
GND
C0
C1
C2
C3
CY
TI CD4029BCLOCK
CI
BD
UD
PE
J1
J2
J3
J4
Q1
Q2
Q3
Q4
CK
CY
VCC
VCC
RESET
GND
GND
GND
GND
C4
C5
C6
C7

Шаг 3. Число + 4: три вентиля

Из каждой микросхемы занят один вентиль; входы остальных вентилей — на GND (в уроке 2 их займёт локоть).

ДетальНогаМетка
TI CD4069UBA
G
B
C
D
E
F
A2
W2
GND
GND
GND
GND
GND
TI CD4070BA
B
J
C
D
E
F
G
H
A3
A2
W3
GND
GND
GND
GND
GND
GND
TI CD4081BA
B
J
C
D
E
F
G
H
A3
A2
W4
GND
GND
GND
GND
GND
GND

Шаг 4. Сравнение: два CD4585 → импульс PWM1

ДетальНогаМетка
TI CD4585BA0
A1
A2
A3
B0
B1
B2
B3
LTIN
EQIN
GTIN
LT
EQ
C0
C1
C2
C3
A0
A1
W2
W3
GND
VCC
VCC
LL
LE
TI CD4585BA0
A1
A2
A3
B0
B1
B2
B3
LTIN
EQIN
GTIN
LT
C4
C5
C6
C7
W4
GND
GND
GND
LL
LE
VCC
PWM1

Шаг 5. Серво

Меню Mechanics → Servo.

ДетальНогаМетка
Servo (серво)PWMPWM1

Россыпью, в чип не сворачивать: в уроке 2 у второго серво генератор, счётчик и RESET будут общие с первым.

1.5. Проверка

  1. Включи питание и один раз нажми RESET — счётчики встают в 0, серво начинает получать импульсы.
  2. Тумблеры A3 A2 A1 A0 = 0000 — рычаг серво на 0°.
  3. Набирай числа по таблице — рычаг поворачивается: на каждую единицу числа — 11,25°.
ЧислоТумблеры A3 A2 A1 A0ИмпульсУгол
00 0 0 00,5 мс0°
40 1 0 01,0 мс45°
81 0 0 01,5 мс90°
121 1 0 02,0 мс135°
151 1 1 12,375 мс169°

Вставка урока 1 (Cmd+I)

Вставлять в новый проект. Нужны микросхемы из arm-chips.json.

# Lesson 1 - a servo turned by a number: switches A3..A0, the servo goes to number x 11.25 degrees.# Paste into a new project. Chips: arm-chips.json. After power on press RESET once.# ---------- power ----------power(VCC)ground(GND)# ---------- clock 8 kHz, RESET ----------clock{hz=1}(CK)button(RESET)# ---------- shoulder number ----------input(A0)input(A1)input(A2)input(A3)# ---------- window counter: two CD4029, 0..255 ----------"TI CD4029B"(CLOCK=CK, CI=GND, BD=VCC, UD=VCC, PE=RESET, J1=GND, J2=GND, J3=GND, J4=GND, Q1=C0, Q2=C1, Q3=C2, Q4=C3, CO=CY)"TI CD4029B"(CLOCK=CK, CI=CY, BD=VCC, UD=VCC, PE=RESET, J1=GND, J2=GND, J3=GND, J4=GND, Q1=C4, Q2=C5, Q3=C6, Q4=C7)# ---------- +4 for the shoulder: one gate of CD4069, CD4070, CD4081 ----------"TI CD4069UB"(A=A2, G=W2, B=GND, C=GND, D=GND, E=GND, F=GND)"TI CD4070B"(A=A3, B=A2, J=W3, C=GND, D=GND, E=GND, F=GND, G=GND, H=GND)"TI CD4081B"(A=A3, B=A2, J=W4, C=GND, D=GND, E=GND, F=GND, G=GND, H=GND)# ---------- shoulder pulse: two CD4585, count < number + 4 -> PWM1 ----------"TI CD4585B"(A0=C0, A1=C1, A2=C2, A3=C3, B0=A0, B1=A1, B2=W2, B3=W3, LTIN=GND, EQIN=VCC, GTIN=VCC, LT=LL, EQ=LE)"TI CD4585B"(A0=C4, A1=C5, A2=C6, A3=C7, B0=W4, B1=GND, B2=GND, B3=GND, LTIN=LL, EQIN=LE, GTIN=VCC, LT=PWM1)# ---------- servo ----------mservo sh{rot=90}(PWM=PWM1)

Не получается? Что-то не работает →