Изучаем Arduino: инструметы и методы технического волшебства - [32]

Шрифт
Интервал

• serial. read() - читает и возвращает следующий символ, который находится в буфере.

Обратите внимание, что каждый вызов к функции Serial. read() возвратит из буфера только один байт, поэтому вы должны повторять эту функцию, пока serial. available() возвращает ненулевое значение. Каждый раз, когда Функция serial. read() получает байт, буфер очищается, и можно принимать следующий байт. Теперь можно загрузить программу из листинга 6.3 на плату Arduino.

Листинг 6.3. Эхо последовательного порта - 'echo.ino

// Эхо каждого символа

char data;

// Текущий входящий символ


void setup()

{

Serial.begin(9600); // Инициализация последовательного порта на скорости 9600

}

- 130 -

void loop()

{

// Вывод только при получении данных

if (Serial.available() > 0)

{

data = Serial.read(); // Чтение байта из буфера

Serial.print(data);// Вывод в последовательный порт

}

}

Запустите монитор последовательного порта и напечатайте что-нибудь в поле ввода текста. Как только вы нажмете кнопку Отправить, все, что вы набрали, вернется назад в компьютер и отобразится в окне монитора последовательного порта. Поскольку в меню выбрана опция Newline, для каждой команды добавляется символ перевода строки (\n), следовательно, каждый ответ отображается с новой строки.

Поэтому вместо функции serial.println() в листинге 6.3 указана функция Serial.print()

Различие между char и int

При отправке алфавитно-цифрового символа через монитор последовательного порта мы на самом деле не отправляем "5" или "А". Мы посылаем байт, который компьютер интерпретирует как символ. В случае последовательной связи для представления всех букв, цифр, символов и специальных команд используется кодировка ASCII. Основной набор символов ASCII (рис. 6.9) представляет собой 7-битовый набор, содержащий 128 символов и команд.

При получении значения, отправленного с компьютера, данные должны быть считаны, как char (см. листинг 6.3). Даже если вы ожидаете из последовательного терминала отправки числа, вам необходимо прочитать байт, как символ, а затем при необходимости конвертировать его. Если вы измените программу листинга 6.3, объявив переменную data как int, то, отправив значение 5, в последовательный монитор вернется значение 53 (десятичное представление символа "5"). Вы можете убедиться в этом, посмотрев на рис. 6.9.

Тем не менее, в Arduino часто необходимо отправлять числовые значения. Как это сделать? Существует несколько способов. Во-первых, можно просто сравнить сами символы. Если вы хотите зажечь светодиод при отправке из монитора цифры 1, то можно непосредственно сравнить значения символов:

if(Serial.read() == '1')

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

int val = Serial.read() - '0'

Такой способ не годится для чисел больше 9, потому что они содержат несколько цифр. В этом случае нас выручит функция parseInt(), входящая в Arduino IDE, ко

- 131 -

Рис. 6.9. Набор символов ASCII

торая извлекает из последовательного потока данных целые числа. Далее мы подробно рассмотрим описанные методы.

Отправка ОДИНОЧНЫХ символов для управления светодиодом

Начнем с написания программы, которая использует простое сравнение символов для управления состоянием светодиода. Вы будете отправлять символ "1 ", чтобы включить светодиод, и "0", чтобы выключить его. Соедините светодиод с контактом 9 платы Arduino, как показано на рис. 6.10.

Как мы уже говорили, при отправке одиночного символа необходимо выполнить простое символьное сравнение. Каждый раз, когда символ окажется в буфере, мы сравниваем его с «0» или «1» и выполняем нужные действия. Загрузите в Arduino код листинга 6.4 и поэкспериментируйте с отправкой нуля или единицы из последовательного терминала.

- 132 -


Рис. 6.10. Подсоединение светодиода к контакту 9 платы Arduino

Листинг 6.4. Управление светодиодом последовательной отправкой символов- single_char_control.ino

// Переключение состояния светодиода отправкой одиночного символа

const int LED=9;

char data;// Переменная для хранения получаемого символа


void setup()

{

Serial.begin(9600); // Инициализация последовательного порта

// на скорости 9600

pinMode(LED, OUTPUT);

}

- 133 -

void loop()

{

// Если в буфере есть символ

if (Serial.available() > 0)

{

data = Serial.read(); // Чтение байта из буфера

// Включение светодиода

if (data == '1')

{

digitalWrite(LED, HIGH);

Serial.println ( "LED ON");

}

// Выключение светодиода

else if (data == '0')

{

digitalWrite(LED, LOW);

Serial.println ( "LED OFF");

}

}

}

Обратите внимание, что вместо простого оператора else применен оператор else if. Это необходимо, потому что в опции терминала установлена отправка символа перевода строки при каждой передаче. Получив символ перевода строки, функция Serial.read() определит, что он не равен '0' или '1', в результате со светодиодом ничего не произойдет. Если бы мы использовали оператор else, то отправка и '0' и '1' приводила бы к откточению светодиода. При отправке '1' светодиод будет включен и немедленно выкточен снова, когда будет получена последовательность \n!