Вывод в монитор порта через Serial print, println, write

Serial.print() и Serial.println() – это основные функции Arduino для передачи информации от платы ардуино к компьютеру через последовательный порт. На самых популярных платах Arduino Uno, Mega, Nano нет встроенного дисплея, поэтому взаимодействие с помощью монитора порта Arduino IDE является самым простым и доступным способом получения информации во время работы скетча. В этой статье мы научимся использовать методы класса Serial для отладки программ и взаимодействия с другими устройствами через UART и последовательный порт.

Функция print() библиотеки Serial

Функция print является одной из самых часто встречающихся в скетчах ардуино. Она принимает на вход текст или цифры и затем передает их через открытый последовательный порт в формате ASCII. Примеры:

  • Serial.print(«Hello, ArduinoMaster») – на экране монитор порта мы увидим надпись Hello, ArduinoMaster
  • Serial.print(12) – число будет автоматически преобразовано и выведено как текст: 12
  • Serial.print(2.9) – это число тоже будет преобразовано в текст: 12.9
  • Serial.print(65) – в данном случае 65 передается как int и будет сконвертировано в строку «65», которая и будет отправлена в последовательный порт.

Т.к. функция является членом класса Serial, мы должны использовать название класса и символ точки «.» в ее синтаксисе . Класс Serial объявляется в библиотеке Serial, но нам не нужно подключать эту библиотеку отдельно, она является внутренней библиотекой ардуино и подключается автоматически. Функция не возвращает значение, поэтому ее нельзя использовать для форматирования и последующего использования в скетче. Для этих целей больше подойдут методы класса String.

Перед использованием функции необходимо предварительно открыть работу с последовательным портом, используя функцию begin(). Подробную информацию по функции Serial.begin вы можете найти в отдельной статье на нашем сайте.

Естественно, мы можем передавать в качестве параметров для функции print() не константы, а переменные определенных типов. Например, так:

String stringForPrinting  = «Hello from Arduino»;
Serial.print (stringForPrinting);

Текст, передаваемый с помощью print() обязательно завершается символом конца строки “\0”, что является стандартом для  C++ и Ардуино.

Функция println и отличия от print

Если вы попробовали использовать функцию print(), то уже обратили внимание, что вся информация в мониторе порта выводится в одной строке. Если же мы хотим вывести текст в новых строках, то должны использовать близкого родственника функции — println() .

Метод println () класса Serial выполняет ту же функцию, что и print() – он выводит в последовательный порт ASCII-текст.  Аргументы у методов тоже совпадают – мы передаем текст или число с возможным вторым аргументом, определяющим формат. Отличие же println заключается в принудительном добавлении в конце передающейся строки символа новой строки “\r” (ASCII код 13). Суффикс ln обозначает сокращенное слово line (строка). Используя println, мы можем быть уверены, что следующая (но не текущая) строка будет выведена с новой строки.

Например, следующие команды выведут три строки текста, каждое предложение в новой строке.

Serial.println(«Line number  1»);
Serial.println(«Line number  2»);
Serial.println(«Line number  3»);

При формировании строки мы также можем использовать следующие специальные символы: “\0”, “\r”, “\t” (символ табуляции). Табулирование позволяет печатать на экране что-то типа таблицы значений:

Serial.print("Column1\t\t");
Serial.println("Column2");
Serial.print("Cell 11\t\t");
Serial.println("Cel l2");
Serial.print("Cell 21\t\t");
Serial.println("Cel 22");

Форматирование и конвертация строк

Если мы передаем в последовательный порт число и хотим, чтобы оно интерпретировалось как число определенной системы счисления и выводилось в соответствующем формате, то можем использовать второй аргумент функции.

Варианты значений констант для форматирования:

  • DEC – обычное число в десятичной системе исчисления
  • BIN – преобразует в двоичный код и выведет строку, содержащую только символы 0 и 1
  • OCT – преобразует в восьмеричную систему исчисления
  • HEX – преобразует в шестнадцатеричную систему
  • Цифра от 0 до 9 – используется, если первый аргумент – вещественное число с плавающей запятой. Форма указывает количество знаков после запятой, которые останутся при выводе. Само число при этом будет округлено.

Примеры:


Serial.println(65, DEC);  // выведет “65”

Serial.println(65, BIN);  // выведет “1000001”

Serial.println(65, OCT);  // выведет 101, т.к. 65 в  8-ной системе исчисления равно 101

Serial.println(65, HEX);  // выведет 41, т.к. 65 в 16-ной системе исчисления равно 41

Serial.println(9.876, 2); // выведет два символа после запятой, предварительно округлив - 9.88

Serial.println(9.876, 0); // выведет число 10

В старых версиях ардуино можно было использовать еще один параметр BYTE. Начиная с версии 1.0 эта константа не поддерживается и компилятор выдаст вам ошибку «Ключевое слово ‘BYTE’ больше не поддерживается». Для вывода ASCII символа по его коду нужно использовать метод write().

Функция write() библиотеки Serial

Если мы хотим передать в монитор порта не ASCII код числа, а само число, то у нас есть возможность это сделать с помощью функции write().

  • Serial.write(65);  —  В данном случае на экране мы увидим символ A, так как 65 – это символ A в ASCII. Используя функцию write, мы отправляем число 65 монитору порта в виде… числа 65, а не текста «65», как в случае функции print(). При выводе на экран уже сам монитор порта будет конвертировать его в соответствие с таблице ASCII. В данном случае, таким символом является латинская буква A.
  • Serial.print(65);  — А теперь мы увидим на экране 65, т.к. в монитор придет уже строка, а не цифра. Каждая цифра исходного числа 65 будет предварительно сконвертирована в ASCII код и монитор порта увидит сроку «65», а не число. Этим и отличаются друг от друга функции print и write.

Проблемы с несколькими аргументами в Serial.print

Проблема при объединении текста и чисел и выводе в print в одной строке

Часто для отладки программы требуется вывести несколько значений, снабдив их каким-то комментарием. Например, такой текст:  «Sensor’s value is:  15». Если вы просто используете такой код:

Serial.print(«Sensor’s value is:  15»);

,то все отобразится правильно. Но если вы попытаетесь вместо подстроки «15» вставить реальное показание датчика, объединив строку и числовое значение, то увидите, что строка выводится некорректно.

Serial.print(«Sensor’s value is:  » + analogRead (A0));

Этот код даст непредсказуемый результат, в мониторе порта вы не увидите или пустоту или случайный набор символов. Причина ошибки в механизме конвертации типов данных. При объединении строк  «на лету», как в нашем примере, ардуино не знает, как интерпретировать типы данных для аргументов при операторе суммирования. В процессе такой непредсказуемой конвертации и результат может быть непредсказуемым.

Для решения этой проблемы вы можете использовать два способа:

Первый вариант. Объявить предварительно переменную типа String, инициализировать ее константой-строкой и использовать в аргументе print. Такой вот пример будет работать:

String str = «Sensor’s value is:  «;

Serial.println(str + analogRead(A0));

Второй, более предпочтительный и удобный вариант: использование функции print несколько раз:

Serial.print(«Sensor’s value is:  «);

Serial.println(analogRead(A0));

Более подробно прочитать об особенностях  работы со строками при выводе информации в монитор порта можно на официальной странице Ардуино.

Проблема объединения нескольких строк в аргументе функции print

Попробуйте загрузить скетч с таким фрагментом:

Serial.print(«Sensor’s value is:  » + analogRead (A0) + «15 cm»);

В данном случае ошибка возникнет уже на стадии компиляции программы: оператор «+» не может использовать больше, чем  два аргумента. Вам придется разбить одно действие на несколько составляющих, создав предварительно готовые «заготовки» строк.

Пример скетча для print и println

В завершении давайте рассмотрим реальный скетч, в котором мы используем монитор порта Arduino IDE для вывода отладочной информации с платы контроллера.

 

void setup() {

  // Объявляем работу с последоватлеьным портом в самом начале
  Serial.begin(9600);
  // Теперь мы можем писать сообщения
  Serial.println ("Hello, Arduino Master");
}

void loop() {

  // Выводим таблицу с информацией о текущих значениях портов
  Serial.print("Port #\t\t");
  Serial.println("Value");
  Serial.print("A0\t\t");
  Serial.println(analogRead(A0));
  Serial.print("A1\t\t");
  Serial.println(analogRead(A1));
  Serial.println("--------");
  delay(1000);
}
ПОДЕЛИТЬСЯ

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here