Arduino Style Guide: руководство по написанию понятного кода и уроков
Руководство по написанию чётких примеров и уроков для Arduino, понятных как новичкам, так и опытным разработчикам.
Это практическое руководство для тех, кто хочет писать примеры и уроки для Arduino так, чтобы их понял и новичок, и опытный разработчик. Следовать этим советам необязательно, но если вы хотите, чтобы ваш код был понятен людям с любым уровнем подготовки — они очень помогут.
Это не жёсткий стандарт, а набор рекомендаций. Часть из них может даже противоречить друг другу — используйте здравый смысл и, если сомневаетесь, спросите у того, кто будет учиться по вашему материалу. Возможно, вам также будет полезен Arduino Style Guide for Creating Libraries.
Если вы хотите внести вклад в документацию Arduino, инструкции по оформлению материалов находятся в папке contribution-templates в репозитории Arduino Documentation repository.
Как писать урок
Большинство этих советов собраны из опыта редакторов за долгие годы. Вот список рекомендаций, которым стоит следовать при написании учебных материалов.
- Пишите в активном залоге.
- Пишите живо и разговорно — как будто человек, который читает ваш урок, сидит рядом с вами.
- Давая инструкции, обращайтесь к читателю во втором лице: так он понимает, что именно ему предстоит действовать.
- Используйте короткие, простые, утвердительные предложения вместо сложноподчинённых. Одна инструкция за раз усваивается лучше.
- Формулируйте указания чётко и конкретно, например:
- «Теперь считайте значение с датчика...»
- «Создайте переменную thisPin...»
- Избегайте фраз, которые не несут смысла. Не пишите «Вам нужно настроить пины» — просто напишите «Настройте пины».
- Используйте фотографии и схемы, а не только принципиальные схемы. Многие радиолюбители не умеют их читать.
- Проверяйте свои допущения. Знаком ли читатель со всеми концепциями, которые вы используете? Если нет — объясните их или дайте ссылку на другой урок.
- Объясняйте вещи концептуально: сначала дайте читателю общую картину того, что он будет делать, а потом — пошаговые инструкции.
- Когда впервые используете технический термин — дайте ему определение. Попросите кого-нибудь проверить, все ли новые термины объяснены: скорее всего, один-два вы пропустили.
- Будьте последовательны в терминологии. Если вы называете компонент или концепцию новым именем, явно укажите связь со старым. Не используйте два термина как взаимозаменяемые, не предупредив об этом читателя.
- Не используйте аббревиатуры без расшифровки.
- Пусть каждый пример делает одну вещь хорошо. Не смешивайте концепции и функции, если только урок не посвящён именно их совместному использованию.
Написание примеров кода
Эффективность — не главное. Главное — читаемость.
Самая важная аудитория Arduino — это новички и люди, которым не важен код сам по себе, а важно реализовать проект. Думайте о тех, кто знает о коде меньше вас. Не считайте, что они обязаны понимать какую-то техническую концепцию: они её не знают, и это не делает их глупыми. Ваш код должен объяснять себя сам — или с помощью комментариев. Если нужна сложная концепция вроде регистров, прерываний или указателей — либо объясните её, либо обойдитесь без неё.
Когда приходится выбирать между технически простым и технически эффективным решением — выбирайте простое.
Вводите новые концепции только тогда, когда они действительно нужны, и старайтесь минимизировать их количество в каждом примере. Например, в самом начале можно объяснить простые функции, используя только тип int и не прибегая к const для именования пинов. В более продвинутых уроках можно постепенно вводить дополнительные концепции: использование const int для номеров пинов, выбор byte вместо int, когда значения не превышают 0–255, и т.д. Всё это полезно, но не критично для старта — используйте такие приёмы осторожно и обязательно объясняйте их, когда они впервые появляются в вашем уроке.
Размещайте setup() и loop() в начале программы. Это помогает новичкам получить общее представление о программе, поскольку все остальные функции вызываются именно из этих двух.
Комментирование кода
- Комментируйте каждое объявление переменной или константы — поясняйте, для чего она нужна.
- Комментируйте каждый блок кода. По возможности делайте это перед блоком, чтобы читатель знал, что его ждёт.
- Комментируйте каждый цикл
for.
Пишите if-условия развёрнуто. Для простоты восприятия начинающими всегда используйте блочный формат. Избегайте такого:
if (distance > 10) moveCloser();
Вместо этого пишите так:
if (distance > 10) {
moveCloser();
}
Избегайте указателей.
Избегайте #defines.
Переменные
- Не используйте однобуквенные имена переменных. Давайте им описательные имена.
- Избегайте имён вроде
valилиpin. Лучше используйте что-то конкретное, напримерbuttonStateилиswitchPin.
Если нужно задать имена пинов или другие неизменяемые величины — используйте const int. Они аккуратнее, чем #defines, и при этом дают возможность объяснить разницу между переменной и константой.
Используйте типы переменных в стиле Wiring/Processing: boolean, char, byte, int, unsigned int, long, unsigned long, float, double, string, array, void — там, где это возможно. Не используйте uint8_t и подобные типы без необходимости: первые задокументированы и имеют более понятные имена.
Избегайте схем нумерации, которые запутывают пользователя, например:
pin1 = 2
pin2 = 3
Если нужно перенумеровать пины, используйте массив:
int myPins[] = { 2, 7, 6, 5, 4, 3 };
Это позволяет обращаться к новым номерам пинов через элементы массива:
digitalWrite(myPins[1], HIGH); // включает pin 7
А также включать или выключать все пины в нужной последовательности:
for (int thisPin = 0; thisPin < 6; thisPin++) {
digitalWrite(myPins[thisPin], HIGH);
delay(500);
digitalWrite(myPins[thisPin], LOW);
delay(500);
}
Оформление заголовочного блока кода
Вот пример хорошего заголовочного блока:
/*
Название скетча
Опишите простыми словами, что он делает. Укажите компоненты,
подключённые к соответствующим пинам.
Схема:
* перечислите компоненты, подключённые к каждому входу
* перечислите компоненты, подключённые к каждому выходу
Создан день месяц год
Автор: имя автора
Изменён день месяц год
Автор: имя автора
http://url/of/online/tutorial.cc
*/
Схемы подключения
Для цифровых входов с кнопками по умолчанию используйте подтягивающий резистор к земле (pull-down), а не к питанию (pull-up). Так логика взаимодействия с кнопкой будет понятна людям без инженерного образования.
Держите схемы простыми. Например, развязывающие конденсаторы бывают полезны, но большинство простых входов работают и без них. Если компонент не является ключевым — объясните его позже, когда читатель уже освоился.
Практические замечания
- Проверяйте на целевой аудитории. Дайте прочитать урок человеку с нужным уровнем подготовки до публикации. Вы удивитесь, сколько очевидных для вас вещей окажутся непонятными.
- Один пример — одна идея. Соблазн показать сразу несколько приёмов велик, но новичок теряется, когда в одном скетче смешаны
millis(), массивы и прерывания. - Комментарии — не роскошь. В учебном коде комментариев не бывает «слишком много». Лучше объяснить лишнее, чем оставить читателя в недоумении.
- Не усложняйте схему. Минималистичная схема, которая работает, лучше технически правильной схемы, которую сложно собрать на макетной плате за пять минут.