Arduino:Примеры/Bridge
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Библиотека Bridge[1]
Этот пример для Arduino Yun, и он демонстрирует использование библиотеки Bridge для доступа к цифровым и аналоговым контактам Arduino при помощи REST-запросов. Другими словами, он показывает, как при помощи REST-запросов, отправляемых через браузер, создать свой собственный API.
Перед запуском этого скетча убедитесь, что ваш компьютер находится в той же сети, что и Yun.
Закончив с программированием платы, вы сможете делать следующие вещи – запрашивать значение контакта, задавать значение контакта, а также задавать статус контакта (входной/выходной).
Итак, если защита паролем для REST отключена, вы можете отсылать Arduino следующие команды, выполненные в виде URL:
- http://myArduinoYun.local/arduino/digital/13 : calls digitalRead(13);
- http://myArduinoYun.local/arduino/digital/13/1 : calls digitalWrite(13,1);
- http://myArduinoYun.local/arduino/analog/9/123 : analogWrite(9,123);
- http://myArduinoYun.local/arduino/analog/2 : analogRead(2);
- http://myArduinoYun.local/arduino/mode/13/input : pinMode(13, INPUT);
- http://myArduinoYun.local/arduino/mode/13/output : pinMode(13, OUTPUT);
Впрочем, если хотите, вместо браузера можно использовать CURL-команды в командной строке.
Необходимое оборудование
- Плата Arduino Yun;
- Компьютер и Yun должны быть расположены в одной сети (проводной или беспроводной);
Необходимое ПО
- Веб-браузер;
Цепь
Для этого примера цепь не требуется.
Код
Этот скетч показывает, как делать REST-запросы к плате Yun, чтобы считывать контактов или задавать контактам те или иные значения. Вам потребуются библиотеки Bridge, YunServer и YunClient:
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
Инстацируем сервер YunServer, который позволит Yun «прослушивать» подключающихся клиентов.
YunServer server;
В секции setup() инициализируем последовательную передачу данных (в отладочных целях), а затем включаем встроенный светодиод, подключенный к 13-ому цифровому контакту, тем самым оповещая об активации библиотеки Bridge. Bridge.begin() – это блокирующая функция, а на ее выполнение уйдет примерно 2 секунды. Когда активация Bridge Полужирное начертаниезавершится, светодиод погаснет.
void setup() {
Serial.begin(9600);
pinMode(13,OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
Во второй части секции setup() мы делаем так, чтобы наш инстацированный YunServer «слушал» входящие соединения, но идущие только от локального хоста, т.е. от компьютера. При этом все подключения, идущие к Linux, будут передаваться процессору 32U4 – для последующего анализа и управления контактами. Все это проходит через порт 5555. Затем начинаем работать с сервером при помощи server.begin().
server.listenOnLocalhost();
server.begin();
}
В блоке loop() создаем экземпляр YunClient для управления соединением. Если клиент подключается, обрабатываем запросы в пользовательской функции (ее описание – ниже), а по завершении закрываем соединение. В конце блока loop() ставим задержку – чтобы процессор не перетруждался.
void loop() {
YunClient client = server.accept();
if (client) {
process(client);
client.stop();
}
delay(50);
}
Создаем функцию под названием process – она будет принимать YunServer в качестве аргумента. Считываем команду, создавая строку, которая будет хранить в себе входящую информацию. Анализируем REST-команды, определяя их функциональность (т.е. то, на что направлены эти команды – на работу с цифровым контактом, на работу с аналоговым контактом или на то, чтобы задать контакту тот или иной режим работы), а затем передаем информацию соответствующей функции.
void process(YunClient client) {
String command = client.readStringUntil('/');
if (command == "digital") {
digitalCommand(client);
}
if (command == "analog") {
analogCommand(client);
}
if (command == "mode") {
modeCommand(client);
}
}
Создаем функцию для работы с цифровыми контактами. Принимаем YunClient в качестве аргумента. Создаем две локальные переменные, в которых будет храниться информация из команды, т.е. данные о контакте и значении.
void digitalCommand(YunClient client) {
int pin, value;
Анализируем запрос клиента на предмет информации о контакте при помощи функции client.pareInt().
Если после числа, обозначающего контакт, стоит символ «/», это значит, что у этого URL дальше имеется либо «0», либо «1». То есть при помощи этих значений контакту передается либо значение HIGH, либо значение LOW. Если символа «/» нет, то просто считываем значение с указанного контакта.
pin = client.parseInt();
if (client.read() == '/') {
value = client.parseInt();
digitalWrite(pin, value);
}
else {
value = digitalRead(pin);
}
Шлем клиенту текстовое сообщение о том, что значение такого-то цифрового контакта стало таким-то (например, «Pin D13 set to 1»,т.е. «значение 13-ого цифрового контакта стало 1»), попутно меняя в базе данных значение ключа на то, которое было указано в клиентском запросе.
«Упаковываем» это сообщение в конструкцию F(), благодаря чему оно будет выводиться из flash-памяти. Тем самым мы экономим место в SRAM, что особенно полезно, если вы работаете длинными строками вроде URL. Ключ делаем составным, он будет включать в себя тип контакта (т.е. «D») и его номер (т.е. «2», «5», «13» и т.д.). Например, ключ «D2» будет означать 2-ой цифровой контакт. Значением (value) будет любая величина, которая либо задается клиентом, либо считывается с контакта.
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to "));
client.println(value);
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
Теперь задаем функцию, которая будет аналогичным образом управляться с аналоговыми запросами, только в ключе вместо D поставим A.
void analogCommand(YunClient client) {
int pin, value;
pin = client.parseInt();
if (client.read() == '/') {
value = client.parseInt();
analogWrite(pin, value);
// Отсылаем клиенту обратное сообщение
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to analog "));
client.println(value);
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
else {
value = analogRead(pin);
client.print(F("Pin A"));
client.print(pin);
client.print(F(" reads analog "));
client.println(value);
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
Создаем еще одну функцию, которая будет заниматься запросами, которые будут задавать для контакта его тип – входной (INPUT) или выходной (OUTPUT). Принимаем YunClient как аргумент и создаем локальную переменную, которая будет хранить номер контакта. Далее считываем значение контакта – точно таким же образом, как в функциях для работы с цифровыми и аналоговыми контактами.
void modeCommand(YunClient client) {
int pin;
pin = client.parseInt();
Делаем проверку, чтобы убедиться, что URL правильный.
if (client.read() != '/') {
client.println(F("error"));
return;
}
Если URL правильный, сохраняем его в виде строки. Далее меняем режим работы контакта на входной или выходной (в зависимости от того, что сказано в запросе) и сообщаем об этом клиенту. Если строка этим значениям не соответствует, сообщаем клиенту об ошибке.
String mode = client.readStringUntil('\r');
if (mode == "input") {
pinMode(pin, INPUT);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as INPUT!"));
return;
}
if (mode == "output") {
pinMode(pin, OUTPUT);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as OUTPUT!"));
return;
}
client.print(F("error: invalid mode "));
client.print(mode);
}
Полная версия скетча – ниже:
// Несколько примеров того, какими могут быть команды для этого скетча:
//
// "digital/13" -> digitalRead(13)
// "digital/13/1" -> digitalWrite(13, HIGH)
// "analog/2/123" -> analogWrite(2, 123)
// "analog/2" -> analogRead(2)
// "mode/13/input" -> pinMode(13, INPUT)
// "mode/13/output" -> pinMode(13, OUTPUT)
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
// Включаем «прослушку» порта 5555 – веб-сервер на Yun будет отправлять туда для нас все HTTP-запросы.
YunServer server;
void setup() {
Serial.begin(9600);
// Активируем библиотеку Bridge:
pinMode(13,OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
// Начинаем «прослушивать» входящие соединения, но идущие только от локального хоста,
// т.е. подключения от внешней сети игнорируем:
server.listenOnLocalhost();
server.begin();
}
void loop() {
// «Забираем» клиентов, идущих от сервера:
YunClient client = server.accept();
// Появился ли новый клиент?
if (client) {
// Обрабатываем запрос:
process(client);
// Закрываем соединение и освобождаем ресурсы:
client.stop();
}
delay(50); // Задержка каждые 50 миллисекунд
}
void process(YunClient client) {
// Считываем команду:
String command = client.readStringUntil('/');
// Это «цифровая» (digital) команда?
if (command == "digital") {
digitalCommand(client);
}
// Это «аналоговая» (analog) команда?
if (command == "analog") {
analogCommand(client);
}
// Это команда для смены режима (mode)?
if (command == "mode") {
modeCommand(client);
}
}
void digitalCommand(YunClient client) {
int pin, value;
// Считываем номер контакта
pin = client.parseInt();
// Если следующим символом является «/», это значит,
// что полученный запрос идет вместе с некоторым значением
// и выглядит примерно так: «/digital/13/1»
if (client.read() == '/') {
value = client.parseInt();
digitalWrite(pin, value);
}
else {
value = digitalRead(pin);
}
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D")); // "Контакту D"
client.print(pin);
client.print(F(" set to ")); // " присвоено значение "
client.println(value);
// Обновляем ключ в базе данных на текущее значение контакта:
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(YunClient client) {
int pin, value;
// Считываем номер контакта:
pin = client.parseInt();
// Если следующим символом является «/», это значит,
// что полученный запрос идет вместе с некоторым значением
// и выглядит примерно так: "/analog/5/120»
if (client.read() == '/') {
// Считываем это значение и выполняем команду:
value = client.parseInt();
analogWrite(pin, value);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D")); // "Контакту D"
client.print(pin);
client.print(F(" set to analog ")); // " присвоено аналоговое значение "
client.println(value);
// Обновляем ключ в базе данных на текущее значение контакта:
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
else {
// Считываем номер аналогового контакта:
value = analogRead(pin);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin A")); // "С контакта A"
client.print(pin);
client.print(F(" reads analog ")); // " считано аналоговое значение "
client.println(value);
// Обновляем ключ в базе данных на текущее значение контакта:
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(YunClient client) {
int pin;
// Считываем номер контакта:
pin = client.parseInt();
// Если «/» не является следующим символом, то URL неправильный:
if (client.read() != '/') {
client.println(F("error")); // "ошибка"
return;
}
String mode = client.readStringUntil('\r');
if (mode == "input") {
pinMode(pin, INPUT);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D")); // "Контакт D"
client.print(pin);
client.print(F(" configured as INPUT!")); // " сделан входным!"
return;
}
if (mode == "output") {
pinMode(pin, OUTPUT);
// Отсылаем клиенту обратное сообщение:
client.print(F("Pin D")); // "Контакт D"
client.print(pin);
client.print(F(" configured as OUTPUT!")); // " сделан выходным!"
return;
}
client.print(F("error: invalid mode ")); // "Ошибка. Вы указали неверную команду для того, чтобы задать режим – "
client.print(mode);
}
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Пример
- Примеры
- Пример программирования Arduino
- Примеры программирования Arduino