Термометр с термистором я вылизывал неделю: столбик чисел в мониторе выдавал 23.4, 23.7, 23.2, 23.5, и я, честно листая прокрутку, сравнивал соседние строки глазами, как будто в них можно что-то понять. Отличить шум датчика от настоящих скачков температуры по такому столбику — гадание на кофейной гуще. Потом я открыл Serial Plotter — и всё стало видно за пять секунд: линия дрожала на две десятых градуса, а редкие иголки вниз оказались моим же проводом, который я время от времени трогал рукой. График — не украшение, это способ видеть данные вместо их перечитывания.
В этом уроке наладим живой график: как открывается Serial Plotter в Arduino IDE 2, в каком формате кормить его числами, как нарисовать два ряда на одном экране — сырой raw и масштабированный pwm — и почему среди чисел нельзя писать прозу. Повторить всё это можно без единого провода: в симуляторе на сайте есть вкладка «Плоттер» рядом с «Монитором», с кнопками «пауза» и «сброс графика» — двигаете ползунок сенсора, и кривая едет вживую. Если монитор порта для вас ещё в новинку, сначала загляните в первый урок про Serial Monitor: плоттер живёт на тех же проводах и той же скорости.
Числа против картины: зачем вообще график
Монитор порта выдаёт историю списком, а график — формой, и разница видна на трёх классических задачах. Тренд: температура в теплице ползёт вверх на градус в час — в столбике чисел это не замечаешь, на графике это наклонная линия, которую видно с первого взгляда. Шум: датчик дрожит на пять единиц туда-сюда — в числах это «всё время разное», на графике это ровная толстая полоса, которую сразу можно усреднить и забыть. Выбросы: раз в минуту приходит ноль вместо 512 — в бегущем списке глаз такое пропускает, а на графике иголка вниз торчит как заноза. Шум мы уже обсуждали в уроке про термистор и Стейнхарта — там десятые градуса дрожали в каждой строке; на графике их характер виден без всякой прокрутки.
Дребезг — отдельная песня. В уроке про debounce я уверял, что кнопка дребезжит миллисекунды при нажатии, но увидеть это глазами было негде. На графике — можно: печатайте чтение кнопки числом, нулём или единицей, пощёлкайте без подтяжки — в момент нажатия линия подпрыгнет зубцами, и вы своими глазами увидите тот самый переходный хаос, который лечат программные паузы. После этого приёмы debounce перестают быть магией: они просто сглаживают зубцы, которые вы уже видели.
Формат данных у плоттера аскетичный: он читает те же строки, что и монитор, и строит кривые по числам в них. Одна строка — один набор точек; сколько чисел в строке — столько кривых двинутся на шаг. Перевод строки обязателен: Serial.println() закрывает кадр, а Serial.print() собирает его по кускам — эту склейку мы тренировали, когда печатали значения с подписями. Стили два: «метка=значение», как raw=512 pwm=130, — ряды получат подписи; или голые числа через пробел и запятую — 512, 130, тогда кривые будут позиционными: первая, вторая, третья без имён.
Как открыть: Arduino IDE 2 и вкладка в симуляторе
В Arduino IDE 2 плоттер открывается из меню Инструменты → Плоттер по последовательному соединению (в английской версии Tools → Serial Plotter); рядом, в правом верхнем углу, есть и кнопка с иконкой графика. Внизу окна выбирается скорость порта — и она обязана совпадать с числом в Serial.begin(). Поставили 9600 в скетче и 115200 в окне — получите не график, а кашу из бессмысленных точек: байты режутся на чужих границах, и число 512 превращается в невиданную 5. Та же ловушка была и с монитором порта, только здесь она заметнее: кривая либо есть, либо это мусор, середины не дано.
В симуляторе на сайте всё то же самое, только без железа: вкладка «Плоттер» переключается рядом с «Монитором», и Serial остаётся тем же. Кнопка «пауза» замораживает картинку, чтобы рассмотреть участок; «сброс графика» очищает ряды и начинает запись заново. Подписи рядов берутся из строк «метка=значение», цвета подбираются сами; в каждом ряду хранится около 240 последних точек — при шаге 200 мс это почти минута истории, дальше старое выталкивается новыми точками. Периферия заводится ползунками: двигаете сенсор A0 — кривая ползёт следом. Это самый быстрый способ выучить формат: три секунды на ползунок — и понятно, что рисует подписи, а что ломает строку.
Чего у плоттера нет: памяти. Закрыли окно — история ушла; для длинных записей пишут в таблицу или на SD-карту, это другой инструмент с другими задачами. Масштаб по вертикали — автоматический: ось подстраивается под минимум и максимум ряда, и один резкий выброс сожмёт остальную кривую в нижнюю треть экрана. Два ряда сильно разных амплитуд — 0–1023 и 0–255 — рисуются честно, но маленький прижмётся к полу; иногда полезнее выводить оба в одном масштабе или жертвовать одним из двух.
Три скетча: минимальный, с метками и синус для проверки
Три скетча ниже закрывают форматы, которые встречаются в живых проектах. Первый — минимальный: одно число в строке, println(raw), никаких подписей. Плоттер нарисует один безымянный ряд — этого хватает, чтобы оценить шум или дребезг, но как только кривых станет две, без имён не разберёшься, какая из них чья.
Второй скетч — рабочий формат с метками: raw=512 pwm=130 в одной строке. Оба значения собираются Serial.print'ом по кускам и закрываются одним println — плоттер увидит два подписанных ряда от одного датчика: сырой raw из 0–1023 и масштабированный pwm из 0–255, знакомые по уроку про map и диммер. Именно такую пару стоит держать на графике, когда настраиваешь пороги: сразу видно, где сырое значение, а где то, что реально уходит в analogWrite.
Третий скетч рисует синус от millis(): если датчика под рукой нет, он нарисует идеальную плавную волну и покажет, как ведёт себя график на чистых данных. Он же — быстрая проверка канала: волна пришла, значит порт и скорость в порядке, и если дальше тишина, виноват формат строки, а не связь.
void setup() { Serial.begin(9600);} void loop() { int raw = analogRead(A0); Serial.println(raw); // перевод строки завершает кадр delay(200); // шаг по времени: 5 точек в секунду}void setup() { Serial.begin(9600);} void loop() { int raw = analogRead(A0); // ручка: 0–1023 int pwm = map(raw, 0, 1023, 0, 255); // масштаб: 0–255 analogWrite(9, pwm); // лампа едет за ручкой Serial.print("raw="); Serial.print(raw); Serial.print(" pwm="); Serial.println(pwm); // одна строка — оба ряда сразу delay(200);}void setup() { Serial.begin(9600);} void loop() { float t = millis() / 1000.0; // секунды с запуска float s = sin(t) * 100.0; // волна от -100 до 100 Serial.print("s="); Serial.println(s, 1); // один знак после запятой delay(50); // шаг 50 мс — линия гладкая}| Строка из Serial | Что нарисует плоттер | Когда использовать |
|---|---|---|
| 512 | один безымянный ряд | самый быстрый монитор датчика |
| raw=512 pwm=130 | два ряда с подписями raw и pwm | сравнить сырые и масштабированные данные |
| 23.4, 48 | два позиционных ряда без имён | CSV-стиль: температура и влажность |
| T=23.4 H=48 | два ряда с подписями T и H | метеостанция: подписи как в легенде графика |
| Pribor gotov | ничего: чисел нет, строка пропущена | текст печатайте отдельно от данных |
- Сравните два стиля формата: замените пары «метка=значение» на печать двух чисел через запятую — получите позиционные ряды без подписей; верните подписи и решите, какой вариант читается быстрее.
- Поймайте выброс: быстро дёрните ползунок туда-сюда, а на реальной макетке коснитесь провода A0 рукой — иголка на графике видна мгновенно; попробуйте найти её же в мониторе прокруткой и почувствуйте разницу.
- Добавьте третий ряд — усреднение: прочитайте analogRead трижды, сложите и напечатайте среднее рядом с raw; линия шума и спокойная средняя на одном экране спорят убедительнее любых слов.
- Откройте на графике дребезг: печатайте digitalRead(2) числом и пощёлкайте кнопку — зубцы в момент нажатия наглядно объяснят, зачем существует debounce из урока про кнопку.
- Поиграйте темпом: поставьте delay(50) и сравните с delay(500) — редкий шаг рвёт волну на точки, частый съедает её в сжатую полосу; подберите комфортный шаг под свой датчик.
- Serial Plotter строит кривые из чисел в Serial: одна строка — один набор точек, println() закрывает кадр, print() собирает его по кускам.
- Пары «метка=значение» дают подписанные ряды (raw=512 pwm=130), голые числа через пробел и запятую — позиционные; проза среди чисел ломает строку.
- В Arduino IDE 2: Инструменты → Плоттер по последовательному соединению; скорость внизу окна обязана совпадать с Serial.begin().
- В симуляторе на сайте — вкладка «Плоттер» рядом с «Монитором»: кнопки «пауза» и «сброс графика», ползунок сенсора двигает кривые без всякого железа.
- График — диагностический инструмент: тренд, шум, выбросы и дребезг видны за секунду; историю он не хранит — для длинных записей нужен логгер.
- 1. Сколько кривых нарисует плоттер для строки «raw=512 pwm=130»?
- 2. Что завершает кадр данных для плоттера?
- 3. Строка «Pribor gotov» пришла в плоттер. Что он нарисует?
- 4. Где живёт Serial Plotter в Arduino IDE 2?
График закрыл последнюю слепую зону отладки без железа: теперь вы видите не только то, что печатается, но и то, как это меняется. Дальше по разделу — таблица данных: несколько переменных в одной строке и аккуратный CSV, который читают и плоттер, и редактор таблиц. Навык же остаётся с вами навсегда: любой датчик курса — потенциометр, термистор, фоторезистор — после этого урока проверяется на глазах, а не прокруткой. Прогоните оба стиля формата на вкладке «Плоттер», поморгайте паузой и сбросом — и когда откроете настоящий Serial Plotter в Arduino IDE, он поведёт себя как старый знакомый.
Частые вопросы по теме урока
- Сколько кривых нарисует плоттер для строки «raw=512 pwm=130»?
- Пары «метка=значение» дают именованные ряды: raw и pwm поедут отдельными кривыми. Текст без меток плоттер пропустил бы, но здесь текст — это и есть подписи. Две, с подписями raw и pwm
- Что завершает кадр данных для плоттера?
- Плоттер собирает числа по строкам: пока нет перевода строки, кадр не закрыт и точки не рисуются. print() копит, println() закрывает. Перевод строки — финальный Serial.println()
- Строка «Pribor gotov» пришла в плоттер. Что он нарисует?
- Без чисел рисовать нечего — строка игнорируется. Проблемы начинаются, когда прозу перемешивают с числами: тогда ряды путаются между строками. Ничего: в строке нет чисел, она пропускается
- Где живёт Serial Plotter в Arduino IDE 2?
- Плоттер встроен в IDE 2 и открывается из меню Инструменты или кнопкой с иконкой графика в правом верхнем углу. Скорость порта выбирается там же, внизу окна. Инструменты → Плоттер по последовательному соединению, рядом с монитором