Arduino:Примеры/EsploraRemote

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Перевел 364226 статей для сайта.</br>Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Удаленное управление и тестирование Esplora[1]

Этот пример создан, чтобы работать вместе с приложением на языке Processing (это язык программирования с открытым кодом). Вам нужно будет установить это приложение на компьютер, чтобы с его помощью, во-первых, считывать данные с датчиков Esplora, а во-вторых, управлять RGB-светодиодом и зуммером Esplora. Кроме того, графический интерфейс в скетче Processing будет представлять собой виртуальную копию вашей Esplora.

Если Processing на вашем компьютере нет, этот пример можно протестировать и при помощи окна Serial Monitor, взаимодействуя с Esplora при помощи специальных интерактивных команд, отсылаемых через последовательный порт.

С этим примером может работать два скетча Processing (ссылки на них можно найти ниже). Первый (попроще, для начинающих Processing-программистов) выводит данные от датчиков в текстовом виде, тогда как второй (посложнее, для продвинутых) демонстрирует графическую репрезентацию Esplora.

В этом ZIP-файле содержится тот скетч, что попроще, а в этом – что посложнее(также с кодом можно ознакомиться ниже).

Вам лишь нужно распаковать файл внутри папки скетчей Processing, а затем запустить саму Processing и открыть в ней файл с расширением *.pde.

Необходимое оборудование

  • Плата Arduino Esplora;

Необходимое ПО

Цепь

Для этого примера нужна лишь Arduino Esplora.

Esplora Slave.png

Расположение элементов 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 }

См.также

  1. Esplora Library

Внешние ссылки