Элементы индикации
Элементы индикации предназначены для передачи информации с контроллера на смартфон.
Индикатор
Индикатор – аналог светодиода. Представьте, что вы подключили к выводам ШИМ контроллера 3-хцветный светодиод. Вы можете управлять яркостью свечения каждого цвета отдельно, выставляя на выводах ШИМ различное значение скважности. Индикатор работает точно так же, выставляя интенсивность яркости каждого цвета, можно добиться отображения 256 в степени 3 цветов (16 777 216 цветов, если быть точным).
Параметры элемента «индикатор»: имя переменной (по умолчанию led), отрисовка (круглая или прямоугольная формы), а так же три флажка для выбора доступных цветов – красный, зеленый и синий. Можно поставить флажки в любой комбинации. Внимание: флажки работают так, что можно снять все три флажка, в таком случае поля структуры для индикатора не будут созданы.
Обратите внимание на структуру. Для каждого цвета индикатора создаются отдельные поля структуры, которые оканчиваются на _r, _g и _b для красного, зеленого и синего цветов соответственно. Значение, которое может принимать поле структуры, лежит в диапазоне от 0 до 255, так же как и в ШИМ. То есть управление цветом индикатора аналогично управлению светодиода посредством ШИМ.
//Структура элемента RGB со значениями по умолчанию.
struct { // output variable
uint8_t led_1_r; // =0..255 яркость красного цвета индикатора uint8_t led_1_g; // =0..255 яркость зеленого цвета индикатора uint8_t led_1_b; // =0..255 яркость синего цвета индикатора // other variable
uint8_t connect_flag; // =1 if wire connected, else =0 } RemoteXY;
Лампа настроения (mood lamp) –лампа, которая плавно меняет цвет в случайном или в определенном порядке. За основу лампы настроения взят фонарик для фризлайта из предыдущей статьи, принципиальная схема остается той же. Изменениям будет подвергнут лишь исходный код. Конфигурация и подключение модуля связи на скриншотах.
Внешний вид мобильного интерфейса. Вверху экрана расположена надпись «Mood Lamp», остальное пространство на экране занимает индикатор прямоугольной формы. Цвет 3-хцветного светодиода, подключенного через ШИМ к контроллеру, будет совпадать с цветом индикатора на экране смартфона.
Обход цветов будет происходить в следующей последовательности. Примем за начало цикла красный цвет. Переход в желтый цвет будет происходить увеличением яркости зеленого цвета. Когда зеленый цвет достигнет максимальной интенсивности, красный цвет начнет снижать яркость, пока она не станет равна нулю. Затем начнется набор яркости синего цвета, уменьшение яркости зеленого и так далее, пока цикл не замкнется. В итоге должен получиться следующий порядок цветов.
Дальнейшие пояснения в комментариях к исходному коду.
//////////////////////////////////////////////
// RemoteXY include library //
//////////////////////////////////////////////
// определение режима соединения и подключение библиотеки RemoteXY #define REMOTEXY_MODE__HARDSERIAL
#include <RemoteXY.h>
// настройки соединения #define REMOTEXY_SERIAL Serial1
#define REMOTEXY_SERIAL_SPEED 9600
// конфигурация интерфейса #pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 0,3,27,0,6,0,1,65,15,0
,10,63,90,2,129,0,7,1,51,9
,9,77,111,111,100,32,76,97,109,112
,0 };
// структура определяет все переменные вашего интерфейса управления struct {
// output variable
uint8_t led_1_r; // =0..255 яркость красного цвета индикатора
uint8_t led_1_g; // =0..255 яркость зеленого цвета индикатора
uint8_t led_1_b; // =0..255 яркость синего цвета индикатора
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop)
/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
uint8_t i=1; //эта переменная будет определять, какой цвет должен изменяться
void setup() {
RemoteXY_Init (); }
void loop() { RemoteXY_Handler ();
/*все действия будут происходить в главном цикле, поскольку передача данных на смартфон осуществляется в обработчике RemoteXY_Handler()
который находится в функции loop()*/
if (i==1) { //при i==1 увеличивается яркость зеленого цвета
RemoteXY.led_1_g++; //это условие сработает 255 раз
if (RemoteXY.led_1_g==255) {i++;} //когда яркость зеленого цвета будем максимальной,
//увеличиваем i на 1 и это условие не будет срабатывать,
// пока i вновь не станет равно 1
}
if (i==2) { //и передаем эстафету следующему условию
RemoteXY.led_1_r—; //здесь уменьшаем яркость красного цвета
if (RemoteXY.led_1_r==0) {i=i+1;} //и снова передаем эстафету
}
if (i==3) {
RemoteXY.led_1_b++; //увеличиваем яркость синего
if (RemoteXY.led_1_b==255) {i=i+1;}
}
if (i==4) {
RemoteXY.led_1_g—; //уменьшаем яркость зеленого
if (RemoteXY.led_1_g==0) {i=i+1;}
}
if (i==5) {
RemoteXY.led_1_r++; //увеличиваем яркость красного
if (RemoteXY.led_1_r==255) {i=i+1;}
}
if (i==6) {
RemoteXY.led_1_b—; //уменьшаем яркость синего
if (RemoteXY.led_1_b==0) {i=i+1;}
} //цикл перебора цветов завершен
//выводим цвета на 3-хцветный светодиод через ШИМ
analogWrite(13, RemoteXY.led_1_r);
analogWrite(12, RemoteXY.led_1_g);
analogWrite(11, RemoteXY.led_1_b);
if (i==7) {i=1;} //поскольку цикл завершен, то сбрасываем i к первоначальному значению, то есть к 1
delay(10);
/*задержку такого рода ставить не рекомендуется, но без нее перебор цветов слишком быстрый.
К тому же такая короткая пауза не препятствует связи контроллера со смартфоном.*/
}
Уровень и шкала
Уровень и шкала служат для графического представления какой-либо переменной.
Всего доступно четыре вида элементов, но поскольку отличаются они лишь внешним видом, то рассматривать их я буду все вместе.
Всего доступно 4 элемента:
- Уровень линейный;
- Уровень дуговой;
- Шкала стрелочная;
- Шкала дуговая стрелочная.
Все эти элементы имеют параметры цвет, имя переменной (по умолчанию level), ориентацию (вертикально или горизонтально), позиция центра. И лишь линейный уровень имеет атрибут вариант отображения, который может иметь значения сплошной или сегментный.
Позиция центра, аналогична позиции центра элемента слайдер, указывает, где будет находиться нулевое положение шкалы. При позиции центра посредине поле структуры может принимать значения от -100 до 100. При позиции центра сверху или снизу для вертикально расположенных элементов и справа или слева для горизонтально расположенных значение поля структуры лежит в диапазоне от 0 до 100.
Для закрепления полученных знаний предлагаю простое практическое задание.
К аналоговому входу А0 подключить переменный резистор как делитель напряжения (см. скриншот). Создать интерфейс, состоящий из одного элемента – дуговой стрелочной шкалы, параметры шкалы по умолчанию. Подключение произвольно.
При вращении ручки переменного резистора стрелка шкалы на экране смартфона будет откланяться, насколько – зависит от характеристики переменного резистора.
На графике изображены:
- А — линейная;
- Б – логарифмическая;
- В — показательная (обратно-логарифмическая) характеристики.
//////////////////////////////////////////////
// RemoteXY include library //
//////////////////////////////////////////////
// определение режима соединения и подключение библиотеки RemoteXY #define REMOTEXY_MODE__HARDSERIAL
#include <RemoteXY.h>
// настройки соединения #define REMOTEXY_SERIAL Serial1
#define REMOTEXY_SERIAL_SPEED 9600
// конфигурация интерфейса #pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 0,1,10,0,6,5,1,66,132,11
,23,41,32,2 }; // структура определяет все переменные вашего интерфейса управления struct {
// output variable
int8_t level_1; // =0..100 положение уровня
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop)
/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
void setup() {
RemoteXY_Init (); }
void loop() { RemoteXY_Handler ();
RemoteXY.level_1=map(analogRead(A0),0,1023,0,100);
/*диапазон шкалы 0-100, поэтому приводим значение аналогового сигнала с входа А0 к необходимому диапазону при помощи функции map*/
}
Текстовая строка
Самое универсальное средство вывода информации, способное заменить текстовый дисплей. Параметры текстовой строки: цвет, имя переменной (по умолчанию text), количество символов строки, выравнивание (слева, по центру или справа), показывать фон (фон лишь темно-серый, если отключить фон, то рамки вокруг текста не остается, а отличии от поля ввода).
Просто присвоить какую либо строку полю структуры нельзя, необходимо использовать следующие функции:
- strcpy – копирование одной строки в другую. К примеру, strcpy (RemoteXY.text_1, str1); strcpy(RemoteXY.text_1, “Этот текст будет скопирован в поле структуры”);
- strcat – объединение 2-х строк, strcat(RemoteXY.text_1, “Этот текст будет добавлен в конец поля структуры ”);
- sprint – действует аналогично функции srtcpy. Пример: sprintf (RemoteXY.text_2, «My text»);
- itoa – для преобразование целого числа в строку. К примеру, itoa(254, RemoteXY.text_1, 10) – обратите внимание на последний аргумент, число 10 означает, что число будет выводиться в десятичной системе счисления.
- dtostrf – для преобразования числа типа double в строку. К примеру, dtostrf(val, 0, 2, RemoteXY.text_1) где 0 – минимальная полученная длина строки, 2 – количество знаков после запятой.
И это не полный список.
И как всегда практическое задание для закрепления знаний.
Цель задания – создать генератор случайных паролей и вывести сгенерированный пароль на экран смартфона. Параметры подключения и внешний вид интерфейса приведены на скриншотах. Схему подключения не привожу, потому что кроме модуля связи к контроллеру ничего не подключено.
Генерация пароля будет происходить следующим образом. За источник символов возьмем таблицу ASCII, в которой каждый символ имеет номер. Номера можно генерировать при помощи функции random, задав в ней диапазон необходимых значений. Ниже я привел урезанную таблицу ASCII, её будет достаточно.
Дальнейшие пояснения в комментариях к исходному коду.
//////////////////////////////////////////////
// RemoteXY include library //
//////////////////////////////////////////////
#define REMOTEXY_MODE__HARDSERIAL
#include <RemoteXY.h>
// настройки соединения #define REMOTEXY_SERIAL Serial1
#define REMOTEXY_SERIAL_SPEED 9600
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 1,11,137,0,6,5,1,1,1,8
,12,48,13,2,208,161,208,179,208,181
,208,189,208,181,209,128,208,184,209,128
,208,190,208,178,208,176,209,130,209,140
,32,208,191,208,176,209,128,208,190,208
,187,209,140,0,67,1,10,41,43,7
,3,11,129,0,8,4,48,5,0,208
,147,208,181,208,189,208,181,209,128,208
,176,209,130,208,190,209,128,32,208,191
,208,176,209,128,208,190,208,187,208,181
,208,185,0,129,0,8,29,48,5,0
,208,146,208,176,209,136,32,208,189,208
,190,208,178,209,139,208,185,32,208,191
,208,176,209,128,208,190,208,187,209,140
,0 };
struct {
// input variable
uint8_t button_1; // кнопка будет запускать генерацию
// output variable
char text_1[11]; // в этой строке пароль будет передан в смартфон
//обратите внимание, что здесь изменить длину строки нельзя
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop) /////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
char pass[11]; //в этом массиве символов будет храниться сгенерированный пароль до передачи его в смартфон
void setup() {
RemoteXY_Init (); }
void loop() { RemoteXY_Handler ();
if (RemoteXY.button_1==1){//если нажата кнопка «сгенерировать пароль»,
//то начинаем генерировать пароль
randomSeed(millis()); //инициализация генератора случайных чисел
for (int i=0; i<=9; i++){ //в нашем пароле 10 символов, начинаем генерировать по 1 символу.
//Массивы нумеруются с 0, поэтому начальное значение i=0.
pass[i]=random(48, 122); //присваиваем очередному элtменту массива pass случайное значение из таблицы ascii,
//я использую с 48 по 122 символы.
//в функции random указано, с какого и по какой символы таблицы ascii использовать при генерации
}
RemoteXY.button_1=0; //обнуляем значение кнопки, что бы был сгенерирован один пароль
//иначе генерация будет продолжаться, пока будет нажата кнопка «сгенерировать пароль»
}
strcpy(RemoteXY.text_1, pass); //передаем сгенерированный пароль в поле структуры text_1 }
На этом цикл теоретических статей по сервису RemoteXY можно считать законченным. Но некоторые нововведения остались в стороне, а именно подключение смартфона к ардуино через облачный сервер и защита соединения паролем. Их я рассмотрю в одной из практических статей, вместе с каким-либо устройством.
Прикрепленные файлы:
- RemoteXY3.zip (4 Кб)