Arduino:Примеры/EsploraRemote
Поддержать проект | Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Содержание
Удаленное управление и тестирование Esplora[1]
Этот пример создан, чтобы работать вместе с приложением на языке Processing (это язык программирования с открытым кодом). Вам нужно будет установить это приложение на компьютер, чтобы с его помощью, во-первых, считывать данные с датчиков Esplora, а во-вторых, управлять RGB-светодиодом и зуммером Esplora. Кроме того, графический интерфейс в скетче Processing будет представлять собой виртуальную копию вашей Esplora.
Если Processing на вашем компьютере нет, этот пример можно протестировать и при помощи окна Serial Monitor, взаимодействуя с Esplora при помощи специальных интерактивных команд, отсылаемых через последовательный порт.
С этим примером может работать два скетча Processing (ссылки на них можно найти ниже). Первый (попроще, для начинающих Processing-программистов) выводит данные от датчиков в текстовом виде, тогда как второй (посложнее, для продвинутых) демонстрирует графическую репрезентацию Esplora.
В этом ZIP-файле содержится тот скетч, что попроще, а в этом – что посложнее(также с кодом можно ознакомиться ниже).
Вам лишь нужно распаковать файл внутри папки скетчей Processing, а затем запустить саму Processing и открыть в ней файл с расширением *.pde.
Необходимое оборудование
- Плата Arduino Esplora;
Необходимое ПО
Цепь
Для этого примера нужна лишь Arduino Esplora.
Расположение элементов Arduino Esplora
Код для Arduino
Этот пример создает интерфейс последовательного соединения между компьютером и Esplora. То есть, отвечая на команды, которые вы будете отправлять через последовательный порт, Esplora будет считывать данные со своих датчиков, а также управлять своими зуммером и RGB-светодиодом.
Ваши команды будут начинаться с символа, обозначающего ту или иную операцию, которую вы хотите проделать с Esplora. В довесок к этому символу будет идти значение, которое нужно будет передать тому или иному элементу Esplora (в данном случае, RGB-светодиоду или зуммеру), или количество «проб» данных, которые нужно собрать.
Используя этот скетч в комбинации с приложением на Processing, вы сможете управлять Esplora, не просто печатая те или иные команды, а пользуясь специальным графическим интерфейсом. Впрочем, вы по-прежнему можете управлять платой и при помощи текстовых команд, вводимых в окне Serial Monitor или какой-либо программе, выполняющей его функции.
Данные ото всех датчиков будут отображаться и на «рисунке» Esplora, который вы будете видеть на экране компьютера, а RGB-светодиодом и зуммером можно будет управлять при помощи слайдеров, простой кликая на нужный компонент.
ПРИМЕЧАНИЕ: Одновременно доступ к последовательному порту компьютера может иметь только одна программа. То есть, если у вас открыт Serial Monitor, то скетч Processing «пробиться» к последовательному порту Esplora не сможет. И наоборот, если у вас будет запущен скетч Processing, то вы не сможете открыть Serial Monitor и перепрограммировать свою Esplora.
1 /*
2
3 Удаленное управление Esplora
4
5 Этот скетч позволяет вам тестировать все периферийные элементы Esplora.
6 Кроме того, им можно пользоваться вместе со скетчем ProcessingStart (для Processing).
7
8 Загрузив его, вы можете открыть Serial Monitor
9 и вписать там одну из нижеследующих команд (без кавычек):
10
11 «D» – выводит данные ото всех датчиков, разделяя их запятой.
12 О том, что это за данные, можно узнать в функции dumpInputs().
13
14 «Rxxx», «Gxxx», «Bxxx» – задают цвет RGB-светодиода.
15 Например, если написать «R255», мы включим на полную яркость красный канал RGB-светодиода.
16 Если написать «G128», то мы установим среднюю яркость у среднего канала.
17 Или, если написать «B0», то мы совсем отключим синий канал.
18
19 «Txxxx» – проигрывает ноту на зуммере.
20 Число – это частота, т.е., например, если вписать команду «T440», зуммер сыграет ноту «ля».
21 А если вписать «T0», это выключит зуммер.
22
23 Создан 22 ноября 2012 Энрико Гуэли (Enrico Gueli, enrico.gueli@gmail.com),
24 модифицирован 23 декабря 2012 Томом Иго (Tom Igoe).
25
26 */
27
28 #include <Esplora.h>
29
30 void setup() {
31 while (!Serial); // нужно для плат на базе Leonardo (вроде Esplora)
32 Serial.begin(9600);
33 }
34
35 void loop() {
36 if (Serial.available())
37 parseCommand();
38 }
39
40 /*
41 Эта функция считывает текстовый символ от команды,
42 присланной через последовательный порт, а затем решает, что делать дальше.
43 Под «что делать дальше» подразумевается вызов функции,
44 соответствующей считанному текстовому символу.
45 Например, команда «D» вызывает функцию dumpInputs(), «Rxxx» – setRed() и т.д.
46 */
47
48 void parseCommand() {
49 char cmd = Serial.read();
50 switch (cmd) {
51 case 'D':
52 dumpInputs();
53 break;
54 case 'R':
55 setRed();
56 break;
57 case 'G':
58 setGreen();
59 break;
60 case 'B':
61 setBlue();
62 break;
63 case 'T':
64 setTone();
65 break;
66 }
67 }
68
69 void dumpInputs() {
70 Serial.print(Esplora.readButton(SWITCH_1));
71 Serial.print(',');
72 Serial.print(Esplora.readButton(SWITCH_2));
73 Serial.print(',');
74 Serial.print(Esplora.readButton(SWITCH_3));
75 Serial.print(',');
76 Serial.print(Esplora.readButton(SWITCH_4));
77 Serial.print(',');
78 Serial.print(Esplora.readSlider());
79 Serial.print(',');
80 Serial.print(Esplora.readLightSensor());
81 Serial.print(',');
82 Serial.print(Esplora.readTemperature(DEGREES_C));
83 Serial.print(',');
84 Serial.print(Esplora.readMicrophone());
85 Serial.print(',');
86 Serial.print(Esplora.readJoystickSwitch());
87 Serial.print(',');
88 Serial.print(Esplora.readJoystickX());
89 Serial.print(',');
90 Serial.print(Esplora.readJoystickY());
91 Serial.print(',');
92 Serial.print(Esplora.readAccelerometer(X_AXIS));
93 Serial.print(',');
94 Serial.print(Esplora.readAccelerometer(Y_AXIS));
95 Serial.print(',');
96 Serial.print(Esplora.readAccelerometer(Z_AXIS));
97 Serial.println();
98 }
99
100 void setRed() {
101 Esplora.writeRed(Serial.parseInt());
102 }
103
104 void setGreen() {
105 Esplora.writeGreen(Serial.parseInt());
106 }
107
108 void setBlue() {
109 Esplora.writeBlue(Serial.parseInt());
110 }
111
112 void setTone() {
113 Esplora.tone(Serial.parseInt());
114 }
Код для Processing
Простой пример
ProcessingSimpleRemote.pde
1 /*
2 Скетч к Processing для удаленного управления Esplora
3
4 Этот скетч позволит вам управлять записью и считыванием с некоторых
5 устройств ввода и вывода, которыми оснащена Esplora.
6
7 Чтобы получить ответ, вам надо будет вписать одну из нижеследующих команд (без кавычек):
8
9 «D» – выводит данные ото всех датчиков.
10
11 «Rxxx», «Gxxx», «Bxxx» – задают цвета для RGB-светодиода.
12 Например, «R255» включит красный канал светодиода на полную яркость,
13 «G128» включит яркость зеленого канала наполовину,
14 а «B0» полностью выключит синий канал.
15
16 «Txxxx» – проигрывает ноту при помощи зуммера.
17 Номер вместо «иксов» обозначает частоту звука, т.е. «T440» будет означать среднее «ля».
18 Если написать «Т0», то это отключит зуммер.
19
20 Создан 22 декабря 2012 Томом Иго (Tom Igoe).
21
22 Этот код не защищен авторским правом.
23 */
24
25 import processing.serial.*; // инициализируем библиотеку Serial
26
27 Serial Esplora; // подключаем Esplora через последовательный порт
28 String numberString = ""; // строка для порта, который будет инициализирован следующим
29 String[] valueNames = { // названия, связанные со значениями, которые будет отправлять Esplora
30 "switch 1", "switch 2", "switch 3", "switch 4", "slider",
31 "light sensor", "temperature (Celsius)", "microphone", "joystick switch",
32 "joystick X", "joystick Y", "accelerometer X axis", "accelerometer Y axis",
33 "accelerometer Z axis"
34 };
35 String displayString = ""; // строка для отображения информации на экране
36 char command; // однобуквенная команда от пользователя
37
38 void setup() {
39 size(640, 480); // размер экрана программы
40 }
41
42 void draw() {
43 // очищаем экран:
44 background(0);
45 fill(255);
46 int linePosition = 20; // задаем позицию для строки с начальным текстом:
47
48 // Если Esplora не инициализирована:
49 if (Esplora == null) {
50 // Получаем список последовательных портов:
51 String[] portList = Serial.list();
52 // Показываем на экране инструкции:
53 text("Type P and the port number of your Esplora:", linePosition, 20); // "Напишите «P» и номер порта вашей Esplora:"
54 // Показываем на экране список портов:
55 for (int i = 0; i < portList.length; i++) {
56 linePosition = (i+4) *20;
57 text("port " + i + ": " + portList[i], 20, linePosition);
58 }
59 }
60
61 // Если все необходимые порты имеются:
62 else {
63 // Показываем самые последние новости:
64 text(displayString, 20, linePosition);
65
66 // Опускаемся чуть ниже, где будем показывать обновления:
67 linePosition = 240;
68 text("type Rxxx (xxx = a number 0-255) and return to set the red value", 20, linePosition); // "Впишите «Rxxx» (где «ххх» – это номер от 0 до 255) и нажмите Enter, чтобы задать значение для красного канала RGB-светодиода"
69 linePosition += 20;
70 text("type Gxxx (xxx = a number 0-255) and return to set the green value", 20, linePosition); "Впишите «Gxxx» (где «ххх» – это номер от 0 до 255) и нажмите Enter, чтобы задать значение для зеленого канала RGB-светодиода"
71 linePosition += 20;
72 text("type Bxxx (xxx = a number 0-255) and return to set the blue value", 20, linePosition); "Впишите «Bxxx» (где «ххх» – это номер от 0 до 255) и нажмите Enter, чтобы задать значение для синего канала RGB-светодиода"
73 linePosition += 20;
74 text("type Txxx (xxx = a number 0 - 20000) and return to set the tone", 20, linePosition); "Впишите «Txxx» (где «ххх» – это номер от 0 до 2000) и нажмите Enter, чтобы задать нужную ноту"
75 linePosition += 20;
76 text("type D to get the values of all sensors", 20, linePosition); // "Впишите D, чтобы получить значения ото всех датчиков"
77
78 }
79 }
80
81 void serialEvent(Serial Esplora) {
82 // считываем строку, пришедшую через последовательный порт:
83 displayString = Esplora.readStringUntil('\n');
84 // анализируем ответ и добавляем надписи для отображения на экране:
85 displayString = parseResponse(displayString);
86 }
87
88 void keyReleased() {
89 // буквы A-Z и a-z могут быть командами:
90 if (key >= 'A' && key <= 'z') {
91 command = key;
92 }
93 // если нажат Enter, останавливаем выбор номера порта:
94 if (key == ENTER ) {
95 String outputString = "";
96 switch (command) {
97 case 'D': // нужно показать данные ото всех датчиков Esplora
98 case 'd':
99 outputString = "D" + numberString;
100 break;
101 case 'R': // задаем значение для красного канала (0 - 255)
102 case 'r':
103 outputString = "R" + numberString;
104 break;
105 case 'G': // задаем значение для зеленого канала (0 - 255)
106 case 'g':
107 outputString = "G" + numberString;
108 break;
109 case 'B': // задаем значение для синего канала (0 - 255)
110 case 'b':
111 outputString = "B" + numberString;
112 break;
113 case 'T': // задаем звук (0 - 20000)
114 case 't':
115 outputString = "T" + numberString;
116 break;
117 case 'P': // открываем последовательный порт
118 case 'p':
119 if (Esplora == null) {
120 choosePort(numberString);
121 outputString = "Port " + numberString + " opened.";
122 }
123 else {
124 outputString = "Port already open";
125 }
126 break;
127 }
128 // Обновляем строку на дисплее последними командами от пользователя:
129 displayString = outputString;
130 // Если есть какие-либо данные для записи на Esplora, отправляем их:
131 if (outputString != "") {
132 Esplora.write(outputString);
133 numberString = ""; // очищаем строку с числами
134 }
135 command = 0; // очищаем переменную с командой
136 }
137 // Если пользователь нажимает от 0 до 9, используем это для выбора номера порта:
138 if (key >= '0' && key <= '9') {
139 numberString += key;
140 }
141 }
142
143 void choosePort(String thisPort) {
144 int whichPort = int(thisPort); // конвертируем строку в целое число
145 // Если считанный номер является подходящим значением, открываем порт:
146 if (whichPort >= 0 && whichPort < Serial.list().length) {
147 // Берем название порта из списка последовательных портов:
148 String portName = Serial.list()[whichPort];
149 // Инициализируем следующую Esplora:
150 Esplora = new Serial(this, portName, 9600);
151 // Считываем байты в буфер, пока не наткнемся на символ перевода строки (номер 10 в таблице ASCII):
152 Esplora.bufferUntil('\n');
153 // Очищаем строку с номером порта:
154 numberString = "";
155 }
156 }
157
158 String parseResponse(String inputString) {
159 String response = ""; // строка с данными, возвращенными от функции
160 int[] values = int(split(inputString, ",")); // разбиваем входящую строку по запятым
161
162 // прочесываем входящий массив, добавляя к значениям названия из массива valueNames:
163 for (int i = 0; i < values.length; i++) {
164 response += (valueNames[i] + ": " + values[i] + "\n");
165 }
166 // Возвращаем итоговую строку:
167 return response;
168 }
Сложный пример
ProcessingEsploraRemote.pde
1 import processing.serial.*;
2
3 final int WIDTH = 1162;
4 final int HEIGHT = 652;
5
6 final int margin = 20;
7 final int boardRatio = 2;
8 final int b_width = WIDTH - boardRatio*margin;
9 final int b_height = b_width/3;
10
11 final int middleY = margin+b_height/2;
12
13 final int jsCenterX = 255;
14 final int jsCenterY = 289;
15 final int jsOuterRadius = 80;
16 final int jsInnerRadius = 60;
17 final int jsSwing = 60;
18
19 final int switchLeft = 787;
20 final int switchesCenterX = 849;
21 final int switchRight = 910;
22 final int switchTop = 231;
23 final int switchesCenterY = 290;
24 final int switchBottom = 351;
25 final int switchRadius = 20;
26
27 final int accelCenterX = 549;
28 final int accelCenterY = 289;
29 final int accelBarHeight = 20;
30 final int accelBarWidth = 50;
31
32 final int micCenterX = 377;
33 final int micCenterY = 419;
34 final int micRadiusOffset = 10;
35 final float micRadiusScale = 50;
36
37 final int sliderLeft = 448;
38 final int sliderRight = 645;
39 final int sliderY = 419;
40 final int sliderCursorHeight = 12;
41 final int sliderCursorWidth = 35;
42
43 final int lightCenterX = 765;
44 final int lightCenterY = 167;
45 final int lightRadius = 10;
46 final float lightScale = 70;
47
48 final int ledCenterX = 720;
49 final int ledCenterY = 419;
50 final int ledRadius = 10;
51
52 final int buzzCenterX = 336;
53 final int buzzCenterY = 167;
54 final int buzzRadius = 30;
55
56 final int tempCenterX = 549;
57 final int tempCenterY = 351;
58
59 PImage esploraBkg;
60
61 void setup() {
62 size(WIDTH, HEIGHT);
63
64 esploraBkg = loadImage("esplora.png");
65
66 Esplora.begin(this);
67
68 for (SlideControl rc : rgbControls) {
69 rc.send();
70 }
71 }
72
73
74
75 void draw() {
76 Esplora.update();
77
78 background(255);
79 ellipseMode(RADIUS);
80
81 /*
82 * Рисунок Esplora
83 */
84 image(esploraBkg, 0, 0);
85
86 pushMatrix();
87 {
88 translate(jsCenterX, jsCenterY);
89
90 /*
91 * Джойстик, статичная часть
92 */
93 fill(64);
94 ellipse(0, 0, jsOuterRadius, jsOuterRadius);
95
96 /*
97 * Джойстик, двигающаяся часть
98 */
99 if (Esplora.joystickSwitch)
100 fill(255, 0, 0);
101 else
102 fill(0, 0, 0);
103 ellipse(Esplora.joystickX * jsSwing,
104 Esplora.joystickY * jsSwing,
105 jsInnerRadius, jsInnerRadius);
106 }
107 popMatrix();
108
109 /*
110 * Кнопки
111 */
112 int[][] switchMap = new int[][] {
113 { switchesCenterX, switchBottom },
114 { switchLeft , switchesCenterY },
115 { switchesCenterX, switchTop },
116 { switchRight , switchesCenterY },
117 };
118 pushMatrix();
119 {
120 for (int i=0; i<switchMap.length; i++) {
121 pushMatrix();
122 {
123 translate(switchMap[i][0], switchMap[i][1]);
124 if (Esplora.switches(i))
125 fill(255, 0, 0);
126 else
127 fill(0, 0, 0);
128 ellipse(0, 0, switchRadius, switchRadius);
129 }
130 popMatrix();
131 }
132 }
133 popMatrix();
134
135 /*
136 * Оси акселерометра
137 */
138 pushMatrix();
139 {
140 translate(accelCenterX, accelCenterY);
141
142 fill(192);
143 drawAccelBar(Esplora.accelX);
144 rotate(-PI/2);
145 drawAccelBar(Esplora.accelY);
146 rotate(-PI/2-PI/4);
147 drawAccelBar(Esplora.accelZ);
148
149 fill(0);
150 }
151 popMatrix();
152
153
154 /*
155 * Микрофон
156 */
157 pushMatrix();
158 {
159 translate(micCenterX, micCenterY);
160 float radius = micRadiusOffset + Esplora.mic*micRadiusScale;
161 ellipse(0, 0, radius, radius);
162 }
163 popMatrix();
164
165
166 pushMatrix(); pushStyle();
167 {
168 /*
169 * Линейный потенциометр, статичная часть
170 */
171 final int sliderWidth = sliderRight - sliderLeft;
172 //line(sliderLeft, sliderY, sliderRight, sliderY);
173
174 /*
175 * Линейный потенциометр, двигающаяся часть
176 */
177 fill(143, 121, 99);
178 translate(sliderLeft + (1-Esplora.slider) * sliderWidth, sliderY);
179 rect(
180 -sliderCursorWidth/2, -sliderCursorHeight/2,
181 sliderCursorWidth, sliderCursorHeight);
182
183 }
184 popStyle(); popMatrix();
185
186 /*
187 * Световой датчик
188 */
189 pushMatrix(); pushStyle();
190 {
191 translate(lightCenterX, lightCenterY);
192 noStroke();
193
194 float l = Esplora.light;
195 scale(l);
196 for (float r = 1; r > 0; r -= .05f) {
197 fill(l*(1-r)*255, l*(1-r)*255, l*(1-r)*255, (1-r)*255);
198 ellipse(0, 0, r*lightScale, r*lightScale);
199 }
200
201 }
202 popStyle(); popMatrix();
203
204 /*
205 * Температурный датчик
206 */
207 pushMatrix(); pushStyle();
208 {
209 translate(tempCenterX, tempCenterY);
210 scale(2);
211 fill(255);
212 textAlign(CENTER, CENTER);
213 text((int)Esplora.temperatureC, 0, 0);
214 textAlign(LEFT, CENTER);
215 text(" °C", 0, 0);
216 }
217 popStyle(); popMatrix();
218
219
220 handleInputControls();
221 }
222
223 void drawAccelBar(float value) {
224 pushMatrix();
225 {
226 translate(accelBarHeight/2,0);
227 rect(0, -accelBarHeight/2, accelBarWidth*value, accelBarHeight);
228 }
229 popMatrix();
230 }
Esplora.pde
1 float[] ACCEL_SCALES = new float[] {
2 160, // X
3 162, // Y
4 140, // Z
5 };
6
7 class _Esplora {
8 /*
9 * Главный поток Processing считывает входящие данные, а Serial-поток записывает их.
10 * Поскольку все переменные независимы друг от друга
11 * (т.е. не находятся в противоречивом состоянии),
12 * я не обращаю внимания на проблемы с синхронизацией,
13 * а переменные для входных данных объявляю изменчивыми,
14 * чтобы отключить любую форму кэширования.
15 */
16 volatile boolean switch1;
17 volatile boolean switch2;
18 volatile boolean switch3;
19 volatile boolean switch4;
20
21 volatile float joystickX;
22 volatile float joystickY;
23 volatile boolean joystickSwitch;
24
25 volatile float accelX;
26 volatile float accelY;
27 volatile float accelZ;
28
29 volatile float mic;
30 volatile float slider;
31 volatile float light;
32 volatile float temperatureC;
33
34 volatile float ledR;
35 volatile float ledG;
36 volatile float ledB;
37 volatile int tone;
38
39
40 public boolean switches(int sw) {
41 switch(sw) {
42 case 0: return switch1;
43 case 1: return switch2;
44 case 2: return switch3;
45 case 3: return switch4;
46 }
47 return false;
48 }
49
50 /**
51 * Список корректных последовательных портов. Если при запуске порт
52 * будет иметь одно из этих названий, то он и будет использоваться.
53 * Впрочем, возможно, будет лучше применить более общий подход.
54 */
55 final String[] SERIAL_PORT_NAMES = {
56 "/dev/ttyACM0",
57 "/dev/ttyACM1",
58 "/dev/tty.usbmodemfd131",
59 "/dev/tty.usbmodemfa131",
60 "/dev/tty.usbmodemfd121",
61 "/dev/tty.usbmodemfa121",
62 "COM6",
63 "COM7"
64 };
65
66 Serial serial = null;
67 StringBuilder serialRow;
68
69
70 public void begin(PApplet applet) {
71 String[] serialList = Serial.list();
72
73 if (serialList.length >= 1) {
74 try {
75 for (String portNameA : serialList) {
76 for (String portNameB : SERIAL_PORT_NAMES) {
77 if (portNameB.equals(portNameA)) {
78 serial = new Serial(applet, portNameA, 9600);
79 println("found serial port: " + portNameA);
80 break;
81 }
82 }
83 }
84 }
85 catch (Exception e) {
86 println("Serial port open error: " + e.toString());
87 }
88 }
89 }
90
91 public void update() {
92 if (serial == null)
93 return;
94
95 String s = String.format("D\nR%d\nG%d\nB%d\nT%d\n",
96 (int)(constrain(ledR*256, 0, 255)),
97 (int)(constrain(ledG*256, 0, 255)),
98 (int)(constrain(ledB*256, 0, 255)),
99 tone
100 );
101
102 serial.write(s);
103 delay(10);
104 if (serial.available() == 0)
105 return;
106
107 String line = serial.readStringUntil('\n');
108 if (line == null)
109 return;
110
111 line = line.trim();
112
113 String[] fields = line.split(",");
114 if (fields.length != 14) {
115 println("nodump: " + line);
116 return;
117 }
118
119 int[] values = new int[fields.length];
120 for (int i=0; i<values.length; i++) {
121 values[i] = Integer.parseInt(fields[i]);
122 }
123
124 switch1 = values[0] == 0;
125 switch2 = values[1] == 0;
126 switch3 = values[2] == 0;
127 switch4 = values[3] == 0;
128
129 joystickSwitch = values[8] == 0;
130 joystickX = -((float)values[9]/1024);
131 joystickY = (float)values[10]/1024;
132
133 int aX = values[11];
134 int aY = values[12];
135 int aZ = values[13];
136 accelX = aX / ACCEL_SCALES[0];
137 accelY = aY / ACCEL_SCALES[1];
138 accelZ = aZ / ACCEL_SCALES[2];
139
140 mic = (float)values[7] / 1024;
141 slider = (float)values[4] / 1024;
142 light = (float)values[5] / 1024;
143 temperatureC = values[6];
144 }
145 }
146
147 _Esplora Esplora = new _Esplora();
Input.pde
1 boolean lastPressed = false;
2 int startDragX = 0;
3 int startDragY = 0;
4
5 boolean draggingLed = false;
6 boolean draggingTone = false;
7
8 final int slideBarHeight = 40;
9 final int slideBarWidth = 250;
10
11 final int toneSliderX = 50;
12 final int toneSliderY = 50;
13
14 final int rgbSlidersX = 700;
15 final int rgbSlidersY = 500;
16
17 abstract class SlideControl {
18 float value = 0;
19 float valueDragging = value;
20 color col;
21 SlideControl(color col) {
22 this.col = col;
23 }
24 void beginDrag() { valueDragging = value; }
25 void endDrag() { value = valueDragging; }
26
27 abstract void send();
28 }
29
30 class ToneSlideControl extends SlideControl {
31 ToneSlideControl() {
32 super(color(255,255,255));
33 }
34 void send(){
35 Esplora.tone=(int)(valueDragging*2000);
36 }
37 void beginDrag() {
38 Esplora.tone=(int)(value*2000);
39 super.beginDrag();
40 }
41 void endDrag() {
42 Esplora.tone=0;
43 super.endDrag();
44 }
45 }
46
47 SlideControl[] rgbControls = new SlideControl[] {
48 new SlideControl(color(255, 0, 0)) {void send(){Esplora.ledR=valueDragging;}},
49 new SlideControl(color(0, 255, 0)) {void send(){Esplora.ledG=valueDragging;}},
50 new SlideControl(color(0, 0, 255)) {void send(){Esplora.ledB=valueDragging;}},
51 };
52
53 SlideControl toneControl = new ToneSlideControl();
54
55 void handleInputControls() {
56
57 if (mousePressed) {
58 if (mouseX > rgbSlidersX && mouseX < rgbSlidersX + slideBarWidth) {
59 for (int i=0; i<rgbControls.length; i++) {
60 SlideControl rc = rgbControls[i];
61 if (mouseY > rgbSlidersY + i * slideBarHeight - slideBarHeight/2
62 && mouseY < rgbSlidersY + i * slideBarHeight + slideBarHeight/2) {
63 rc.valueDragging = (mouseX - rgbSlidersX) / (float)slideBarWidth;
64 rc.send();
65 }
66 }
67 }
68
69 if (mouseY > toneSliderX && mouseX < toneSliderX + slideBarWidth) {
70 if (mouseY > toneSliderY - slideBarHeight/2
71 && mouseY < toneSliderY + slideBarHeight/2) {
72 toneControl.valueDragging =
73 (mouseX - toneSliderX) / (float)slideBarWidth;
74 toneControl.send();
75 }
76 }
77 }
78 else
79 toneControl.endDrag();
80
81
82 /*
83 * Слайдер для звука
84 */
85 pushStyle(); pushMatrix();
86 {
87 translate(toneSliderX, toneSliderY);
88 drawSliders(new SlideControl[]{toneControl});
89 }
90 popMatrix(); popStyle();
91
92 /*
93 * Слайдеры для цвета
94 */
95 pushStyle(); pushMatrix();
96 {
97 translate(rgbSlidersX, rgbSlidersY);
98 drawSliders(rgbControls);
99 }
100 popMatrix(); popStyle();
101
102 }
103
104 void drawSliders(SlideControl[] controls) {
105 for (int i=0; i<controls.length; i++) {
106 SlideControl c = controls[i];
107 pushMatrix();
108 {
109 translate(0, i*slideBarHeight);
110 //rect(0, -slideBarHeight/2, slideBarWidth, slideBarHeight);
111 gradientRect(
112 0, -slideBarHeight/2,
113 slideBarWidth, slideBarHeight,
114 color(0,0,0), c.col);
115
116 translate(slideBarWidth*c.valueDragging, 0);
117 stroke(255);
118 line(0, -slideBarHeight/2, 0, slideBarHeight/2);
119 }
120 popMatrix();
121 }
122 }
123
124 void gradientRect(int l, int t, int w, int h, color c1, color c2) {
125 for (int x=l; x<w; x++) {
126 float inter = map(x, l, l+w, 0, 1);
127 color c = lerpColor(c1, c2, inter);
128 stroke(c);
129 line(x, t, x, t+h);
130 }
131 }
См.также
- Esplora Library
Внешние ссылки