Далее приводится скетч для платы-получателя:
// sketch_10_03_Adruino_Receiver
#include "SoftwareSerial.h"
const int ledPin = 13;
int reading = 0;
SoftwareSerial receiver(8, 9); // RX, TX
void setup()
{
pinMode(ledPin, OUTPUT);
receiver.begin(9600);
}
void loop()
{
if (receiver.available() > 1)
{
byte h = receiver.read();
byte l = receiver.read();
reading = (h << 8) + l;
}
flash(reading);
}
void flash(int rate)
{
// 0 — редко, 1023 — очень часто
int period = (50 + (1023 — rate) / 4);
digitalWrite(ledPin, HIGH);
delay(period);
digitalWrite(ledPin, LOW);
delay(period);
}
Принимающий скетч ждет, пока будет получено не менее 2 байт, и затем восстанавливает значение типа int, сдвигая старший байт на 8 бит влево и прибавляя к результату младший байт.
Для передачи данных с более сложной структурой можно использовать библиотеку EasyTransfer: www.billporter.info/2011/05/30/easytransfer-arduino-library/.
Несмотря на то что в этом примере контакт Tx одной платы Arduino связан проводом с контактом Rx другой, для взаимодействий точно так же можно использовать беспроводные соединения. Многие модули беспроводной связи действуют прозрачно, то есть как если бы связь осуществлялась по проводам.
Модуль GPS
В заключительном примере демонстрируется использование последовательного интерфейса ТТЛ для чтения географических координат (широты и долготы) из модуля глобальной навигационной системы (Global Positioning System, GPS), которые затем форматируются и выводятся в монитор последовательного порта (рис. 10.5).
Рис. 10.5. Чтение данных из модуля GPS в плату Arduino
Связь с модулем GPS возможна только в одну сторону, поэтому достаточно соединить вывод Tx модуля с выводом Rx на плате Arduino. В примере используется модуль GPS, выпускаемый компанией Sparkfun Venus (www.sparkfun.com/products/11058). Подобно большинству других модулей GPS, он имеет последовательный интерфейс ТТЛ и раз в секунду посылает сообщения на скорости 9600 бод.
Формат сообщений соответствует стандарту национальной ассоциации морской электроники (National Marine Electronics Association, NMEA). Сообщение — это текстовая строка, завершающаяся символом перевода строки, с полями, разделенными запятыми. Далее показано, как выглядит типичное сообщение:
$GPRMC,081019.548,A,5342.6316,N,00239.8728,W,000.0,079.7,110613,,,A*76
Поля в данном примере имеют следующие значения:
• $GPRMC — тип сообщения;
• 081019.548 — время (очень точное) в 24-часовом формате, 8:10:19.548;
• 5342.6316, N — широта, умноженная на 100, то есть 53,426316 градуса северной широты;
• 00239.8728,W — долгота, умноженная на 100, то есть 0,2398728 градуса западной долготы;
• 000.0 — скорость;
• 079.7 — курс 79,7 градуса;
• 110613 — дата, 11 июня 2013.
Остальные поля для данного примера не имеют значения.
ПРИМЕЧАНИЕ
Полный список сообщений NMEA GPS можно найти по адресу http://aprs.gids.nl/nmea/.
Далее приводится скетч для этого примера:
#include <SoftwareSerial.h>
SoftwareSerial gpsSerial(10, 11); // RX, TX (TX не используется)
const int sentenceSize = 80;
char sentence[sentenceSize];
void setup()
{
Serial.begin(9600);
gpsSerial.begin(9600);
}
void loop()
{
static int i = 0;
if (gpsSerial.available())
{
char ch = gpsSerial.read();
if (ch != '\n' && i < sentenceSize)
{
sentence[i] = ch;
i++;
}
else
{
sentence[i] = '\0';
i = 0;
//Serial.println(sentence);
displayGPS();
}
}
}
void displayGPS()
{
char field[20];
getField(field, 0);
if (strcmp(field, "$GPRMC") == 0)
{
Serial.print("Lat: ");
getField(field, 3); // число
Serial.print(field);
getField(field, 4); // широта N/S
Serial.print(field);
Serial.print(" Long: ");
getField(field, 5); // число
Serial.print(field);
getField(field, 6); // долгота E/W
Serial.println(field);
}
}
void getField(char* buffer, int index)
{
int sentencePos = 0;
int fieldPos = 0;
int commaCount = 0;
while (sentencePos < sentenceSize)
{
if (sentence[sentencePos] == ',')
{
commaCount ++;
sentencePos ++;
}
if (commaCount == index)
{
buffer[fieldPos] = sentence[sentencePos];
fieldPos ++;
}
sentencePos ++;
}
buffer[fieldPos] = '\0';
}
Сообщения, посылаемые модулем GPS, имеют разную длину, но не более 80 символов, поэтому в скетче используется буфер емкостью 80 символов, который заполняется данными, пока не заполнится или не будет получен признак конца строки.
После того как полное сообщение будет прочитано, в конец буфера вставляется нулевой символ, завершающий строки в языке C. Это необходимо, только если вы пожелаете «напечатать» сообщение в его исходном виде.
Остальная часть скетча реализует извлечение полей и форматирование выходной строки для записи в монитор последовательного порта. Функция getField извлекает текст из поля с указанным индексом.
Функция displayGPS игнорирует любые сообщения, тип которых отличается от "$GPRMC", и извлекает широту и долготу, а также односимвольные названия полушарий для отображения.
В заключение
В этой главе мы исследовали несколько способов программирования взаимодействий через последовательный интерфейс между платами Arduino, периферийными устройствами и компьютерами.
В следующей главе мы обратим внимание на одну интересную особенность Arduino Leonardo, которая позволяет имитировать поведение периферийных устройств USB, таких как клавиатура и мышь. А также рассмотрим некоторые аспекты программирования интерфейса USB.
11. Программирование интерфейса USB
В этой главе рассматриваются разные аспекты использования порта USB на плате Arduino. В том числе возможность эмуляции клавиатуры и мыши, поддерживаемой платой Arduino Leonardo, а также подключения клавиатуры или мыши к соответственно оборудованной плате Arduino.
Эмуляция клавиатуры и мыши
Три модели Arduino — Due, Leonardo и Micro (основанная на модели Leonardo) — позволяют использовать их порт USB для эмуляции клавиатуры или мыши. Существуют также Arduino-совместимые платы, такие как LeoStick от компании Freetronics (рис. 11.1), поддерживающие аналогичную возможность.
Эта возможность широко используется, например, с музыкальными контроллерами, что позволяет плате Arduino взаимодействовать с музыкальными синтезаторами и управляющими программами, такими как Ableton Live. Благодаря ей можно, к примеру, на основе Arduino создавать новые музыкальные инструменты, управляющие музыкальным программным обеспечением с помощью датчиков поворота, прерываемых лучей света или педальной клавиатуры. К несерьезным применениям этой возможности можно отнести устройства, которые создают впечатление, что мышь живет своей жизнью независимо от действий пользователя или клавиатура сама печатает случайные символы.
Рис. 11.1. Плата LeoStick
Модель Arduino Due имеет два порта USB. Эмуляция клавиатуры и мыши осуществляется через локальный порт USB, а программирование Arduino Due — через порт USB для программирования (рис. 11.2).
Рис. 11.2. Плата Arduino Due с двумя портами USB
Эмуляция клавиатуры
Функции эмуляции клавиатуры просты в использовании. Они входят в состав стандартной библиотеки языка, поэтому для доступа к ним не требуется подключать дополнительные библиотеки. Чтобы включить режим эмуляции клавиатуры, добавьте в функцию setup следующую команду:
Keyboard.begin();
Чтобы