Плата ехала до меня девять дней, и все девять я честно отрабатывал в симуляторе: мигалка, кнопка, диммер — всё щёлкалось без единой ошибки. Вечер X: Uno на столе, кабель в порту, я нажимаю «Загрузить» на скетче, который гонял десятки раз. Полоса прогресса доползла до середины, у надписей TX и RX на плате пробежали огоньки, среда на пару секунд замолчала — и я закрыл окно: показалось, что зависло. Скетч в это время спокойно загрузился и уже мигал. Я узнал об этом случайно, когда поймал мышкой свёрнутое окно: Done uploading висело себе и ждало.
Переход из симулятора на настоящую плату — не «то же самое, только с проводами». Между вами и кодом появляется прослойка, которой на виртуальной плате нет: компилятор тратит реальное время, среда выбирает порт, загрузчик платы принимает прошивку, а каждое действие руками теперь имеет цену ошибки — от «порт занят» до «не та плата выбрана». Хорошая новость: сам код менять не нужно. Мигалка из симулятора собирается на Uno без единой правки, и это не везение, а принцип — симулятор честно повторяет подмножество настоящего Arduino API.
Здесь — порядок действий, который я в итоге записал на стикере и теперь показываю каждому новичку: что проверить до загрузки, что происходит в пятнадцать секунд после нажатия кнопки, как сверить результат с тем, что вы видели в симуляторе, и три отказа, с которыми я сталкивался чаще всего. Компиляцию и чтение ошибок мы уже разобрали в уроке про первый скетч в среде, саму мигалку собирали с нуля в уроке про светодиод — сейчас склеим это в один вечер с железом.
Что меняется, когда вместо симулятора — плата
Первое отличие заметно сразу после кнопки «Проверить». В симуляторе запуск мгновенный, а на настоящей машине компилятор собирает всё ядро целиком: первая компиляция даже пустого скетча занимает у меня около тридцати секунд на старом ноутбуке и секунд двадцать на новом, повторная после правки одной строки — пять-семь. Это одноразовая цена входа, а не зависание: тулчейн кэшируется, и вторая сборка летает. Если вы до этого дня только в симуляторе, первые тридцать секунд тишины легко принять за поломку — теперь вы предупреждены.
Второе отличие — плата и порт. В симуляторе плата одна и всегда подключена, здесь же среда должна понять, куда шить. В IDE 2 сверху выпадающий список: выбрали плату — среда опознала её и подписала порт, например COM5 или /dev/ttyUSB0. Пока плата не воткнута, список пуст, и это не ошибка. Если плату видно по USB, но ни один порт не появляется — почти всегда виноват драйвер USB-чипа: у клонов с CH340 этому посвящён отдельный разбор.
Третье отличие невидимо, но объясняет загадочные паузы. Между нажатием кнопки и стартом вашего скетча происходит ресет платы, и её загрузчик — маленькая программа, живущая во flash с завода, — успевает принять новую прошивку по UART. Огоньки TX и RX в этот момент честно отражают трафик. Поэтому после надписи Done uploading скетч стартует не мгновенно, а с задержкой около секунды: не глюк, а ритуал загрузчика. Дважды за вечер я успел понажимать RESET на «зависшей» плате, пока не понял, что она просто загружалась.
void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT);} void loop() { digitalWrite(LED_BUILTIN, HIGH); Serial.print("led=1 t="); Serial.println(millis()); delay(100); digitalWrite(LED_BUILTIN, LOW); Serial.print("led=0 t="); Serial.println(millis()); delay(900);}// LED_BUILTIN на Uno и Nano — пин 13 со встроенным светодиодом L.Сверку результата я делаю по трём пунктам, и все три повторяют то, что было видно в симуляторе. Ритм: одна вспышка в секунду — сумма задержек в эталоне как раз 1000 мс. Монитор порта: пары led=1 t=... и led=0 t=... идут с тем же шагом, что и на виртуальной плате, и значения t растут равномерно. Тонкость, до которой я дошёл не сразу: при 9600 бод строка из десяти символов занимает около десяти миллисекунд, поэтому на фоне 900 мс паузы печать незаметна, а вот на циклах в 10-20 мс Serial уже начнёт съедать ритм — полезно знать заранее, чтобы не лечить несуществующий глюк.
Светодиод L встроен в плату, для первого переноса макетка не нужна вообще. Но вечер первой удачной загрузки — идеальный повод добавить второй шаг: внешний светодиод с резистором на макетке, как в уроке про первую схему на макетке. Мигающий L подтверждает, что канал «среда — плата» жив; внешний светодиод подтверждает, что вы уже и схему собрали правильно. Два подтверждения за один вечер — лучшая мотивация, которую я знаю.
История, на которой я потерял полчаса в первый вечер: скетч продолжал работать после того, как я выдернул USB и отключил питание. Я был уверен, что прошивка «живёт в среде», и искал настройку, которая «возвращает программу на плату». Настоящая механика проще: скетч записывается во flash-память контроллера и переживает отключение питания годами. Плата, питаемая зарядкой от телефона, будет мигать без всякого компьютера — среда нужна только для загрузки новой прошивки и для наблюдения через монитор порта. Прежде чем идти дальше, потренируйтесь руками в среде — ниже тренажёр меню Arduino IDE: восемь заданий, от установки библиотеки до Монитора порта, без риска что-то сломать.
| Что | В симуляторе | На настоящей плате |
|---|---|---|
| Запуск после правки | мгновенно, без сборки | компиляция: первая около 30 с, повторная 5-7 с |
| Ошибки схемы | перегоревший светодиод невозможен | перепутанные 5 В и GND греют детали и гасят сигнал |
| Жизнь прошивки | скетч живёт, пока открыта вкладка | flash хранит скетч без питания годами |
| Сброс | кнопка перезапуска у виджета | кнопка RESET или переподключение кабеля |
| Монитор порта | та же панель, порт всегда свободен | тот же монитор, но порт надо освободить перед загрузкой |
8 заданий в симуляции строки меню: от библиотек из реестра до Плоттера порта.
Подгружаем интерактив…
Три отказа первого вечера
Отказ первый — «порт занят». Монитор порта держит COM-порт открытым, и в этот момент загрузка не начинается: среда пишет port busy или avrdude жалуется на доступ. Лечение — закрыть панель монитора и нажать «Загрузить» снова. Я поначалу обижался на «глючную среду», пока не понял договорённость: пока среда слушает порт глазами, она не может говорить ртом. В новых версиях монитор закрывается автоматически, но привычка «сначала закрыл монитор» уже спасла мне нервы на других машинах.
Отказ второй — выбрана не та плата. Ошиблись в списке — загрузчик платы получает байты, которые не понимает, и avrdude отвечает загадочным not in sync. Особенно коварен Nano: у клонов два варианта загрузчика, и если не стартует, загляните в Инструменты, в пункт про процессор — там бывает старый вариант, и это уже тема отдельного урока. Правило простое: перед загрузкой сверяйте название в списке с тем, что написано на плате.
Отказ третий — кабель без данных. Зарядные провода выглядят как настоящие, но в них нет линий данных: плата при этом даже не появляется в списке портов. Проверка за минуту: подключите этим кабелем телефон — если он не предложил передавать файлы, данные по проводу не ходят. Я теперь ношу с собой проверенный кабель и не покупаю «такой же, только дешевле»: сто рублей экономии однажды съели у меня целый вечер.
После первой удачной загрузки закрепите цикл «правка — загрузка — сверка» на осознанном уровне. Измените период: поставьте обе задержки по 100 мс — светодиод замелькает десять раз в секунду, и вы увидите, как повторная загрузка затёрла старую прошивку целиком: во flash лежит ровно то, что уехало последним. Потом верните 100 и 900. Две минуты упражнения — и кнопка «Загрузить» перестаёт быть ритуалом с непредсказуемым исходом.
Дальше по вечерам станет тесно от delay: мигать и одновременно опрашивать кнопку он не даёт. Когда упрётесь — в уроке про millis мы убираем задержки совсем, а пока пары led= и t= в мониторе порта остаются вашим самым дешёвым отладчиком: то, что печатается, всегда честнее того, что кажется.
- 1. Что делает загрузчик платы, когда получает новый скетч?
- 2. Среда пишет, что порт занят, при нажатии «Загрузить». Первое действие?
- 3. Вы отключили USB и внешнее питание платы. Что со скетчем?
- 4. Первая компиляция пустого скетча занимает около 30 секунд, повторная — 5-7. Почему?
- 5. Строки в мониторе идут, а светодиод L не мигает. Что проверить первым?
- Симулятор и плата говорят на одном языке: мигалка переносится без правок кода.
- Пятнадцать секунд после «Загрузить» — это компиляция, ресет, работа загрузчика и огоньки TX/RX.
- Сверяйте ритм вспышек и пары led=/t= в мониторе: цифры совпадут с симулятором.
- Скетч живёт во flash: питание можно снять, прошивка останется.
- Три первых отказа — занятый порт, не та плата в списке, кабель без линий данных.
Частые вопросы по теме урока
- Что делает загрузчик платы, когда получает новый скетч?
- Загрузчик принимает прошивку по UART, записывает её во flash и стартует ваш код. Старый скетч при этом затирается: во flash лежит последний загруженный. Записывает его во flash-память и передаёт управление
- Среда пишет, что порт занят, при нажатии «Загрузить». Первое действие?
- Монитор порта держит порт открытым, и загрузка не может его занять. Кабель и драйверы проверяйте потом — сначала закройте панель монитора. Закрыть монитор порта
- Вы отключили USB и внешнее питание платы. Что со скетчем?
- Flash-память хранит прошивку без питания. Плата, запитанная от зарядки, продолжит выполнять последний загруженный скетч без компьютера. Он остаётся во flash и стартует заново при подаче питания
- Первая компиляция пустого скетча занимает около 30 секунд, повторная — 5-7. Почему?
- Первый запуск — одноразовая цена входа: тулчейн собирает всё ядро. Дальше сборки берут готовый кэш, поэтому правка одной строки компилируется за секунды. В первый раз ядро собирается целиком, потом используется кэш
- Строки в мониторе идут, а светодиод L не мигает. Что проверить первым?
- Без pinMode(LED_BUILTIN, OUTPUT) пин остаётся входом: печать в Serial работает, а мигания нет. Это первая классическая ошибка после переноса на железо. Есть ли в setup pinMode со значением OUTPUT