В первый месяц с Arduino я едва не сдался из-за одного экрана. Собрал схему по картинке из интернета, загрузил скетч, открыл Serial Monitor — и увидел кашу: вопросики, стрелочки и непечатаемые символы вместо нормальных слов. Плата вроде бы работала: светодиод на борту мигал, кнопка Reset отзывалась, — но разговаривать она отказывалась. Я уже грешил на брак и готовил претензию продавцу, когда в одном форумном ответе мелькнула фраза «проверьте скорость порта». Оказалось, скетч шёл на 9600 бод, а монитор порта у меня стоял на 115200. Плата честно передавала данные — мы с ней просто договаривались на разных языках. Две минуты возни с выпадающим списком, и вместо кракозябр пошёл чистый текст. С тех пор первое, что я проверяю в чужом проекте, — не схему и не код, а именно совпадение скоростей.
В этом уроке мы открываем Serial Monitor — главное окно общения с Arduino и, без преувеличения, самый полезный инструмент всего курса. Вы узнаете, что скрывается за словом Serial и как устроен интерфейс UART ардуино, разберёте функцию Serial.begin() и поймёте, что такое скорость порта и почему обе стороны должны договориться о ней точно. Научитесь печатать через Serial.print() и Serial.println() — сначала слова, потом числа, потом целые читаемые строки вида «A0 = 512». А главное — перестанете бояться кракозябр: вы будете точно знать, откуда они берутся, и чинить их за десять секунд. Всё, что дальше по самоучителю — датчики, дисплеи, хранение данных, — опирается на этот навык, потому что без вывода в порт вы слепы.
Что такое UART: почтальон между платой и компьютером
За словом Serial прячется конкретный железный механизм — UART, универсальный асинхронный приёмопередатчик. Идея проста: два провода, и по каждому байты идут друг за другом, бит за битом. На Arduino Uno за передачу отвечает пин 1 (TX), за приём — пин 0 (RX). Когда вы пишете Serial.println("Privet"), микроконтроллер буквально дёргает пином TX, выставляя на нём нули и единицы в заданном темпе. Но к компьютеру плата подключена кабелем USB, а USB говорит на своём языке. Поэтому на борту Uno стоит чип-преобразователь, который переводит поток UART в USB и обратно — для вас вся эта кухня невидима: печатаешь в коде — видишь текст в мониторе порта. Запомните главное: это честный проводной канал со строгими правилами, и его же используют Bluetooth-модули HC-05, GPS-приёмники и множество датчиков, так что навык окупится десятки раз.
Зачем вообще выгружать текст на компьютер, если у платы нет экрана? Serial Monitor — это окно в мозг микроконтроллера. Без него вы видите только внешнее поведение: мигает, щёлкает, крутится. С ним — числа, значения переменных и порядок событий. Канал двунаправленный: можно печатать с платы, можно отправлять на плату, и даже делать это одновременно, ведь RX и TX — независимые линии; приёму данных посвящён следующий урок. Пока же договоримся о базовой гигиене: любой вывод в порт требует, чтобы порт был открыт. Этим занимается Serial.begin(скорость) в setup() — без этого вызова молчат и print, и println, как телефон без набранного номера. Забытый Serial.begin() — вторая по частоте ошибка новичка сразу после кракозябр: код компилируется, плата работает, а окно остаётся пустым.
void setup() { Serial.begin(9600); // открываем порт на скорости 9600 бод Serial.println("Hello from Arduino!");} void loop() { // здесь пусто: сообщение уже напечатано один раз при старте}Serial.begin и скорость порта: договор на 9600 бод
Скорость порта измеряется в бодах — битах в секунду. Каждый байт упаковывается в рамку: стартовый бит, восемь битов данных, стоповый бит. Приёмник замеряет напряжение на линии с той частотой, о которой договорились заранее. Если передатчик шлёт на 9600 бод, а приёмник слушает на 115200, он заглядывает на линию в двенадцать раз чаще и собирает из битов бессмыслицу — вот вам и кракозябры. Никакой магии и поломок: чистый рассинхрон скоростей. Поэтому значение в Serial.begin(9600) и в выпадающем списке Serial Monitor должны совпадать до последнего бита. Классика — 9600: достаточно быстро для текста и надёжно даже на длинных проводах. Другие ходовые значения — 19200, 57600, 115200; последняя по умолчанию у ESP32 и современных загрузчиков. Скорость заливки скетча эта настройка не трогает: у загрузчика она своя, отдельная.
Держите в голове короткий алгоритм на случай мусора в мониторе. Шаг первый — посмотрите, что написано в Serial.begin вашего скетча. Шаг второй — сверьте выпадающий список скоростей внизу монитора порта. В девяти случаях из десяти на этом всё и закончится. Если текст шёл нормально, а потом оборвался в кашу после переподключения кабеля — плата просто перезагрузилась: при старте загрузчик Uno на долю секунды выдаёт мусор на своей скорости, это штатное поведение, лечится повторным открытием монитора. И не гонитесь за экстремальными скоростями вроде 230400 на дешёвых платах с самодельными USB-чипами: экономия миллисекунд не стоит вечера, проведённого с кракозябрами. Для учебных проектов честные 9600 — правильный выбор, и все примеры этого самоучителя работают именно на них.
long seconds = 0; void setup() { Serial.begin(9600);} void loop() { seconds = seconds + 1; Serial.print("Sekunda: "); Serial.println(seconds); delay(1000);}print и println: строки, которые приятно читать
У Serial два главных инструмента печати, и разница между ними ровно одна. Serial.print() выводит текст или число и ничего не добавляет: следующий вывод приклеится прямо к концу. Serial.println() делает то же самое плюс отправляет перевод строки, поэтому следующий текст начнётся с новой строки. Числа печатаются в привычном виде автоматически: Serial.print(42) даст 42, а дробное значение — с двумя знаками после запятой (у print есть и второй параметр — количество знаков, до него доберёмся в проектах). Главный приём читаемого вывода — метка и значение по очереди: сначала Serial.print("A0 = "), затем само число. Через десять минут непрерывного лога голое «512» ничего вам не скажет, а «A0 = 512» скажет всё. Отсутствие меток — причина номер один, по которой новички не могут прочитать собственный отладочный лог.
Собирать сложную строку на Arduino принято цепочкой вызовов: несколько print, а в конце один println. Функции printf в стандартной библиотеке Uno нет — в отличие от настольного C++, здесь так не выйдет, зато и форматные спецификаторы путать не придётся. Порядок простой: метка, значение, разделитель, следующая метка; разделителем служат два пробела или вертикальная черта — что легче глазу. Если строки слиплись в одну длинную кашу — где-то вы забыли println или отправили лишний print без перевода строки. Потренируйтесь на коде ниже: он каждую полсекунды печатает значение с аналогового входа A0 и время работы платы в секундах. Время мы берём из millis() — количества миллисекунд с включения, делённого на тысячу; ей посвящён отдельный урок про мигание без delay, а пока просто используйте её как встроенные часы.
void setup() { Serial.begin(9600);} void loop() { int raw = analogRead(A0); // сырые единицы: 0..1023 Serial.print("A0 = "); Serial.print(raw); Serial.print(" t = "); Serial.print(millis() / 1000); Serial.println(" s"); delay(500);}- Serial — это UART: пин 1 (TX) передаёт, пин 0 (RX) принимает, к компьютеру поток идёт через USB-преобразователь
- Serial.begin(9600) открывает порт; скорость в скетче и в мониторе порта должна совпадать точно
- Кракозябры — почти всегда рассинхрон скоростей, а не поломка платы
- print печатает без перевода строки, println — с переводом; числа превращаются в текст автоматически
- Пины 0 и 1 не занимайте под внешнюю схему — это линии UART
- 1. Что произойдёт, если в скетче стоит Serial.begin(9600), а в мониторе порта выбрано 115200?
- 2. Чем Serial.println() отличается от Serial.print()?
- 3. Какие пины Arduino Uno использует UART?
- 4. Сколько раз напечатается строка из setup() при включении платы?
Мы научились говорить: плата печатает, вы читаете, кракозябры вам больше не страшны. Но настоящий разговор — диалог, и в следующем уроке мы развернём поток в обратную сторону: заставим плату слушать. Вы отправите ей команды ON и OFF прямо из монитора порта — или со смартфона, если подключите Bluetooth-модуль, — соберёте распорядитель команд из отдельных символов и превратите светодиод в послушного исполнителя. Заодно разберём приёмный буфер: почему данные вычерпывают по одному байту, зачем перед каждым чтением проверять available() и что случится, если этого не делать. Привычку открывать монитор порта в каждом проекте оставьте себе навсегда — она ещё сотню раз спасёт вам вечер.
Частые вопросы по теме урока
- Что произойдёт, если в скетче стоит Serial.begin(9600), а в мониторе порта выбрано 115200?
- Передатчик и приёмник обязаны работать на одной скорости: приёмник заглядывает на линию не в те моменты и собирает из битов бессмысленные байты. Текст превратится в кракозябры — скорости не совпадают
- Чем Serial.println() отличается от Serial.print()?
- print выводит данные без перевода строки, println — с переводом: следующий вывод начнётся с новой строки. println дополнительно отправляет перевод строки
- Какие пины Arduino Uno использует UART?
- У Uno за UART закреплены пины 0 и 1; через USB-преобразователь этот же поток попадает в Serial Monitor на компьютере. 0 (RX) и 1 (TX)
- Сколько раз напечатается строка из setup() при включении платы?
- setup() выполняется однократно, поэтому и строка из него печатается один раз. Чтобы печатать повторно, вывод переносят в loop(). Один раз