Урок 1. 12 байт, каждый с работой
Урок 1. 12 байт, каждый с работой: проектируем формат пакета
Паспорт урока
| Параметр | Значение |
|---|---|
| Место в модуле | BeaconRadio, модуль 1 «Информатика», урок 1 из 7 |
| Длительность | 45 мин |
| Возраст | 12–16 |
| Оборудование | Компьютер, бумага в клетку; желательно плата с прошивкой |
| Предварительные знания | Двоичная и шестнадцатеричная системы (базово) |
| Предмет | Информатика (представление данных) |
Образовательные цели
| № | Цель | Блум | Миллер | Чем доказывается |
|---|---|---|---|---|
| 1.1 | Проектировать бинарный пакет: раскладывать величины по байтам | применять | показывает как | Пакет, собранный на бумаге |
| 1.2 | Упаковывать булевы флаги в битовое поле | применять | показывает как | Собранный статус-байт 0x69 |
| 1.3 | Обосновывать целочисленное представление вместо дробного | оценивать | знает как | Ответ: 4 байта против 8 |
| 1.4 | Объяснять роль порядка байт (little-endian) | понимать | знает как | Разбор записи lat×1e7 |
Сценарий занятия (45 минут)
| Время | Блок | Что делает педагог | Что делают ученики |
|---|---|---|---|
| 0–7 | Постановка | Легенда маячка, вопрос «что послать?» | Перечисляют нужные данные |
| 7–15 | Проблема размера | «А сколько это байт? Эфир дорогой» | Оценивают наивный размер |
| 15–28 | Теория | Целые числа, порядок байт, битовые флаги | Разбирают формат |
| 28–40 | Практика | Собирают пакет на бумаге | Решают задачи |
| 40–45 | Итог и ДЗ | Фиксация | Записывают |
Блок 1. Постановка задачи (0–7 мин)
Легенда
«Мы делаем маячок для пожилого человека с деменцией. Он может уйти и потеряться, может упасть. Маячок должен рассказывать диспетчеру, где человек и что с ним. Вопрос: что именно маячок должен передавать?»
Класс перечисляет, педагог фиксирует на доске:
| Что нужно знать диспетчеру | Данные |
|---|---|
| Где человек | широта, долгота |
| Какой маячок (их много) | номер устройства |
| Нажал ли кнопку помощи | флаг SOS |
| Не упал ли | флаг падения |
| Не лежит ли без движения | флаг неподвижности |
| Работает ли GPS | флаг валидности |
| Не сел ли аккумулятор | заряд, флаг разряда |
Ключевой вопрос урока
«Всё это надо уложить в один короткий пакет и послать по радио. Почему короткий? Потому что эфир — общий ресурс, а батарея — ограничена. Чем длиннее пакет, тем дольше передача, тем больше энергии и тем меньше места для других. Наша задача — уложить всё нужное в минимум байт.»
Блок 2. Проблема размера (7–15 мин)
Наивный подход
«Давайте прикинем размер “в лоб”. Координата — дробное число вроде 55.6306. Как компьютер хранит дробное число?»
Ответ: тип double — 8 байт. Значит две координаты — 16 байт только на позицию. Плюс всё остальное — получается более 20 байт.
Постановка проблемы оптимизации
«20 байт — много. Можно ли меньше, ничего не потеряв? Оказывается, да — и это работа инженера: уложить те же данные плотнее.»
Записать на доску целевую цифру: 12 байт. Весь урок — путь к ней.
Блок 3. Теория (15–28 мин)
3.1. Базовый уровень (12–14 лет)
Идея 1. Координата — это целое число, если убрать точку.
Широта 55.6306 — это то же, что 556 306 000, если умножить на 10 миллионов. А целое число до пары миллиардов помещается в 4 байта вместо 8. Мы просто «запомнили», что надо потом поделить обратно.
Идея 2. Восемь фактов — в одном байте.
Флаги «нажал SOS», «упал», «лежит», «GPS работает», «батарея села» — это ответы да/нет. Каждый ответ — один бит. В одном байте восемь битов, значит восемь ответов помещаются в один байт вместо восьми.
Аналогия:
Это как список галочек в анкете: не пишешь «да» словом пять раз, а ставишь пять галочек в одной строке.
3.2. Углублённый уровень (14–16 лет)
Шаг 1. Итоговый формат — 12 байт.
| Смещение | Размер | Поле | Тип | Назначение |
|---|---|---|---|---|
| 0 | 1 | id | uint8 | номер маячка |
| 1–4 | 4 | lat | int32 | широта × 10⁷ |
| 5–8 | 4 | lon | int32 | долгота × 10⁷ |
| 9 | 1 | status | биты | 5 флагов + счётчик |
| 10 | 1 | battery | uint8 | заряд, % |
| 11 | 1 | crc8 | uint8 | контрольная сумма |
Шаг 2. Целочисленное представление координаты.
Вместо double (8 байт) координата хранится как int32:
Для 55.6306: 556 306 000 — умещается в int32 (диапазон ±2,1 млрд). Точность 10⁻⁷ градуса — это около 1 см на местности, заведомо избыточно для GPS (его точность — метры).
Выигрыш: 4 байта вместо 8 на каждую координату, и никаких операций с плавающей точкой в эфире.
Шаг 3. Порядок байт (endianness).
Число 556 306 000 в шестнадцатеричном виде — 0x21288E50. В памяти четыре байта можно расположить двумя способами:
| Порядок | Байты в эфире | Кто использует |
|---|---|---|
| little-endian | 50 8E 28 21 (младший первым) | x86, ARM, наш стенд |
| big-endian | 21 28 8E 50 (старший первым) | сетевые протоколы («сетевой порядок») |
Отправитель и получатель должны договориться о порядке, иначе число прочитается неверно. Наш стенд использует little-endian — «родной» для процессора, не требует перестановки.
Шаг 4. Битовое поле статуса.
Байт status упаковывает восемь фактов:
| Бит | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Значение | seq | seq | seq | low_batt | gps_valid | immobile | fall | SOS |
Биты 0–4 — пять флагов. Биты 5–7 — счётчик seq (0…7 по кругу).
Зачем seq. Вместе со счётчиком кадров LoRaWAN он мгновенно показывает, где теряются пакеты: дыры в счётчике на сервере — проблема в эфире или шлюзе; кадры есть, а строк в базе нет — проблема в обработке. Три бита превращаются в диагностический инструмент.
Шаг 5. Как собрать байт статуса.
Оператор << сдвигает бит на нужную позицию, ∨ (побитовое ИЛИ) объединяет.
Блок 4. Практикум: собираем пакет (28–40 мин)
Работа на бумаге в клетку, в парах.
Разбор примера вместе с классом
Событие: нажата кнопка SOS, GPS работает, seq = 3.
Флаги: SOS = 1, fall = 0, immobile = 0, gps_valid = 1, low_batt = 0, seq = 3.
Проверить по битам:
| Бит | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Значение | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 |
| └─ seq=3 ─┘ | low=0 | gps=1 | im=0 | fall=0 | SOS=1 |
01101001 = 0x69. Сходится.
0x29 → 0x49 → 0x69 → 0x89. Это SOS с растущим seq (1, 2, 3, 4). Ученики могут разобрать эту последовательность сами — она подтверждает, что их расчёт совпадает с настоящей прошивкой.Блок 5. Практические задачи (внутри блока 4)
Уровень A (12–14 лет)
A1. Сколько фактов «да/нет» помещается в один байт? Почему?
Ответ
Восемь — потому что в байте восемь битов, а каждый бит хранит один ответ да/нет (0 или 1).
A2. Почему координату умножают на 10 миллионов и хранят как целое число?
Ответ
Чтобы избавиться от дробной части: целое число занимает 4 байта вместо 8 у дробного, и с ним проще и надёжнее работать. Множитель 10⁷ сохраняет точность до сантиметра — этого более чем достаточно.
A3. Соберите статус-байт для события: GPS работает, остальное выключено, seq = 0.
Ответ
Только бит 3 (gps_valid): 00001000 = 0x08. Это обычный телеметрический пакет — «всё спокойно, координата свежая».
Уровень B (14–15 лет)
B1. Соберите статус-байт для события: обнаружено падение, человек неподвижен, GPS работает, seq = 5.
Решение
fall = 1 (бит 1), immobile = 1 (бит 2), gps = 1 (бит 3), seq = 5 (биты 5–7).
Проверка по битам: 10101110 = 0xAE. Сходится.
B2. Координата долготы 37.6033. Как она запишется в 4 байта (int32, little-endian)?
Решение
37.6033 × 10⁷ = 376 033 000 = 0x1669CEE8.
В little-endian (младший байт первым) в эфир уйдут байты: E8 CE 69 16.
Проверка обратно: 0x1669CEE8 = 376 033 000; делим на 10⁷ = 37,6033 — исходное значение восстановлено точно.
Замечание для педагога: при программной реализации стоит использовать округление round(v * 1e7), а не отбрасывание дробной части, — иначе на некоторых значениях появится ошибка в последнем разряде из-за представления чисел с плавающей точкой.
B3. Почему отправитель и получатель должны договориться о порядке байт?
Ответ
Число из нескольких байтов можно расположить в памяти двумя способами (младший байт первым или старший первым). Если отправитель пишет одним способом, а получатель читает другим, число прочитается неверно — например, 0x21288E50 превратится в 0x508E2821, то есть в совершенно другую координату. Договорённость о порядке (у нас little-endian) устраняет неоднозначность.
Уровень C (15–16 лет)
C1. Оцените экономию нашего формата по сравнению с наивным (координаты double, флаги — по байту на каждый). Во сколько раз короче?
Решение
Наивный формат:
| Поле | Байт |
|---|---|
| id | 1 |
| lat (double) | 8 |
| lon (double) | 8 |
| 5 флагов (по байту) | 5 |
| battery | 1 |
| Итого | 23 |
Наш формат: 12 байт.
Экономия: 23 / 12 ≈ в 1,9 раза короче. При SF10 это примерно вдвое меньше эфирного времени и энергии на каждый пакет — а маячок шлёт их годами.
C2. Счётчик seq — всего 3 бита (0…7). Не мало ли для диагностики потерь? Обоснуйте.
Разбор
3 бита дают цикл из 8 значений. Этого достаточно, потому что seq работает в паре с 4-байтовым счётчиком FCnt самого LoRaWAN:
FCnt(миллиарды значений) показывает потери на уровне эфир/шлюз;seq(8 значений) показывает потери на уровне обработки после приёма — если между двумя строками в базеseqперескочил, потеряна запись в конвейере.
Для второй задачи 8 значений хватает: если подряд теряется больше 8 пакетов обработки, проблема очевидна и без точного счёта. Тратить больше 3 бит на seq было бы расточительством — байт статуса и так плотно занят.
Вывод: размер поля выбирается под его роль, а не «побольше». 3 бита — точный инженерный выбор.
C3. Предложите, что изменить в формате, если добавить передачу высоты (altitude) и скорости движения. Уложитесь в разумный размер.
Разбор
Высота: диапазон в России примерно от −30 до +5000 м, точность метра достаточно. Помещается в int16 (±32 000) — 2 байта.
Скорость пешехода: 0–10 м/с, с точностью 0,1 м/с — значения 0–100, помещается в 1 байт (uint8).
Итого +3 байта → пакет станет 15 байт. Это приемлемо. Но стоит спросить: нужны ли эти поля для задачи? Для маячка человека с деменцией высота бесполезна, скорость — сомнительна. Лучший инженерный ответ часто: «не добавлять то, что не работает на задачу». Каждое поле должно обслуживать конкретную потребность диспетчера.
Ответы на вопросы, которые прозвучат
| Вопрос ученика | Как отвечать |
|---|---|
| «Почему не послать просто текстом, как сообщение?» | Текст "55.6306,37.6033,SOS" — это ~20 символов = 20 байт только на координаты, плюс разбор строки на приёмнике. Бинарный формат вдвое короче и парсится мгновенно |
| «А если координата отрицательная (западная долгота)?» | int32 — знаковый тип, хранит и отрицательные. −37.6° × 10⁷ уложится так же |
| «Зачем битовые флаги, память же большая?» | В эфире важна не память, а время передачи. Каждый байт — это эфирное время и энергия батареи. Маячок живёт годами, экономия критична |
| «Что если понадобится девятый флаг?» | В байте статуса seq занимает 3 бита. Если нужен ещё флаг — сократить seq до 2 бит или добавить второй байт статуса. Это осознанное проектное решение |
| «Как приёмник поймёт, где кончается одно поле и начинается другое?» | По фиксированной схеме: все знают, что байты 1–4 — широта, 5–8 — долгота. Формат жёстко задан, разделители не нужны |
Раздаточный лист (для печати)
Урок 1. Формат пакета маячка
Задача: уложить данные маячка в 12 байт.
[0] [1 2 3 4] [5 6 7 8] [9] [10] [11] id lat × 1e7 lon × 1e7 status batt CRC8 (int32) (int32) (биты) (%)Битовое поле статуса:
Бит 7 6 5 4 3 2 1 0 seq seq seq low_batt gps_valid immobile fall SOS Формула сборки:
status = SOS | (fall<<1) | (immobile<<2) | (gps<<3) | (low<<4) | ((seq&7)<<5)Задания. Соберите статус-байт:
Событие Биты Результат (hex) SOS, GPS работает, seq=3 Падение, неподвижность, GPS, seq=5 Только GPS (телеметрия), seq=0 Разряд батареи, GPS, seq=0 Перевод координаты в int32:
Широта _______ × 10⁷ = ___________ = 0x________
Мой вывод: зачем нужен компактный бинарный формат?
____________________________________________________
Домашнее задание
Обязательная часть
Врайтап по рубрике А. Обязательный пункт: объясните своими словами, почему координату хранят целым числом, а не дробным.
Уровень A
Придумать формат пакета для другого устройства — например, домашней метеостанции (температура, влажность, давление). Расписать, сколько байт под каждое поле и почему.
Уровень B
Разобрать три статус-байта из лога маячка: 0x29, 0x49, 0x89. Определить для каждого: какие флаги взведены и чему равен seq. Что происходило с маячком?
Ответ для педагога
Все три: бит 0 (SOS) = 1, бит 3 (gps_valid) = 1. seq: 0x29 → 1, 0x49 → 2, 0x89 → 4. Это серия тревожных пакетов SOS с растущим счётчиком (пакет с seq=3, то есть 0x69, между ними потерян или не попал в выборку). Человек нажал кнопку помощи, GPS даёт валидную координату.
Уровень C
Спроектировать формат пакета для маячка с расширенными возможностями: добавить точность GPS (HDOP) и температуру носителя (контроль переохлаждения). Обосновать выбор типа и размера каждого нового поля, оценить итоговый размер пакета и его эфирное время при SF10.
Итог урока: что записать в журнал
Вывод урока 1
- В эфире важен размер пакета: он определяет время передачи и расход батареи.
- Дробную координату хранят как целое
lat × 10⁷: 4 байта вместо 8, без операций с плавающей точкой. - Восемь фактов «да/нет» упаковываются в один байт битовыми флагами.
- Отправитель и получатель договариваются о порядке байт (у нас little-endian).
- Счётчик
seq(3 бита) вместе сFCntпоказывает, где теряются пакеты. - Итог: все данные маячка уложены в 12 байт — вдвое компактнее наивного формата.
Связь с курсом
| Что родилось на этом уроке | Где станет инструментом |
|---|---|
| Проектирование пакета | FoxHunter (пакет лисы), RFCurtain, PowerSentry |
| Битовые флаги | PowerSentry (байт flags), RFCurtain |
| Порядок байт | Любая работа с протоколами |
seq как диагностика потерь | PowerSentry, WarWalk |
Чек-лист педагога перед уроком
- Бумага в клетку по числу учеников
- На доске заготовлена таблица битов статуса
- Проверен пример: SOS+GPS+seq3 = 0x69
- Готов лог маячка со статусами 0x29…0x89 для сверки
- Раздаточный лист распечатан