Перейти к содержимому
4. Энкодер и кнопки: протокол ввода

4. Энкодер и кнопки: протокол ввода

Занятия 4–5. Энкодер и кнопки: протокол ввода судьи

Занятие 4. Энкодер как устройство ввода

Цель занятия: обучающиеся вводят цифру 1–8 поворотом стрелки на шкале с 8 делениями.

Разминка-вспоминание (5 мин)

  1. Первое действие с датчиком освещённости на новом месте?
  2. Как гасятся выбросы датчика? (интервальный возврат: занятие 2)
  3. Стенка на 12 см, порог 15 см — что выведет Задание 1: 0 или 1?

Разбор (worked example): шкала 8 делений

Конструкция (компетенция 7): неподвижный картонный круг на раме, размечен на 8 секторов по 45° с цифрами 1–8; на оси мотора — стрелка. Регламент разрешает крутить стрелку вручную — мотор работает как энкодер: программа читает угол оси по счётчику энкодера.

Математика перевода угла в цифру: dialDeg() отдаёт угол от нулевой метки в диапазоне 0…359° (счётчик энкодера по модулю одного оборота). Делим на 45:

pos ← угол оси от нулевой метки      # 0..359
цифра ← целая часть (pos / 45) + 1   # сектора: 0-44°→1, 45-89°→2, … 315-359°→8
#include "stend.h"

int encoderDigit() {
  return dialDeg() / 45 + 1;               // 0..359 -> 1..8, деление целых
}

void setup() {
  Serial.begin(115200);
  stendBegin();
}

void loop() {
  int d = encoderDigit();
  Serial.printf("Ввод: %d\n", d);
  screen(String(d));
  delay(150);
}

Разбор: dialDeg() отсчитывает угол от положения стрелки при включении питания — перед стартом ставьте стрелку на начало сектора «1», иначе введите программную поправку (pos = (pos - SDVIG + 360) % 360 — в C++ остаток от отрицательного числа отрицательный, поэтому + 360); показ текущей цифры в реальном времени — обязательная часть UX: судья и участник видят, что вводится, до подтверждения.

Компетенция 1.3.3 включает и вариант «положительный угол → 1, отрицательный → −1»: это тот же угол, но со знаком: счётчик энкодера без приведения к 0…359 и одно условие. Диапазоны из регламента (0–90 → 1, 91–180 → 2, …) — тот же приём с делителем 90 вместо 45.

Практика

Изготовить шкалу

Круг из картона, 8 равных секторов (транспортир: 45°), цифры крупно по краю. Закрепить на раме, стрелку — на ось.

Совместить ноль

Добиться, чтобы «1» читалась во всём своём секторе: покрутить стрелку по границам секторов, при рассинхроне добавить программную поправку.

Ввести серию

Партнёр называет цифры — вводите поворотом. «Введи 3, 7, 1» — три из трёх на экране.

Мини-проверка выхода занятия 4

Ввод трёх названных цифр подряд без промаха; вопрос: «почему pos / 45 + 1, и что изменится, если объявить pos как float?»


Занятие 5. Кнопки, автомат ввода, ГСЧ — и сдача Задания 1

Цель занятия: обучающиеся реализуют конечный автомат «команда судьи → ввод → подтверждение кнопкой → вывод» без перезапуска программы.

Разминка-вспоминание (5 мин)

  1. Стрелка на 200° при шкале из 8 секторов — какая цифра?
  2. Что будет, если не ждать отпускания кнопки?
  3. Из чего складываются 25 баллов Задания 1?

Разбор (worked example): автомат ввода

Все мини-задачи регламента устроены одинаково — это конечный автомат:

    stateDiagram-v2
    [*] --> Ожидание: старт программы
    Ожидание --> ВводA: команда судьи
    ВводA --> ПоказA: кнопка-подтверждение
    ПоказA --> ВводB: команда судьи
    ВводB --> ПоказB: кнопка-подтверждение
    ПоказB --> Результат: кнопка
    Результат --> [*]: либо следующий раунд без перезапуска
  

Шаблон, в который подставляется любой способ ввода (энкодер, карточка, датчик расстояния) и любая обработка:

#include "stend.h"

int encoderDigit() {
  return dialDeg() / 45 + 1;
}

void waitPress(Btn b = BTN_R) {      // ждать нажатие И отпускание — иначе одно нажатие сработает дважды
  while (!pressed(b)) delay(10);
  while (pressed(b))  delay(10);
}

void show(int v) {
  Serial.println(v);
  screen(String(v));
  delay(5000);                             // «не менее 5 секунд» — требование регламента
}

int vvod(const char* imya) {
  Serial.printf("Вводите %s и нажмите правую кнопку\n", imya);
  waitPress(BTN_R);
  int v = encoderDigit();
  show(v);                                 // вывод введённого значения — это баллы!
  return v;
}

void setup() {
  Serial.begin(115200);
  stendBegin();
  int a = vvod("A");
  int b = vvod("B");
  waitPress();
  show(a + b);                             // здесь любая обработка
}

void loop() {}

Три системных правила, которые дают баллы: вывод каждого введённого значения — в таблицах Заданий 2–4 за это отдельные строки по 5 баллов; удержание вывода ≥5 с — прямое требование Задания 3; никаких перезапусков внутри задачи, если регламент их не разрешил.

Двухразрядное число (компетенция 2.1): два последовательных ввода — десятки и единицы: chislo = d1 * 10 + d2. Генератор случайных чисел: random(-5, 6) — верхняя граница в Arduino не входит — обязательно сразу вывести на экран/консоль, это оцениваемое событие.

Практика

Собрать автомат «A, B → сумма»

По шаблону: ввод энкодером, подтверждение правой кнопкой, вывод каждого значения на 5 с.

Двухразрядное число

Ввести 47: десятки → кнопка → единицы → кнопка → «47» на экране.

ГСЧ в диапазоне

По кнопке — случайное число от −5 до 5 на экран (заготовка Задания 4). Проверить, что выпадают и отрицательные, и ноль.

Контрольная точка: сдача Задания 1

Наставник — судья, полный протокол занятия 2, без перезапуска. Цель — 25/25.

Техника безопасности. Стрелку ввода крутить за стрелку, а не за ось мотора; при подтверждении кнопкой придерживать раму — сдвиг устройства ломает измерения расстояния в интегральных задачах.

Типичные ошибки

  1. Дребезг кнопки — одно нажатие засчитывается дважды, автомат перескакивает состояние. Лечится ожиданием отпускания (waitPress).
  2. Не вывели введённое значение — обработка верна, но 5-балльные строки «выведено значение A/B» потеряны.
  3. Вывод мигнул на полсекунды — судья не успел зафиксировать; держите ≥5 с.
  4. ГСЧ вне диапазона — перепутали random(-5, 6) с random(-5, 5) (5 никогда не выпадет) или с random(0, 6). Диапазон — из условия дня, не из привычки.

Мини-проверка выхода

Задание 1 сдано на полный балл; блиц: «какие три события в Заданиях 2–4 оплачиваются по 5 баллов независимо от правильности вычисления?» (вывод A, вывод B, удержание вывода по протоколу)

Уровни сложности