Светильник, управляемый по USB
В этом эксперименте мы отправляем устройству команды, как ему светить.
Список деталей для эксперимента
1 плата Arduino Uno
1 беспаечная макетная плата
1 светодиод
1 резистор номиналом 220 Ом
2 провода «папа-папа»
Принципиальная схема

Схема на макетке

Скетч
// p190_serial_brightness.ino
#define LED_PIN 9
// для работы с текстом существуют объекты-строки (англ. string)
String message;
void setup()
{
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop()
{
// передаваемые с компьютера данные поставляются байт за
// байтом, в виде отдельных символов (англ. character). Нам
// нужно последовательно их обрабатывать пока (англ. while)
// в порту доступны (англ. available) новые данные
while (Serial.available()) {
// считываем (англ. read) пришедший символ в переменную
char incomingChar = Serial.read();
// не стоит путать целые числа и символы. Они соотносятся
// друг с другом по таблице, называемой кодировкой. Например
// '0' — это 48, '9' — 57, 'A' — 65, 'B' — 66 и т.п. Символы
// в программе записываются в одинарных кавычках
if (incomingChar >= '0' && incomingChar <= '9') {
// если пришёл символ-цифра, добавляем его к сообщению
message += incomingChar;
} else if (incomingChar == '\n') {
// если пришёл символ новой строки, т.е. enter, переводим
// накопленное сообщение в целое число (англ. to integer).
// Так последовательность символов '1', '2', '3' станет
// числом 123. Результат выводим на светодиод
analogWrite(LED_PIN, message.toInt());
// обнуляем накопленное сообщение, чтобы начать всё заново
message = "";
}
}
// посылайте сообщения-числа с компьютера через Serial Monitor
}
Пояснения к коду
В этой программе мы создаем объект класса
String
. Это встроенный класс, предназначенный для работы со строками, т.е. с текстом.Не путайте его с типом данных
string
, который является просто массивом символов.String
же позволяет использовать ряд методов для удобной работы со строками.Мы знакомимся с новым видом циклов: цикл с условием
while
. В отличие от цикла со счетчикомfor
, циклwhile(expression)
выполняется до тех пор, пока логическое выражениеexpression
истинно.Метод
available()
объектаSerial
возвращает количество байт, полученных через последовательный порт.В данном эксперименте цикл
while
работает до тех пор, покаavailable()
возвращает ненулевое значение, любое из которых приводится кtrue
.Переменные типа
char
могут хранить один символ.В этом примере символ мы получаем методом
Serial.read()
, который возвращает первый байт, пришедший на последовательный порт, или -1, если ничего не пришло.Обратите внимание, что в
if
мы сравниваем не пришедший символ с 0 и 9, но их коды. Если пришел какой-то символ, который не является цифрой, мы не будем его добавлять к нашей строкеmessage
.Объекты типа
String
позволяют производить конкатенацию, т.е. объединение строк. Это можно сделать так:message = message + incomingChar
, но можно записать в сокращенной форме:message += incomingChar
.В этой программе мы дополняем
if
конструкциейelse if
. Это еще один условный оператор, который проверяется только в случае ложности выражения, данного первому оператору. Несколькоelse if
могут следовать друг за другом, при этом каждое следующее условие будет проверяться только в случае невыполнения всех предыдущих. Если в конце разместитьelse
, он выполнится только если ни одно из условий не выполнено.Напомним, что последовательностью
\n
кодируется символ переноса строки. Если он был передан устройству, мы передаем полученные ранее символы как параметр дляanalogWrite()
, которая включает светодиод.Мы используем один из методов
String
,toInt()
, который заставляет считать строку не набором цифр, но числом. Он возвращает значение типаlong
, при этом, если строка начинается с символа, не являющегося цифрой, будет возвращен 0. Если после цифр, идущих в начале строки, будут символы не-цифры, на них конверсия остановится.Обратите внимание на выпадающее меню внизу монитора порта: чтобы наше устройство получало символ перевода строки, там должно быть выбрано «Новая строка (NL)»
Пустая строка обозначается так:
""
. Опустошив ее, мы готовы собирать новую последовательность символов.
Вопросы для проверки себя
Какие объекты позволяют легко манипулировать текстовыми данными?
Что возвращают методы
Serial.available()
иSerial.read()
?Чем отличаются конструкции
for
иwhile
?Каким образом можно организовать более сложное ветвление, чем
if … else
?Как можно объединить текстовые строки?
Как можно привести текстовую строку, содержащую цифры, к числовому типу?
Задания для самостоятельного решения
Проверьте, попадает ли переданное число в диапазон значений, которые нужно передавать в
analogWrite()
. Передайте на компьютер сообщение об ошибке, если нет.Переделайте программу так, чтобы устройство распознавало текстовые команды, например, «on» и «off», и соответственно включало и выключало светодиод.
Вам может пригодиться один из методов
String
:toLowerCase(yourString)
илиtoUpperCase(yourString)
, которые возвращают переданную строкуyourString
, приведенную к нижнему или верхнему регистру соответственно.