Реклама ⓘ
Главная » Arduino
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

Интернет вещей с RemoteXY: элементы управления, часть 2

Продолжаю серию статей по сервису RemoteXY. В статье рассмотрены элементы управления джойстик, поле ввода и RGB-круг. Работа с каждым элементом рассмотрена на практическом примере простых для повторения новичками устройств.

Джойстик

Если слайдер предполагает изменение значения положения в одной оси, то джойстик дает возможность изменять сразу два значения в двух перпендикулярных осях.

Элемент «джойстик» имеет параметры цвет, имя переменной (по умолчанию joystick), авто центрирование, кнопка центрирования и кнопка G-сенсора. Поскольку джойстик изменяет положение в 2 осях, то для хранения этих значений в структуре RemoteXY создаются два поля с постфиксами _x и _y, (для значения по умолчанию создаются поля RemoteXY.joystick_1_x и RemoteXY.joystick_1_y).

struct {   // input variable
int8_t joystick_1_x; // =-100..100 координата x положения джойстика   int8_t joystick_1_y; // =-100..100 координата y положения джойстика   // other variable
uint8_t connect_flag;  // =1 if wire connected, else =0 } RemoteXY;

Закрепим полученные знания, применив их в необычном музыкальном проекте.Поля структуры принимают значения от -100 до 100, центр джойстика имеет значение 0. Авто центрирование автоматически возвращает положение джойстика в 0, как только будет убран палец с «движка» джойстика. Если не включено авто центрирование, то вернуть значения полей структуры в 0 можно при помощи кнопки центрирования. Переключатель G-сенсора позволяет включить управление элементом «джойстик» при помощи встроенных в смартфон сенсоров положения. По умолчанию программа предполагает нулевое положение смартфона экраном вверх. Но это значение можно «обнулить» в любом другом положении при помощи кнопки центрирования. Переключатель G-сенсора и кнопку авто центрирования можно установить в одно из четырех положений: вверх слева, снизу слева, вверху справа или внизу справа.

За основу этого музыкального проекта был взят музыкальный инструмент терменвокс (назван в честь его изобретателя Льва Сергеевича Термена, изобретен в 1920 году), инструмент не имеет привычных элементов управления в виде клавиш, струн и даже педалей. Управление инструментом осуществляется дистанционно, приближением и отдалением рук от чувствительных антенн. В классическом терменвоксе высота звука зависит от приближения правой руки к правой антенне, левая рука и, соответственно, левая антенна изменяют громкость звука. Поскольку темой этой главы является джойстик, то и управлять «терменвоксом» будем джойстиком. Одна ось джойстика будет отвечать за частоту звука, второй осью попытаемся регулировать громкость (сразу скажу, что без полноценного ЦАП это не получится, так же не получится и полноценный терменвокс). Генерировать звук будем при помощи зуммера без встроенного генератора.

Немного о зуммерах. Я использую зуммеры 1212XP со встроенным генератором звука (примерно 2500 герц) и аналогичный зуммер без встроенного генератора (извлечен из старых часов в виде пейджера). Обратим взор к маркировке зуммера 1212XP: первая часть числа означает размер зуммера (12 мм), вторая – напряжение питания (01 для 1,5 вольт, 03 для 3 вольт, 05 для 5 вольт и 12 для 12 вольт), буква X означает, что зуммер снабжен встроенным генератором звуковой частоты (А - зуммер без генератора). Потребляют такие зуммеры не более 30 mA.

Что касается управлением высотой звука, то тут всё просто, используем функцию tone для генерации прямоугольных импульсов. Импульсы всегда с 50% скважностью, но их частоту можно менять. С регулировкой громкости звука сложнее, потому что аналоговый сигнал получить от arduino невозможно, только его имитацию при помощи ШИМ. Таким образом, вместо регулировки громкости звука получится модуляция сигнала с более высокой частотой сигналом с менее низкой. Частота генерации ШИМ около 1 кГц (вот только что специально замерил), частота генерации tone лежит в диапазоне от 31 до 65535 Гц. В итоге получится сложный сигнал, пример такого сигнала представлен на скриншоте.

Тем не менее, звучит это довольно забавно, но все же это нельзя назвать полноценным терменвоксом. На этом варианте и остановимся. Код проекта в текущей реализации приведен ниже.

// определение режима соединения и подключение библиотеки 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[] =

 { 2,0,10,0,6,5,1,5,0,0

 ,17,63,63,2 };

// структура определяет все переменные вашего интерфейса управления struct {

   // input variable

 int8_t joystick_1_x; // =-100..100 координата x положения джойстика

 int8_t joystick_1_y; // =-100..100 координата y положения джойстика

// other variable

 uint8_t connect_flag; // =1 if wire connected, else =0

} RemoteXY;

#pragma pack(pop)

void setup() {

 RemoteXY_Init ();   }

void loop() {  RemoteXY_Handler ();

analogWrite(13, map(RemoteXY.joystick_1_x, -100, 100, 0, 255));  tone(12, map(RemoteXY.joystick_1_y, -100, 100, 50, 5000));  }

Что еще можно сделать на основе этого проекта?

  • Изменить функцию tone на analogWrite(12, map(RemoteXY.joystick_1_y, -100, 100, 0, 255));  
  • Использовать обе оси в функции tone(13, (map(RemoteXY.joystick_1_y, -100, 100, 50, 500)*map(RemoteXY.joystick_1_x, -100, 100, 1, 10))); для более точного управления высотой звука;
  • В качестве источника звука использовать зуммер с генератором, получаются интересные звуковые эффекты.

Поле ввода

Поле ввода предназначено для передачи в контроллер строки или числа. Элемент имеет параметры цвет, имя переменной (по умолчанию edit), тип вводимых данных, выравнивание (слева, по центру или справа), отображение фона и кнопка очистки.

Пройдемся по элементам в обратном порядке. Кнопка очистки, располагается в правой части элемента, выглядит как прямоугольник с крестиком. При нажатии на нее на экране смартфона появляется всплывающее окошко с вопросом «Очистить поле ввода?» и кнопками «Да» и «Отмена». Обратите внимание: цвет окна совпадает с цветом элемента, а текст остается белым. Поэтому если установлен светлый цвет элемента, то белая надпись будет читаться с трудом (но мы уже знаем что там написано).

Обратите внимание, что белый текст на желтом фоне плохо виден.

Если стоит галочка «показывать фон», то фон внутри рамки элемента будет темно-серым, и на темно-сером фоне надписи темным цветом будут плохо читаться. Если галочка не стоит, то фон будет прозрачным, через него будет видно фон экрана и элементы, находящиеся позади поля ввода (например, панель).

Выравнивание, как ни странно, выравнивает надпись внутри рамки в одном из трех положений: слева, по центру или справа.

Тип вводимых данных:

  • Целое число, от −32767 до +32767, тип int16_t. Если ввести число, не попадающее в это диапазон, то в поле появится максимальное (или минимальное, если было введено отрицательное число) число 32767. Дробное число ввести не получится, десятичная точка просто не сработает. Если попытаться вставить дробное число через буфер обмена, то точка просто будет изъята из числа, и вместо, например, числа 2,31 будет вставлено число 231.
  • Вещественное число (десятичная дробь), тип float. При выборе вещественного числа появляется дополнительный выпадающий список, в котором можно выбрать количество знаков после запятой (от 0 до 6 или не ограничено). При этом программа позволяет ввести больше знаков после запятой, но затем округляет их по правилам округления. Если попытаться вставить через буфер обмена в поле текст, то ничего не получится, он просто там не появится. Если текст, вперемешку с числами, то все символы кроме чисел пропадут, а числа сольются в одно число.
  • Текстовая строка, тип char. При выборе текстовой строки появляется дополнительное поле, в котором можно указать, сколько символов должна занимать строка (на самом деле выделяется количество байт, но при передаче текста используется кодировка UTF8, в которой некоторые символы могут занимать 2 байта). Генератор исходного кода автоматически добавит 1 байт к текстовой строке для символа завершения строки.

Для закрепления полученных знаний предлагаю переделать проект «кодового» замка в по-настоящему кодовый замок. Схема устройства меняться не будет, изменению будет подвергнут только исходный код.

Создаем новый интерфейс, конфигурация и подключение модуля на скриншотах.

В этот раз я включу кодовый замок в локальную сеть. Интерфейс будет выглядеть так. Обратите внимание на параметры поля ввода, я выделил 5 символов для пароля, тип вводимых данных – текстовая строка, поэтому код можно сделать довольно сложным.

Дальнейшие пояснения в комментариях к коду.

//////////////////////////////////////////////

//   RemoteXY include library   //

//////////////////////////////////////////////

// определение режима соединения и подключение библиотеки RemoteXY #define REMOTEXY_MODE__ESP8266WIFI_LIB

#include <ESP8266WiFi.h>

#include <RemoteXY.h>

// настройки соединения #define REMOTEXY_WIFI_SSID "TP-LINK"

#define REMOTEXY_WIFI_PASSWORD ""

#define REMOTEXY_SERVER_PORT 6377

// конфигурация интерфейса  #pragma pack(push, 1)

uint8_t RemoteXY_CONF[] =

 { 7,0,45,0,6,0,1,1,1,11

 ,49,43,12,2,79,112,101,110,0,7

 ,38,8,25,49,12,2,6,129,0,9

 ,12,44,6,14,69,110,116,101,114,32

 ,112,97,115,115,119,111,114,100,0 };

 // структура определяет все переменные вашего интерфейса управления struct {

 // input variable

 uint8_t button_1; //  0

 char edit_1[6]; // измените значение в [] скобках, если хотите установить пароль другой
//длинны, но помните о дополнительном байте для завершающего символа строки

   // other variable

 uint8_t connect_flag; // =1 if wire connected, else =0

} RemoteXY;

#pragma pack(pop)

/////////////////////////////////////////////

//   END RemoteXY include   //

/////////////////////////////////////////////

#define PIN_BUTTON_1 D0 //к этому выводу подключен электромагнитный замок

 char pass[] = "q1W34"; //это пароль, при необходимости его можно изменить. 
//Следите за тем, что бы он был не длиннее, чем позволяет поле структуры RemoteXY.edit_1

void setup() {

RemoteXY_Init ();   pinMode (PIN_BUTTON_1, OUTPUT);

}



void loop() {  RemoteXY_Handler ();

//отсюда начинается магия

//функция strcmp сравнивает строки, если они равны, то возвращает 0

 if ((strcmp (RemoteXY.edit_1, pass)==0)&&RemoteXY.button_1==1)//если строки равны И нажата кнопка

  {  digitalWrite(PIN_BUTTON_1, HIGH);//то срабатывает электромагнит в замке

  else

  {

 digitalWrite(PIN_BUTTON_1, LOW);//принудительно закрываем замок

  }

}

 

RGB-круг

Элемент «RGB» предназначен для установки цвета в палитре RGB.

Имеет всего два параметра: цвет и имя переменной (по умолчанию rgb), но задает значения сразу для трех полей структуры, по одному полю на компонент цвета. Имена полей структуры оканчиваются на _r, _g, _b для красного, зеленого и синего цветов соответственно.

struct {   // input variable
uint8_t rgb_1_r; // =0..255 значение Красного цвета   uint8_t rgb_1_g; // =0..255 значение Зеленого цвета   uint8_t rgb_1_b; // =0..255 значение Синего цвета   // other variable
uint8_t connect_flag;  // =1 if wire connected, else =0 } RemoteXY; 

Значение полей структуры для RGB лежат в диапазоне от 0 до 255. Обратите внимание на внешний вид элемента. Внешнее кольцо устанавливает цвет, внутреннее настраивает интенсивность свечения всех трех цветов. Внутренний круг разбит на четыре сектора. Буква b означает black – интенсивность всех трех компонентов цвета устанавливается равной нулю. Буква w означает white – устанавливает максимальное свечение всех трех компонентов цвета. Буква g это оттенки серого, при перемещении регулятора по верхней дуге внутреннего круга все три компоненты цвета будут устанавливаться одинаковыми, таким образом можно настроить интенсивность свечения белого цвета. На самом низу устоит буква с – color. Если регулятор установлен прямо на букве, то значения цветов совпадают с установленным цветом на наружном кольце. Перемещая движок от c к b можно приглушить яркость цветов вплоть до черного цвета (то есть отсутствия свечения), перемещая движок от c к w цвета можно осветлить вплоть до белого.

Внимание, пытаясь понять то, что здесь написано вы рискуете вообще ничего не понять и окончательно запутаться. Если же вы все-таки решили прочитать это, но в итоге не поняли, то постарайтесь забыть.

На самом деле все немного хитрее, чем я описал, регулятор работает с палитрой HSB, но потом переводит её в RGB. Внешнее кольцо выбора цвета характеризует компоненту H палитры HSB, в которой значением от 0 до 360 задается цвет. Компонента S задает сдвиг цвета H к белому цвету, а компонента B - к черному. Таким образом, в положении “c” компоненты S и B находятся в положении 100.  Сдвигая регулятор на внутреннем кольце в сторону w, мы сдвигаем компоненту S в сторону нуля, а цвет становится более блеклым, пока не станет совсем белым. Сдвигая регулятор в сторону b, мы уменьшаем компоненту B в сторону нуля, цвет теряет насыщенность вплоть до черного цвета (отсутствия свечения светодиодов). Когда регулятор находится в верхней части внутреннего круга, компонента S становится равна нулю, изменяется только компонента B, то есть цвет принимает оттенки серого.

Что бы разобраться во всех нюансах палитр рекомендую воспользоваться программой “Color Palette  - Iromihon- “, программа расположена по адресу https://play.google.com/store/apps/details?id=net.uzumaki.android.iromihon

 

Для закрепления материала я предлагаю практическое задание.

Цель задания – создать фонарик, который может менять цвет свечения, для фотографий в стиле freezligt.

 

Фризлайт (застывший свет) – прием в фотографии, когда на фотоаппарате, установленном на штатив, устанавливают длинную выдержку и, пока затвор открыт, рисуют в воздухе фонариком всякую всячину. Пример фризлайта на фото.

Управление цветом свечения будет осуществляться со смартфона через программу RemoteXY. Параметры и конфигурация подключения произвольны (в моем случае соединение по Bluetooth, контроллер arduino mega2560, модуль связи HC-05, подключение модуля связи по Serial1 на скорости 9600). На рабочем поле располагается только элемент выбора цвета, рекомендую сделать его как можно больше, так легче управлять.

Устройство построено по следующей схеме.

Для любителей программы Fritizing.

И для тех, кто предпочитает стандартные схемы.

Сигнал с выводов, поддерживающих ШИМ, проходит через микросхему ULN2003, где усиливается и инвертируется. Светодиод (а в моем случае светодиодная лента) подключается к микросхеме через гасящие резисторы, номинал резисторов надо подобрать исходя из параметров светодиода и напряжения питания. В моем случае лента предназначена для работы с напряжением 12 вольт, резисторы на ней уже установлены. Светодиод подключен к отдельному источнику питания с напряжением 12 вольт, напряжение подается через отдельный штекер. Дальнейшие пояснения по коду в комментариях.

//////////////////////////////////////////////

//   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[] =

 { 3,0,10,0,6,5,1,6,0,-1

 ,1,64,64,2 };

  // структура определяет все переменные вашего интерфейса управления struct {

   // input variable

 uint8_t rgb_1_r; // =0..255 значение Красного цвета

 uint8_t rgb_1_g; // =0..255 значение Зеленого цвета

 uint8_t rgb_1_b; // =0..255 значение Синего цвета
   // 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 ();

if (RemoteXY.connect_flag==1) //здесь я покажу, как можно использовать «флаг подключения» в программе

//если соединение между контроллером и смартфоном установлено, 
//то устанавливаем значения ШИМ в соответствии с полями структуры элемента RGB

{

analogWrite(13, RemoteXY.rgb_1_r);

analogWrite(12, RemoteXY.rgb_1_g);

analogWrite(11, RemoteXY.rgb_1_b);

}

else {

 analogWrite(13, 0);

 analogWrite(12, 0);

 analogWrite(11, 0);

   }//если подключения нет, то светодиод гаснет.

}

Таким образом, получаем светодиодный фонарик, который

  • Меняет цвет свечения;
  • Горит только тогда, когда установлено соединение со смартфоном.

На этом рассмотрение элементов управления можно считать оконченным. В следующей статье поведаю про элементы индикации.

P.S. Вставка кода изуродовала исходные коды, нормально отформатированные исходные коды смотрите в приложенных файлах.

Прикрепленные файлы:

Теги:

Опубликована: 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (0) | Я собрал (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Raspberry Pi 2
Raspberry Pi 2
Pickit 2 - USB-программатор PIC-микроконтроллеров Модуль радиореле на 4 канала
вверх