Моторы: едем и останавливаемся
Первые движения робота: вперёд, назад и обязательная остановка из программы.
Результат урока
Робот проезжает вперёд, останавливается и возвращается назад по программе. Движения оформлены функциями forward(), backward() и stopMotors().
Ты научишься
- Объяснить, что задаёт контакт направления и что — контакт скорости.
- Включить и остановить моторы командами digitalWrite и analogWrite.
- Написать функции движения и вызвать их по порядку.
- Объяснить, почему движение без команды остановки не заканчивается.
Нужно знать
- 1.1 Собираем робота и оживляем плату
Понадобится
Зачем этот урок
Робот собран, но пока стоит. Сегодня он поедет. Ты узнаешь, как плата командует моторами, и научишь робота ехать вперёд, назад и — самое важное — останавливаться по программе.
- Сколько раз выполняется
setup(), а сколько —loop()? - Что делает
digitalWrite(вывод, HIGH)? - Где на твоём роботе левый мотор?
Моторы проверяем на подставке: колёса не касаются стола. Программу загружаем при выключенном питании моторов. Чтобы остановить опыт, выключи питание моторов выключателем.
Подготовь робота
5 минЧто должен делать робот. Роботу нужно начать движение, проехать участок и остановиться. Для этого научимся отдельно задавать направление и мощность каждого из двух моторов, а затем объединим команды в понятные действия.
Что используем и как это работает. Моторы подключены через драйвер L298P: вывод Arduino подаёт управляющий сигнал, а ток к мотору поступает через драйвер. DIR выбирает направление. ШИМ быстро чередует включение и выключение питания; большее значение analogWrite означает большую долю включённого времени. Это команда мощности, а не измеренная скорость в сантиметрах в секунду.
Как связать измерение с действием. Если оба колеса крутятся вперёд, робот едет; если одно слабее, он отклоняется. delay только задерживает следующую команду: мотор продолжает выполнять предыдущую. Поэтому в программе нужна отдельная остановка. Сначала наблюдаем колёса на подставке, затем проверяем направление, расстояние и остановку на поле.
- Поставь робота на подставку так, чтобы оба колеса висели в воздухе.
- Найди выключатель питания моторов и выключи его.
- Подключи USB-кабель.
Колёса висят, питание моторов выключено, плата подключена к компьютеру.
Включи левый мотор
15 минКаждым мотором управляют два контакта. Контакт направления решает, куда крутится колесо. Контакт скорости решает, насколько сильно: число от 0 (стоит) до 255 (полная мощность). Левый мотор подключён к контактам 7 (направление) и 6 (скорость).
const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int FORWARD = HIGH; void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); digitalWrite(LEFT_DIR_PIN, FORWARD); analogWrite(LEFT_SPEED_PIN, 100); delay(2000); analogWrite(LEFT_SPEED_PIN, 0);} void loop() {}
Что сделает колесо после загрузки? Сколько секунд оно будет крутиться? Остановится ли оно само? Скажи напарнику до запуска.
- Набери программу и загрузи её при выключенном питании моторов.
- Включи питание моторов и нажми кнопку Reset на плате: программа начнётся заново.
- Сравни, что произошло, со своим прогнозом.
Левое колесо крутится вперёд 2 секунды и останавливается.
Как это устроено: Что значит каждая строка
const int LEFT_DIR_PIN = …;— имя для номера контакта. Дальше в программе пишем имя, а не число: так понятнее и меньше ошибок.digitalWrite(LEFT_DIR_PIN, FORWARD);— выбрать направление «вперёд».analogWrite(LEFT_SPEED_PIN, 100);— включить мотор с силой 100 из 255.analogWrite(LEFT_SPEED_PIN, 0);— остановить мотор.- Всё написано в
setup(), поэтому выполняется один раз.loop()пустой: после остановки робот просто стоит.
| Что видишь | Что сделать |
|---|---|
| Колесо не крутится | Включено ли питание моторов? Нажми Reset после включения. |
| Колесо крутится назад | Запиши это в журнал — на следующем шаге исправим направлением. |
| Крутится правое колесо | Провода моторов перепутаны на шилде. Выключи питание и поменяй местами провода в клеммах M1 и M2. |
Каждым мотором управляют два контакта. Контакт направления решает, куда крутится колесо. Контакт скорости решает, насколько сильно: число от 0 (стоит) до 255 (полная мощность). Левый мотор подключён к контактам 7 (направление) и 6 (скорость).
| Команда | Что делает |
|---|---|
pinMode(контакт, OUTPUT); | Разрешает плате управлять контактом |
digitalWrite(контакт, FORWARD); | Выбирает направление «вперёд» |
analogWrite(контакт, сила); | Включает мотор с силой от 0 до 255; 0 — стоп |
delay(мс); | Ждёт указанное число миллисекунд |
- Создай скетч
L21_Left_Motorпо шаблону и напишиsetup()сам: что должно произойти, сказано в комментариях.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int FORWARD = HIGH; // ===== Твоя часть: напиши сам ===== void setup() { // Подготовь оба контакта левого мотора. // Левое колесо крутится вперёд 2 секунды с силой 100 из 255 и останавливается само.} void loop() {}
Что будет, если забыть команду остановки? Запиши ответ и проверяй его только на подставке.
- Загрузи программу при выключенном питании моторов.
- Включи питание моторов и нажми кнопку Reset на плате: программа начнётся заново.
Подсказка: С чего начать
Сначала оба контакта должны стать выходами, потом — направление, потом сила.
Левое колесо крутится вперёд 2 секунды и останавливается. Прогноз записан.
| Что видишь | Что сделать |
|---|---|
| Колесо не крутится | Настроены ли контакты как выходы? Включено ли питание моторов? Нажми Reset. |
| Колесо крутится назад | Запиши это в журнал — на следующем шаге исправим направлением. |
| Крутится правое колесо | Провода моторов перепутаны на шилде. Выключи питание и поменяй местами провода в клеммах M1 и M2. |
Левый мотор подключён к контактам 7 (направление) и 6 (скорость). Направление «вперёд» на этом комплекте — уровень HIGH.
Как это устроено: Справка по командам
| Команда | Что делает |
|---|---|
pinMode(pin, OUTPUT) | Разрешает плате управлять контактом |
digitalWrite(pin, HIGH) / LOW | Направление мотора |
analogWrite(pin, v) | Сила мотора: v от 0 (стоит) до 255 |
delay(ms) | Ждать ms миллисекунд |
Требование 1. Скетч L21_Left_Motor: левое колесо крутится вперёд ровно 2 секунды с силой из именованной переменной и останавливается само. Номера контактов — именованные константы, а не числа в командах.
Приёмка.
- На подставке напарник засекает по секундомеру, сколько крутится колесо.
- Замени уровень направления на противоположный. Что сделало колесо? Запиши, какой уровень на твоём роботе — «вперёд».
- Объясни в журнале, почему колесо остановилось, хотя
loop()пустой.
Подсказка: Идея (1 из 2)
Один раз при включении: настроить контакты, выбрать направление, включить, подождать, выключить.
Подсказка: Подсказка к пункту 3 (2 из 2)
Где выполнилась команда остановки — в setup() или в loop()? Сколько раз?
Колесо крутится 2 секунды и останавливается. В журнале — время по секундомеру, уровень «вперёд» и объяснение остановки.
Включи оба мотора
15 мин- Создай скетч
L21_Both_Motorsи набери программу.
const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH; int speed = 100; void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); digitalWrite(LEFT_DIR_PIN, FORWARD); digitalWrite(RIGHT_DIR_PIN, FORWARD); analogWrite(LEFT_SPEED_PIN, speed); analogWrite(RIGHT_SPEED_PIN, speed); delay(1000); analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void loop() {}
- Загрузи и запусти на подставке.
- Поменяй
speedна 60, потом на 200. Как меняется вращение?
Оба колеса крутятся вперёд одну секунду и останавливаются. С большим speed колёса крутятся быстрее.
Как это устроено: Почему 0–255, а не километры в час
Число в analogWrite — это не скорость, а доля времени, когда мотор включён. При 255 он включён всё время, при 100 — примерно 40 % времени. Настоящая скорость зависит ещё от батареи и пола. Поэтому скорость подбирают опытом.
Правый мотор устроен так же, как левый: контакт направления 4 и контакт скорости 5. Имена всех четырёх контактов в шаблоне уже есть.
- Создай скетч
L21_Both_Motorsпо шаблону и напишиsetup()сам. Свою программу левого мотора используй как образец.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;int speed = 100; // ===== Твоя часть: напиши сам ===== void setup() { // Подготовь контакты обоих моторов. // Оба колеса крутятся вперёд со скоростью speed одну секунду и останавливаются.} void loop() {}
- Загрузи и запусти на подставке.
- Поменяй
speedна 60, потом на 200. Как меняется вращение?
Ты включаешь колёса по очереди: сначала левое, потом правое. Заметно ли, что они трогаются не одновременно? Почему?
Подсказка: Колёса ведут себя по-разному
Сравни команды для левого и правого мотора строка за строкой: для каждого нужны настройка, направление, сила и остановка.
Оба колеса крутятся вперёд одну секунду и останавливаются. С большим speed колёса крутятся быстрее, прогноз записан.
Как это устроено: Почему 0–255, а не километры в час
Число в analogWrite — это не скорость, а доля времени, когда мотор включён. При 255 он включён всё время, при 100 — примерно 40 % времени. Настоящая скорость зависит ещё от батареи и пола. Поэтому скорость подбирают опытом.
Требование 2. Оба колеса крутятся вперёд ровно одну секунду со скоростью из одной именованной переменной speed и останавливаются. Правый мотор подключён к контактам 4 (направление) и 5 (скорость). Начни со своей программы для левого мотора и сохрани её как L21_Both_Motors.
Исследование: с какого числа колесо трогается. На подставке ставь speed = 20, 40, 60, 80… и запиши для каждого колеса, при каком наименьшем числе оно начинает уверенно крутиться.
speed | Левое крутится? | Правое крутится? |
|---|---|---|
| 20 | ||
| 40 | ||
| 60 |
Будут ли эти числа одинаковыми у двух колёс? А у тебя и у соседней команды?
Подсказка: Колесо гудит, но не крутится
Мотору не хватает силы сдвинуть редуктор. Такое число — ещё «мёртвая зона».
Оба колеса крутятся одну секунду и останавливаются. В журнале — наименьшая скорость трогания для каждого колеса и вывод, какие числа speed брать нельзя.
Найди ошибку остановки
10 минСоседи перенесли команды движения в loop() и убрали остановку:
void loop() {
analogWrite(LEFT_SPEED_PIN, speed);
analogWrite(RIGHT_SPEED_PIN, speed);
delay(1000);
}
Они ждали, что робот проедет одну секунду. Что будет на самом деле и почему? Как исправить?
Ты можешь объяснить: delay только ждёт, моторы сами не выключаются, а loop() повторяет команды снова и снова.
Соседи перенесли движение в loop() и добавили остановку:
void loop() {
analogWrite(LEFT_SPEED_PIN, speed);
analogWrite(RIGHT_SPEED_PIN, speed);
delay(1000);
analogWrite(LEFT_SPEED_PIN, 0);
analogWrite(RIGHT_SPEED_PIN, 0);
}
Они ждали: секунду едет, потом стоит. На подставке колёса крутятся почти без остановки. Почему?
- Запиши ответ в журнал.
- Предложи два разных исправления и запиши их кодом: одно — без
loop(), второе — оставив движение вloop().
Подсказка: Второе исправление
Можно ли после остановки «застрять» на месте, чтобы loop() больше не повторялся? Вспомни защиту из урока 1.1… или пустой бесконечный цикл while (true) { }.
Ты можешь объяснить, почему остановка длится мгновение, и в журнале два исправления.
У соседей loop() пустой, а движение — в setup():
void forward(int ms) {
drive(FORWARD, speed, FORWARD, speed);
delay(ms);
}
void setup() {
// … настройка контактов
forward(1000);
}
void loop() {
}
Робот должен был проехать одну секунду, а едет, пока его не выключат. Почему, если loop() пустой? Запиши ответ в журнал.
Требование. Перепиши программу так, чтобы движение осталось в loop(), но робот проехал ровно одну секунду и больше не трогался. while (true) использовать нельзя.
- Проверь на подставке: колёса крутятся одну секунду и стоят, пока не нажмёшь Reset.
- Объясни в журнале, как твоя программа «помнит», что движение уже было.
Подсказка: Идея
Нужна переменная, которая хранит «уже ехали» — bool. Её проверяют в начале loop().
Программа выполняет требование, объяснение записано.
Оформи движения функциями
15 минПисать каждый раз по четыре строки неудобно. Соберём их в функции: forward(), backward(), stopMotors(). Внутри них — знакомые команды.
- Создай скетч
L21_Movesи набери программу.
const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; int speed = 100; void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void forward(int ms) { drive(FORWARD, speed, FORWARD, speed); delay(ms);} void backward(int ms) { drive(BACKWARD, speed, BACKWARD, speed); delay(ms);} void stopMotors() { analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); delay(2000); // время убрать руки от робота forward(1000); stopMotors(); delay(500); backward(1000); stopMotors();} void loop() {}
- Найди, где функции описаны и где они вызываются. Покажи напарнику.
Как это устроено: Как устроена функция с параметром
void forward(int ms) — функция с именем forward и параметром ms. Когда пишем forward(1000), внутри функции ms равно 1000. Так одна функция умеет ехать любое время.
drive(…) — вспомогательная функция: она сразу задаёт направление и скорость обоих колёс. Ей пользуются остальные функции.
Программа проверяется без ошибок. Ты можешь показать описание и вызов forward.
Писать каждый раз по четыре строки неудобно. Соберём их в функции: forward(), backward(), stopMotors(). Функции drive и forward в шаблоне — образец.
- Создай скетч
L21_Movesпо шаблону. Напишиbackward,stopMotorsи движение вsetup()сам.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях.// Функции drive и forward ниже — образец. const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH;int speed = 100; // ===== Твоя часть: напиши сам ===== void backward(int ms) { // Оба колеса крутятся назад со скоростью speed ms миллисекунд.} void stopMotors() { // Оба мотора стоят.} void setup() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); delay(2000); // время убрать руки от робота // Вперёд 1 секунду, остановка, пауза полсекунды, назад 1 секунду, остановка.} // ===== Образец — не меняй ===== void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void forward(int ms) { drive(FORWARD, speed, FORWARD, speed); delay(ms);} void loop() {}
- Найди, где функции описаны и где они вызываются. Покажи напарнику.
Подсказка: Функция назад
Чем «назад» отличается от «вперёд»? В программе уже есть константа для этого направления.
Подсказка: Как вызвать функцию
Вызов — имя функции и значение параметра в скобках, в конце ;.
Как это устроено: Как устроена функция с параметром
void forward(int ms) — функция с именем forward и параметром ms. Когда пишем forward(1000), внутри функции ms равно 1000. Так одна функция умеет ехать любое время.
Программа проверяется без ошибок. Ты можешь показать описание и вызов backward.
Требование 3. Программа L21_Moves построена из функций:
drive(leftDir, leftSpeed, rightDir, rightSpeed)— единственное место, где задаются направление и скорость колёс;forward(ms)иbackward(ms)— движение на заданное время,stopMotors()— остановка;- направление «назад» не записано числом, а получено из
FORWARD: на другом комплектеFORWARDможет быть другим; - после включения есть 2 секунды, чтобы убрать руки;
- в
setup(): вперёд 1 секунду, стоп, пауза полсекунды, назад 1 секунду, стоп.
Подсказка: Идея (1 из 3)
Сначала одна общая функция, которая ставит направление и скорость обоих колёс. Остальные функции только вызывают её с нужными значениями.
Подсказка: План (2 из 3)
drive— четыре строки из своей программы, но с параметрами вместо чисел.forward(ms)—driveвперёд иdelay(ms).backward(ms)— то же назад.stopMotors()— скорость 0.
Подсказка: Фрагмент кода (3 из 3)
const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; — прочитай как «если FORWARD равен HIGH, то LOW, иначе HIGH».
Программа выполняет требование 3 и проверяется без ошибок.
Первый заезд по полу
15 минОсвободи на полу или столе место не меньше метра вперёд и назад. Держи руку рядом с выключателем.
- Загрузи программу на подставке и проверь: вперёд, пауза, назад, стоп.
- Поставь робота на пол, включи питание моторов и нажми Reset.
- Отметь на полу мелом или скотчем точку старта и точку, где робот остановился.
Робот проезжает вперёд, останавливается и возвращается примерно на место старта.
| Что видишь | Что сделать |
|---|---|
| Робот едет не прямо | Моторы не одинаковые — это нормально. Запиши, куда уводит. |
| Робот вернулся не на старт | Вперёд и назад колёса крутятся чуть по-разному. Запиши разницу. |
| Робот поехал сразу после загрузки | Так и есть: программа стартует сама. Поэтому в setup() есть пауза 2 секунды. |
- Загрузи программу на подставке и проверь: вперёд, пауза, назад, стоп.
- Поставь робота на пол, отметь старт скотчем, включи питание моторов и нажми Reset.
- Повтори три раза. Каждый раз отметь, где робот остановился, и измерь линейкой, на сколько сантиметров он ушёл от старта вперёд-назад и вбок.
| Заезд | Вперёд или назад, см | Вбок, см | Куда уводит |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 |
- Одинаково ли робот ошибается в трёх заездах? Запиши вывод.
Таблица из трёх заездов и вывод: куда и насколько уводит твоего робота.
| Что видишь | Что сделать |
|---|---|
| Робот едет не прямо | Моторы не одинаковые — это нормально. Запиши, куда уводит. |
| Робот поехал сразу после загрузки | Так и есть: программа стартует сама. Поэтому в setup() есть пауза 2 секунды. |
Узнай, насколько прямо едет твой робот, и попробуй это исправить одним изменением.
- Проверь программу на подставке, потом поставь робота на пол у начала метровой полосы скотча. Проедь вперёд 2 секунды. Измерь, на сколько сантиметров нос ушёл вбок от полосы. Повтори три раза.
- Предложи одно изменение, которое уменьшит увод: например, разные скорости левого и правого колеса. Запиши, почему ты ожидаешь улучшения.
- Сделай изменение и снова три заезда. Стало лучше? На сколько?
| Увод 1, см | Увод 2, см | Увод 3, см | |
|---|---|---|---|
| До | |||
| После |
Подсказка: Колёса разные
Если робот уходит вправо, какое колесо крутится быстрее?
Две серии по три заезда, одно изменение с обоснованием и вывод по числам.
Измени программу
10 мин- Сделай так, чтобы робот проехал вперёд в два раза дальше, а назад — как раньше.
- Сделай «челнок»: вперёд — назад три раза подряд с паузами.
- Сделай так, чтобы робот проехал вперёд в два раза дальше, а назад — как раньше.
- Сделай «челнок» — вперёд, стоп, назад, стоп три раза подряд, — написав вызовы
forward,stopMotors,backwardтолько один раз. Нужен циклforиз урока 1.1.
Вернётся ли робот после трёх челноков точно на старт? Запиши прогноз, потом отметь старт и финиш на полу.
Подсказка: Как устроен for
for (int i = 0; i < 3; i++) { … } повторяет команды в скобках три раза.
Робот выполняет оба задания. В журнале — прогноз и насколько робот ушёл от старта после трёх челноков.
Требование 4. Функция shuttle(times, ms) делает «челнок» times раз: вперёд ms миллисекунд, стоп, назад, стоп. Вызовы движений в ней написаны один раз.
Исследование: сколько проезжает робот.
- Три раза запусти
forward(1000)приspeed = 100и измерь путь линейкой в миллиметрах. Повтори приspeed = 200. - Посчитай, сколько миллиметров в секунду проезжает робот при каждой скорости. Во сколько раз отличаются результаты? Вдвое ли, как отличаются числа
speed? - Подбери время
backwardтак, чтобы после одного челнока робот вставал не дальше 2 см от старта. Запиши, почему вперёд и назад время получилось разным.
speed | Путь 1, мм | Путь 2, мм | Путь 3, мм | мм за секунду |
|---|---|---|---|---|
| 100 | ||||
| 200 |
Подсказка: Пути разные при одной программе
Это нормально: колёса проскальзывают, батарея садится. Поэтому меряем три раза и берём среднее.
shuttle работает. В журнале — таблица путей, скорость в мм/с для двух speed, вывод про связь числа speed и настоящей скорости и подобранное время возврата.
Робот проезжает вперёд 1 секунду, останавливается и возвращается назад.
Сделай «челнок» из трёх повторов, написав вызовы forward, stopMotors, backward только один раз. Подсказка: цикл for из урока 1.1.
Измерь, сколько миллиметров робот проезжает за секунду, и подбери время назад так, чтобы после челнока он вставал не дальше 2 см от старта. Запиши, почему время вперёд и назад разное.
Проверь себя
Выберите ответы для подготовки. Они не сохраняются и не оцениваются на сайте. Пройдите проверку знаний в программе курса или обсудите ответы с преподавателем.
● Основное
★ Средний уровень
★★ Продвинутый уровень
Отвечай на вопросы своего уровня. Нужно верных ответов: Начальный — 4 из 5; Средний — 4 из 5; Продвинутый — 4 из 5. Ответы проверит преподаватель или программа курса.
Итог
Робот ездит по твоей программе. Главное: analogWrite включает мотор, и он крутится, пока другая команда его не остановит. Функции делают программу короче и понятнее. В следующем уроке робот научится поворачивать.
Как подтвердить результат
Для каждого опыта сохраняй условия, версию программы, наблюдение и вывод. Сравнивая попытки, меняй одну причину за раз; неудачные попытки тоже остаются в журнале. Отметка результата относится к уже выполненным действиям, повторять их ради отметки не нужно. Если результат не получен, запиши расхождение и следующую проверяемую гипотезу. Модель, измерения настоящего робота и объяснение — разные виды доказательств.
Словарь урока
| ШИМ | Частое включение и выключение питания мотора. Число от 0 до 255 задаёт, какую долю времени мотор включён. |
| направление | Состояние контакта направления: одно значение крутит колесо вперёд, другое — назад. |
| константа | Число с именем, которое не меняется во время работы программы, например номер контакта. |
| функция | Именованный блок команд. Его можно вызвать много раз, написав имя и скобки. |
| параметр | Число, которое передают функции в скобках, например время движения. |