Урок 19. Светильник, управляемый по USB


В этом уроке мы отправляем устройству команды, как ему светить.

Список деталей для эксперимента

Принципиальная схема

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

Скетч

  1.     #define LED_PIN 9
    
  2.     // для работы с текстом существуют объекты-строки (англ. string)
    
  3.     String message;
    
  4.  
  5.     void setup(
    )
    
  6.     {
    
  7.       pinMode(LED_PIN, OUTPUT)
    ;
    
  8.       Serial.begin
    (
    9600
    )
    ;
    
  9.     }
    
  10.  
  11.     void loop(
    )
    
  12.     {
    
  13.       // передаваемые с компьютера данные поставляются байт за
    
  14.       // байтом, в виде отдельных символов (англ. character). Нам
    
  15.       // нужно последовательно их обрабатывать пока (англ. while)
    
  16.       // в порту доступны (англ. available) новые данные
    
  17.       while (Serial.available
    (
    )
    ) {  
  18.         // считываем (англ. read) пришедший символ в переменную
    
  19.         char incomingChar = Serial.read
    (
    )
    ;
    
  20.         // не стоит путать целые числа и символы. Они соотносятся
    
  21.         // друг с другом по таблице, называемой кодировкой. Например
    
  22.         // '0' — это 48, '9' — 57, 'A' — 65, 'B' — 66 и т.п. Символы
    
  23.         // в программе записываются в одинарных кавычках
    
  24.         if (incomingChar >= '0' && incomingChar <= '9'
    ) {
    
  25.           // если пришёл символ-цифра, добавляем его к сообщению
    
  26.           message +
    = incomingChar;
    
  27.         } else if (incomingChar == '\n'
    ) {
    
  28.           // если пришёл символ новой строки, т.е. enter, переводим
    
  29.           // накопленное сообщение в целое число (англ. to integer).
    
  30.           // Так последовательность символов '1', '2', '3' станет
    
  31.           // числом 123. Результат выводим на светодиод
    
  32.           analogWrite(LED_PIN, message.toInt
    (
    )
    )
    ;
    
  33.           // обнуляем накопленное сообщение, чтобы начать всё заново
    
  34.           message = ""
    ;
    
  35.         }
    
  36.       }
    
  37.       // посылайте сообщения-числа с компьютера через Serial Monitor
    
  38.     }
    

Пояснения к коду

  • В этой программе мы создаем объект класса 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, приведенную к нижнему или верхнему регистру соответственно.

 

 

  • Предыдущий урок -Урок 18. Тестер батареек
  • Читайте наш следующий урок - Урок 20. Перетягивание каната на следующей неделе
Теги: 
Источник: 
wiki.amperka.ru