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

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

Плата Leonardo может эмулировать USB-клавиатуру, отправляя коды нажатия клавиш и их комбинаций. Рассмотрим эти возможности. Напишем простую программу, которая записывает данные от нескольких аналоговых датчиков в файл, разделяя их символом двоеточия ( формат CSV), который затем можно открыть в Excel или Google SpreadSheeets для построения графика.

Вызовем любой текстовый редактор, создадим пустой документ и сохраним его в файле с расширением csv. Для этого в диалоговом окне Сохранить можно выбрать тип файла Все файлы и вручную ввести имя файла с расширением, например data.csv.

Затем соберем простую схему, как показано на рис. 6.16. Устройство будет следить за показаниями температуры и освещенности, поступающими от аналоговых датчиков, с которыми мы уже встречались в главе 3. Кроме датчиков, в схеме есть кнопка для включения и выключения записи и светодиод, который будет показывать, идет ли в настоящее время запись данных.

Кнопка для включения/выключения записи снабжена функцией устранения дребезга ( см. главу 2). В процессе записи плата Arduino опрашивает датчики и раз в се-

- 144 -

Рис. 6.16. Схема подключения датчиков температуры и освещенности

кунду отправляет в компьютер данные, разделенные запятой. При этом загорается светодиодный индикатор. Поскольку Arduino постоянно опрашивает состояние кнопки, то задержку 1000 мс перед каждой отправкой данных формирует не функция delay(), а функция millis(), которая возвращает количество миллисекунд с последнего сброса платы Arduino. Вы можете посылать данные каждый раз, когда функция millis() выдает значение, кратное 1000 мс, фактически создавая задержку между посылками, равную 1 с. Это реализует оператор остатка деления по модулю (%). Если, например, вы выполните операцию 1000%1000, то результат будет равен нулю, т. к. 1000/1000 = 1 с нулевым остатком. 1500%1000 вернет 500, потому что 1500/1000= 1 с остатком 500. Выполняя деление по модулю millis() на 1000, по

- 145 -

лучим нулевой результат каждый раз, когда millis() выдает значение, кратное 1000, т. е. каждую секунду.

Изучите код листинга 6.9 и загрузите его на плату Arduino Leonardo. Убедитесь, что вы выбрали опцию Arduino Leonardo из меню Инструменты -> Board в Arduino IDE.

Листинг 6.9. Запись данных освещенности и температуры - csv_logger.ino

// Запись данных температуры и освещенности


const int TEMP=0;// Датчик температуры к аналоговому входу 0

const int LIGHT=1;// Датчик освещенности к аналоговому входу 1

const int LED=3;// Светодиод к выводу 13

const int BUTTON=2; // Кнопка к выводу 2

boolean lastButton = LOW;//Последнее состояние кнопки

boolean currentButton = LOW;//Текущее состояние кнопки

boolean running = false;//По умолчанию запись выключена

int counter = 1;//Индекс записываемых данных


void setup()

{

pinMode (LED, OUTPUT);// Контакт светодиода как выход OUTPUT

Keyboard.begin();// Запуск эмуляции клавиатуры

}


void loop()

{


currentButton = debounce(lastButton);// Чтение состояния


if (lastButton == LOW && currentButton==HIGH) // Если нажатие...

running = !running;// Переключить статус записи

lastButton = currentButton;// Установить статус кнопки


if ( running)// Запись включена

{

digitalWrite(LED, HIGH);// Включить светодиод

if (millis() % 1000 == 0)// Прошло 1000 мс

{

int temperature = analogRead(TEMP); // Чтение данных

// с датчика температуры

int brightness = analogRead(LIGHT); // Чтение данных

// с датчика освещенности

Keyboard.print(counter);// Вывод индекса данных

Keyboard.print(",");// Вывод разделителя

Keyboard.print(temperature);// Вывод температуры

Keyboard.print(",");// Вывод разделителя

Keyboard.println(brightness);// Вывод освещенности

// и символа новой строки

counter++;// Инкремент индекса

}

- 146 -


else

{

digitalWrite(LED, LOW);// Запись выключена, погасить светодиод


}

}

}

/*

* Функция устранения дребезга кнопки

* Получает предыдущий и возвращает текущий статус.

*/

boolean debounce(boolean last)

{

boolean current = digitalRead(BUTTON); // Чтение состояния кнопки

if (last != current)// Состояние изменилось...

{

delay(5);// Ждем 5 мс

current = digitalRead(BUTTON);// Чтение состояния кнопки

}

return current;// Возврат текущего состояния кнопки

}


Подробнее рассмотрим некоторые новые функциональные возможности, реализованные в этой программе. Как и ранее при инициализации последовательного порта, клавиатура инициализируется оператором Keyboard.begin() в функции setup().

В цикле loop() Arduino проверяет состояние кнопки и запускает программу устранения дребезга. При нажатии на кнопку значение переменной статуса записи инвертируется. Это достигается применением оператора ! к переменной running.

Когда программа находится в режиме записи, отправка данных выполняется раз в 1000 мс, благодаря описанному ранее приему. Функции эмулированной клавиатуры и последовательного порта очень похожи. Команда Keyboard.print() отправляет строку в компьютер. После получения данных аналоговых датчиков программа передает данные в компьютер в виде нажатия клавиш. Благодаря команде Keyboard.println() Arduino эмулирует нажатие клавиши (или )

после отправки строки. Индекс данных и оба аналоговых значения при выводе разделяются запятой.