Переезд с классической среды на IDE 2 у меня совпал со строительством командного пульта: из поля монитора я отправлял плате числа, скетч ел их через parseInt. В классике всё работало, в новой — команды доезжали, а парсер молчал. Полчаса я грешил на новую среду, на драйвер, на клон платы, успел перезагрузить компьютер. Виноват оказался выпадающий список окончания строки: по умолчанию стояло No line ending, к моей команде не дописывался символ новой строки, которого ждал парсер. Тридцать минут из-за одного пункта меню, которого в старой среде вообще не существовало.
Монитор порта в IDE 2 — не просто переехавшее окно: вокруг него появилось полдюжины настроек, из которых новичку бросаются в глаза три, а спасают чаще всего именно невидимые. В этом уроке пройдём по панели справа от кода: скорость, окончания строк, тайм-метки, автопрокрутка, фильтр, очистка — что каждая делает, где ловит и на чём я наступал лично. База — отправка и приём — уже была в уроке про первый запуск монитора; здесь именно фишки, из-за которых монитор превращается в пульт.
Панель справа: что где
Открывается монитор иконкой с лупой в правом верхнем углу или Ctrl+Shift+M; живёт он боковой панелью, а не отдельным окном, и код остаётся на виду — мне это нравится больше всплывающего окна классики, которое закрывало полэкрана. Сверху справа — скорость порта: она обязана совпадать с числом в Serial.begin, это то же правило, что и раньше. Несовпадение выглядит узнаваемо: вместо строк — мусорные кракозябры, потому что биты едут мимо разметки, и ни один код тут не виноват. Слева внизу — поле ввода и кнопка отправки: Enter уводит строку плате, а что она допишет к ней — уже решает список окончания строки. Поле принимает и многострочный текст: Shift+Enter переводит строку, а Enter отправляет всё сразу — для протоколов из нескольких полей это экономит десятки лишних отправок.
Три кнопки в верхней полосе экономят больше времени, чем кажутся. Автопрокрутка: если поток пар пачками вылетает со скоростью двести строк в секунду, выключите её — окно замрёт, и вы рассмотрите строки. Поле фильтра сверху выцепит из потока только строки с вашей подстрокой: напечатайте pot — и увидите исключительно pot= из потока на двести строк. Кнопка очистки стирает историю перед новым прогоном; я жму её перед каждой загрузкой, чтобы не путать свежие пары со старыми и не «находить» эффекты, которых в этом прогоне не было.
| Элемент панели | Что делает | Когда спасает |
|---|---|---|
| Скорость (справа) | Задаёт боды монитора | Кракозябры вместо строк — сверить с Serial.begin |
| Окончание строки | Что дописывать к отправке: ничего, NL, CR, оба | Парсеры на parseInt и readStringUntil |
| Тайм-метки | Печатает миллисекунды перед строкой | Ищете паузы и дребезг без правки кода |
| Автопрокрутка | Тянет окно к новым строкам | Поток быстрее глаза — выключить и рассмотреть |
| Фильтр | Показывает строки по подстроке | Много пар — выцепить свою |
| Очистка | Стирает историю | Новый прогон после загрузки |
Тайм-метки — фишка, ради которой я и переезжал на новую панель: галочка включает печать миллисекунд перед каждой строкой. Отсчёт идёт от открытия монитора, и тут есть нюанс, который сбивает в первые дни: открытие монитора дёргает ресет платы, скетч стартует заново — поэтому метки почти совпадают с возрастом скетча, как будто это его uptime. «Почти» — ключевое слово: между ресетом и открытием окна проскакивают десятки-сотни миллисекунд, и для точных замеров это разные величины; там уже нужен millis() внутри кода, а совсем точные интервалы живут в уроке про замеры на micros.
Для чего метки в практике: вы мигаете светодиодом и хотите увидеть интервал между вспышками, не дописывая в скетч печать времени, — включили метки, посмотрели разность соседних строк. Поймали дребезг кнопки: нажатие одно, а строк событий пять с разницей в пару миллисекунд — вот они, лишние срабатывания, о которых подробно рассказывал урок про дребезг. При этом метки не заменяют Serial.print(millis()) в коде: они ставятся перед вашей строкой на стороне компьютера и показывают момент приёма, а не отправки. На 9600 бодах символ стоит около миллисекунды, и строка из тридцати знаков приплывает с опозданием на тридцать — для медленных пауз это неважно, для быстрых процессов разница решает.
Окончания строки — пункт, на котором я обжёгся, и потому он у меня первым в списке подозреваемых. Список из четырёх значений решает, что среда дописывает к вашей отправке: ничего (No line ending), NL — символ новой строки с кодом 10, CR — возврат каретки с кодом 13, или оба сразу. Скетчу на Serial.parseInt до лампочки: он пропустит всё, что не цифра, и прочитает число. А вот readStringUntil(10) — чтение строки до кода 10 — без NL просто не увидит конца: команда доезжает, но распознаётся как незавершённая. Один и тот же текст ввода, а судьба у него разная — вот почему этот крохотный список вынесен прямо в шапку панели, рядом со скоростью. Моё правило для нового проекта: сначала Both NL & CR, потом упрощай, если парсер оказался чувствительным.
Монитор и загрузка теперь живут дружно: IDE 2 сама отпускает порт перед заливкой и возвращает панель после — в классике монитор приходилось закрывать руками, иначе загрузка спотыкалась о занятый порт. На клонах с CH340 панель иногда сама не оживает после загрузки: щёлкните иконкой с лупой ещё раз, порт жив и скетч уже печатает. И честное ограничение: монитор — не логгер. История исчезает при закрытии панели, файла на диске не создаётся, журнал температуры за ночь в монитор не поместится — для этого есть урок про логирование на SD-карту, где данные пишутся рядом с платой. Даже длина истории ограничена: при многочасовом потоке старые строки уходят вверх навсегда, и то, что вы не успели заметить глазами, монитор не вернёт.
Отдельный приём, который стоит ввести в привычку с первого дня, — печать парами имя=значение. Монитор показывает их текстом, а плоттер превращает каждую пару в подписанный ряд — это подробно разобрано в уроке про Serial Plotter: две линии pot и led различаются глазами, а не порядком цветов. Пары выгодны и фильтру: подстрока pot выцепляет свою серию из потока мгновенно. Печатать числа без префиксов — значит, отдать расшифровку на волю случайности; с префиксами ваш вывод становится протоколом, который читают и вы, и инструменты.
void setup() { Serial.begin(9600); pinMode(12, OUTPUT);} void loop() { int pot = analogRead(A0); int led = 0; if (pot > 512) { led = 1; } digitalWrite(12, led); Serial.print("t="); // метка изнутри кода: момент отправки Serial.print(millis()); Serial.print(" pot="); Serial.print(pot); Serial.print(" led="); Serial.println(led); delay(300);}// Такие пары читают монитор, фильтр и плоттер — и вы через полгода тоже.Тренажёр: команды 1, 2, 3
Ниже — пульт из моей истории переезда, собранный заново по правилам этого урока. Отправьте 1 — плата ответит парой t= с миллисекундами: тайм-метка, только изнутри кода. Отправьте 2 — светодиод мигнёт, в мониторе появится mig=1. Отправьте 3 — отчёт uptime= в секундах. По ходу проверьте окончания строки: поставьте No line ending и убедитесь, что parseInt всё равно съест цифру, — а потом представьте, что вместо него в коде readStringUntil, и команды перестанут доезжать ровно как у меня. Тем же способом плату дёргают из урока про управление светодиодом из монитора.
- 1. Скорость монитора не совпадает с Serial.begin. Что вы увидите?
- 2. Тайм-метки в IDE 2 печатают…
- 3. Почему открытие монитора перезапускает скетч?
- 4. readStringUntil молчит, парсер не видит конца строки. Что проверить первым?
- 5. Монитор — не логгер. Куда девать ночной журнал температуры?
- Ctrl+Shift+M — панель монитора справа; скорость и окончания строки — в верхней полосе.
- Кракозябры — несовпадение бодов; молчащий парсер — сначала окончание строки, потом всё остальное.
- Тайм-метки печатают миллисекунды; открытие монитора дёргает ресет, поэтому метки почти равны возрасту скетча.
- Автопрокрутка, фильтр и очистка — три кнопки, которые экономят вечера при плотных потоках пар.
- Пары имя=значение — протокол, а не привычка: их читают монитор, фильтр и плоттер одинаково.
Частые вопросы по теме урока
- Скорость монитора не совпадает с Serial.begin. Что вы увидите?
- Несовпадение бодов ломает разметку битов: принимающая сторона читает мусор. Первое действие при кракозябрах — сверить скорость монитора с числом в Serial.begin. Кракозябры вместо строк
- Тайм-метки в IDE 2 печатают…
- Метки ставит среда на стороне компьютера, отсчёт — от открытия монитора. Поскольку открытие дёргает ресет платы, метки почти совпадают с возрастом скетча. Миллисекунды от открытия монитора
- Почему открытие монитора перезапускает скетч?
- Классическая плата ресетится при открытии порта по DTR. Поэтому setup() пробегает заново — и поэтому же счётчики в RAM обнуляются, а EEPROM не трогается. Открытие порта дёргает линию DTR и вызывает ресет платы
- readStringUntil молчит, парсер не видит конца строки. Что проверить первым?
- readStringUntil(10) ждёт символ с кодом 10. С окончанием No line ending его нет — строка копится, но не отдаётся. Ставим NL или Both NL & CR. Окончание строки: выбрано ли NL в списке
- Монитор — не логгер. Куда девать ночной журнал температуры?
- История монитора умирает при закрытии панели. Ночные журналы пишут на SD-карту рядом с платой или шлют наружу — но не в окно монитора. На SD-карту скетчем с записью по времени