Чтение последовательного порта в Arduino

Примеры чтения из serial-порта в arduino

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

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

В этой статье мы сначала узнаем, как получать пользовательский ввод из serial порта Arduino. Затем мы рассмотрим несколько примеров программ, чтобы увидеть, как создать меню, калькулятор веса и интерфейс входа с паролем.

Как получить пользовательский ввод с монитора порта

Чтобы получить ввод пользователя с монитора порта, разобьем код на три простых шага.

Шаг 1. Запрос на получение информации

Это может быть вопрос типа “сколько раз вы хотите, чтобы светодиод мигал?” или “выберите опцию из меню?”. Это просто текст, сообщающий пользователю, что ему нужно что-то ввести. Код для подсказки может быть простой функцией Serial.print(), которая выводит вопрос на последовательном мониторе.

Пользователи могут вводить типы данных int, float или string. Только вам нужно будет заранее знать, какой тип данных будет вводить пользователь.

Шаг 2. Ждем обратную связь от пользователя

Для этой цели будем использовать функцию Serial.available() в пустом цикле while. Функция Serial.available() возвращает количество байт, доступных для чтения с последовательного порта. Когда пользователь не вводит данные, функция Serial.available() возвращает нулевое значение. Но когда пользователь вводит данные и нажимает Enter, то функция вернет ненулевое значение. Это используется как условие пустого цикла while, чтобы заставить программу ждать, пока не поступит ввод от пользователя:

while (Serial.available() == 0) {

}

Здесь условие пустого цикла while: Serial.available()==0. Когда пользователь не вводит никаких данных, функция Serial.available() возвращает нулевое значение, что делает условие истинным. Скетч остается внутри цикла while до тех пор, пока пользователь не введет что-то и функция Serial.available() не вернет ненулевое значение.

Шаг 3. Чтение данных

Последним шагом является чтение информации, введенной пользователем, и выполнение действия на основе этого ввода.

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

  • Serial.parseInt()
  • Serial.parseFloat()
  • Serial.readString()

Тип данных вводимой пользователем информации определяет, какую функцию следует использовать.

  • Если пользователь будет вводить целое число, то используйте Serial.parseInt().
  • Если пользователь будет вводить число с плавающей точкой, тогда используйте Serial.parseFloat().
  • А вот если пользователь будет вводить строку, используйте Serial.readString().

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

Например, чтобы проанализировать целое число, вы можете объявить переменную int с именем intVariable и установить ее равной функции Serial.parseInt() следующим образом:

int intVariable = Serial.parseInt();

Чтобы получить число с плавающей точкой, вы можете объявить переменную float и установить ее равной функции Serial.parseFloat():

float floatVariable = Serial.parseFloat();

Чтобы прочитать строку из порта Arduino, вы можете объявить строковую переменную и установить ее равной функции Serial.readString():

String stringVariable = Serial.readString();

Давайте посмотрим, как работать с чтением из порта на нескольких примерах.

Как анализировать целочисленные типы данных

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

Меню предлагает пользователю выбрать одну из трех характеристик для измерения и вывода значения в serial порт arduino: температура, влажность или атмосферное давление:

int temp;
int Rh;
int pressure;

void setup() {
  Serial.begin(9600);

  Serial.println("1. Температура");
  Serial.println("2. Влажность");
  Serial.println("3. Атмосферное давление");
}

void loop() {
  Serial.println("Какой датчик вы хотели бы прочитать? ");

  while (Serial.available() == 0) {
  }

  int menu = Serial.parseInt();

  switch (menu) {
    case 1:
      // код для датчика температуры
      Serial.print("Температура: ");
      Serial.println(temp);
      break;

    case 2:
      // код для датчика влажности
      Serial.print("Влажность: ");
      Serial.println(Rh);
      break;

    case 3:
      // код для датчика давления
      Serial.print("Атмосферное давление: ");
      Serial.println(pressure);
      break;

    default:
      Serial.println("Пожалуйста, сделайте свой выбор 1, 2 или 3");
  }
}

Для простоты код взаимодействия с датчиками не включен в этот скетч. Но Вы можете ознакомиться со статьей «Подключение датчика BMP280 к Ардуино», чтобы разобраться как подключить его и считать температуру, влажность и атмосферное давление. После этого будет проще добавить код для датчика в этот скетч.

В верхней части скетча мы объявляем три переменные для хранения показаний с датчика (или датчиков).

  • Переменная с именем temp будет хранить показания температуры.
  • Переменная с именем Rh будет хранить показания влажности.
  • А переменная с именем pressure будет хранить показания давления.

В разделе setup() мы начинаем с инициализации последовательного монитора с помощью функции Serial.begin().

Затем у нас есть несколько вызовов функции Serial.print(). Они выводят опции меню на последовательном мониторе. Первый вариант — температура, второй вариант — влажность, а третий вариант — атмосферное давление.

В разделе loop() мы сначала предлагаем пользователю ввести пункт меню. У нас есть функция Serial.println(), которая будет выводить текст «Какой датчик вы хотите прочитать?» в монитор порта.

Теперь нам просто нужно дождаться, пока пользователь введет выбор. Мы делаем это с помощью пустого цикла while. Условие цикла while: Serial.available()==0. Функция Serial.available() возвращает количество байтов, отправленных с монитора последовательного порта. Функция возвращает ноль, когда нет последовательных данных, поэтому скетч остается в цикле while, пока пользователь что-нибудь не введет. Когда пользователь вводит выбор, Serial.available() возвращает ненулевое значение, поэтому скетч выходит из цикла while и продолжает работать с оставшейся частью скетча.

Далее нам нужно прочитать данные, которые ввел пользователь, и для этого нам нужно их проанализировать. Поскольку это меню, пользователь будет вводить целое число, чтобы сделать выбор. Поэтому нам нужно использовать Serial.parseInt(). Мы будем хранить полученные данные в переменной int с именем menu.

На этом этапе мы предложили пользователю ввести пункт меню. Мы ждали, пока он войдет в выбор. И мы получили этот выбор и сохранили его в переменной. Теперь все, что нам нужно сделать, это заставить что-то произойти с этим выбором.

Поскольку есть три разных пункта меню, мы могли бы использовать три разных условных оператора if, чтобы управлять тем, что происходит, когда пользователь вводит выбор. Но более эффективным способом будет использование оператора switch case. Итак, в скетче выше есть оператор switch с переменной menu в скобках.

Затем есть три разных оператора case — case 1, case 2 и case 3.

  • Если пользователь вводит 1, скетч выполнит код в первом операторе case и распечатает показания датчика температуры.
  • В случае если пользователь введет 2, скетч выполнит код во втором операторе case, который распечатает показания влажности с датчика.
  • Если пользователь введет 3, скетч выполнит код в третьем операторе case, который выведет показания атмосферного давления в монитор порта.

Если пользователь вводит число, отличное от одного, двух или трех, мы можем использовать оператор default для вывода сообщения об ошибке, предлагающего ему ввести допустимое число. В приведенном выше скетче, если выполняется оператор default, на последовательный порт выводится текст «Пожалуйста, сделайте свой выбор 1, 2 или 3».

Чтение из serial-порта arduino чисел с плавающей точкой

Теперь давайте рассмотрим пример того, как получить тип данных float от пользователя из последовательного порта. Этот скетч представляет собой калькулятор, который преобразует вес в килограммах в вес в фунтах:

void setup() {
  Serial.begin(9600);
  Serial.println("**** Калькулятор перевода килограммов в фунты ****");
}

void loop() {
  Serial.print("Введите вес в кг: ");

  while (Serial.available() == 0) {
  }

  float weightKg = Serial.parseFloat();
  Serial.println(weightKg);
  float weightLbs = weightKg * 2.2046;
  Serial.print("Вес в фунтах: ");
  Serial.println(weightLbs);
}

В разделе setup() мы сначала инициализируем Serial порт. Затем мы выводим текст: «Калькулятор перевода килограммов в фунты».

В разделе loop() мы запрашиваем у пользователя информацию, выводя «Введите вес в кг: ».

Затем у нас есть пустой цикл while с Serial.available()==0 в качестве условия, поэтому скетч будет ждать, пока пользователь не введет число.

Теперь, поскольку перевод килограммов в фунты может привести к дробному числу, мы объявляем переменную weightKg как число с плавающей точкой. Затем мы устанавливаем его равным функции Serial.parseFloat() и выводим переменную weightKg в монитор порта.

Теперь мы делаем пересчет из килограммов в фунты. В одном килограмме 2,2046 фунта, поэтому мы можем умножить переменную weightKg на 2,2046, чтобы получить фунты и сохранить это значение в новой переменной с плавающей точкой с именем weightLbs. Затем мы последовательно выводим текст «Вес в фунтах:», за которым следует переменная weightLbs.

Чтение строки из serial порта arduino

Теперь давайте посмотрим, как работать со строковыми входными данными. Этот скетч запросит у пользователя пароль. Если пароль правильный, он выведет «Верный пароль!». Если пароль неверен, он выведет «Неверный пароль!»:

String password = "QWERTY";

void setup() {
   Serial.begin(9600);
}

void loop() {
   Serial.println("Пожалуйста, введите пароль: ");

   while(Serial.available() == 0) {
   }

   String input = Serial.readString();

   if(input == password) {
      Serial.println("Верный пароль!");
   }

   else {
      Serial.println("Неверный пароль!");
   }
}

Первое, что мы делаем, это определяем пароль. Вверху скетча есть строковая переменная с именем password, которая устанавливается равной паролю, который будет использоваться. У нас это QWERTY.

В разделе setup() мы инициализируем последовательный монитор с помощью Serial.begin(9600);.

В разделе loop() мы сначала используем функцию Serial.println() для вывода текста: «Пожалуйста, введите свой пароль:». Затем есть пустой цикл while с Serial.available() == 0 в качестве условия. Это необходимо для того, чтобы скетч ждал, пока пользователь введет пароль.

Значение, хранящееся в переменной пароля, представляет собой строку. Поэтому нам нужно использовать Serial.readString() для чтения строки из последовательного буфера. Вывод функции readString() сохраняется в другой строковой переменной с именем input.

Теперь нам просто нужно сравнить пароль, хранящийся во входной переменной, с паролем, который был определен в скетче. Условие оператора if: input == password. Если условие истинно, скетч войдет в тело и выполнит функцию Serial.println(), которая выведет «Верный пароль!» на последовательном мониторе.

Внутри оператора if вы размещаете код, реагирующий на правильность пароля. Например, вместо того, чтобы выводить текст на последовательном мониторе, вы можете установить на цифровом контакте высокий уровень функцией digitalWrite(), чтобы включить привод для открытия двери.

Если пароль, введенный пользователем, не совпадает с паролем, определенным в скетче, будет выполнен оператор else. Внутри оператора else находится функция Serial.println(), которая выведет «Неверный пароль!» на последовательном мониторе.

Надеюсь, эта статья оказалась вам полезной! Оставляйте комментарии ниже, если у вас есть какие-либо вопросы.

Документация

Компоненты

  • Arduino NANO
  • Arduino UNO
  • Arduino MEGA
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии