Проект родился из желания научится управлять устройствами, подключенными к Arduino с помощью компьютера. Так получилось, что на глаза попался сайт LuckyLarry (www.luckyLarry.co.uk) – правда совсем по другому поводу – подключение Kinect к компьютеру через USB (кстати – подключить удалось, приобретя блок питания и переходник с кинектовского USB на обычный). Там же на глаза попалась статья о управлении Arduino c ПК (http://luckylarry.co.uk/arduino-projects/using-processing-to-send-values-to-arduino/ ) и путем его несложной трансформации получился простой проект решения поставленной цели.
Итого использованные компоненты:
1х arduino Nano
3х светодиоды
1х макетная плата
Скетч для ардуино:
/* Sets LED values based on values sent on the serial port from Processing application.
luckylarry.co.uk
modified 2012 andrey surkov
*/
// create an array of LED pins – need to be the PWM digital pins
int ledPin[] = {9,10,11};
// array to store the 3 values from the serial port
int incomingByte[3];
void setup() {
// initialize serial communication – make sure its the same as expected in the processing code
Serial.begin(9600);
// loop through and set the pins as outputs
for (int i=0; i analogWrite(ledPin[i], incomingByte[i]);
}
}
}
Скетч для processing
/*
Code by Lucky Larry: www.luckylarry.co.uk
RGB visualisation to control LED’s by dragging sliders to define colour
Copyright (C) 2009 Pete Dainty aka ‘Lucky Larry’
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see.
Also makes use of gradient drawing code found at: http://processing.org/learning/basics/lineargradient.html
*/
// import the serial library to allow us to send data via the serial ports (USB in this case)
import processing.serial.*;
// create a new instance of the serial classes and assign it to ‘myPort’
Serial myPort;
// create set of variables to store vector infomation (X nd Y co-oordinates)
PVector redSlider,greenSlider,blueSlider,whichSlider,lockSliders;
// create an arry to store the vectors of each slider
PVector sliders[];
// boolean value (true or false) to store if lock sliders button has been clicked
boolean locked;
// values needed for gradient code
int Y_AXIS = 1;
int X_AXIS = 2;
// setup our font
PFont myFont;
void setup() {
// screen size
size(300,315);
// setup my font type and size
myFont = createFont(«verdana», 10);
textFont(myFont);
// specifiy the co-ordinates for each slider, the lock sliders button
redSlider = new PVector(50,150);
greenSlider = new PVector(110,150);
blueSlider = new PVector(170,150);
lockSliders = new PVector(12,27);
// setup an array to store the values of each slider
sliders = new PVector[] {redSlider,greenSlider,blueSlider};
// smooth shapes
smooth();
/* define which port to use mine is COM10 and is 2nd in the array list.
you can print out to the screen which ports are accessible by using this code line below
set the baud rate to the same as in your Arduino code so mine is 9600
*/
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
} // end setup
void draw() {
// set background colour to grey in case the setGradient code fails
background(50);
// set outlines of shapes to be black
stroke(0);
/* creates a rectangle shape based up on X and Y co-ords,
width and height, 2 RGB values to the colours to mix and which
axis to apply the gradient.
*/
color b1 = color(130, 130, 130);
color b2 = color(70, 70, 70);
setGradient(0, 0, width, height, b1, b2, Y_AXIS);
// set the backgrounds of our slider columns
color sliderGrad1 = color(120, 120, 120);
color sliderGrad2 = color(50, 50, 50);
setGradient(25, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
setGradient(85, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
setGradient(145, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
noFill();
rectMode(CENTER);
// draw the outlines of each column and a guide line in the center
rect(50,160,50,275);
rect(110,160,50,275);
rect(170,160,50,275);
line(50,30,50,285);
line(110,30,110,285);
line(170,30,170,285);
// loop through 25 times to produce 25 measurement lines and measurements
for (int i=0; i stroke(30);
// first column
line(46,30+(i*10),54,30+(i*10));
// second column
line(106,30+(i*10),114,30+(i*10));
// third column
line(166,30+(i*10),174,30+(i*10));
// right hand gauge and measurement numbers
fill(40);
stroke(40);
line(196,30+(i*10),201,30+(i*10));
text(Integer.toString(i*10),216,35+(i*10),25,25);
}
// draw the sliders – one for each item in the sliders array
for (int i=0; i fill(50);
stroke(0);
rect(sliders[i].x,sliders[i].y,40,10);
}
// display text at top of columns.
text(«RED»,50,20,50,25);
text(«GREEN»,110,20,50,25);
text(«BLUE»,170,20,50,25);
text(«COLOUR»,260,20,50,25);
// rotate the lock sliders text using pushMatrix and opMatrix to isolate the transformation
// so that it doesn’t affect everything else
pushMatrix();
translate(-33,155);
rotate(radians(270));
text(«Lock Sliders»,100,50,100,25);
popMatrix();
// draw the rectangle button for locking sliders
fill(255);
rect(lockSliders.x,lockSliders.y,10,10);
fill(0);
// if locked is true then change the button to show its active.
if(locked) {
text(«X»,19,30,20,20);
}
// create 3 circles for each colour which will change depending on the slider
fill(int(redSlider.y),0,0);
ellipse(70,15,10,10);
fill(0,int(greenSlider.y),0);
ellipse(130,15,10,10);
fill(0,0,int(blueSlider.y));
ellipse(190,15,10,10);
// create a colour square to show the current mixed colour
fill(int(redSlider.y),int(greenSlider.y),int(blueSlider.y));
rect(260,32,50,20);
// display text at bottom of each column to show slider value (0-255)
fill(40);
text(Integer.toString(int(round(redSlider.y))-31),65,310,50,25);
text(Integer.toString(int(round(greenSlider.y))-31),125,310,50,25);
text(Integer.toString(int(round(blueSlider.y))-31),185,310,50,25);
/* we need to send this fill value to the Arduino to light up the LED’s accordingly
we do this by writing a value to the serial port
You can write values to the serial port using bytes, integers and chars.
I’m going to send the 3 values separately and store them in an array on the Arduino
*/
myPort.write(int(round(redSlider.y))-31);
myPort.write(int(round(greenSlider.y))-31);
myPort.write(int(round(blueSlider.y))-31);
}
/* when the mouse is pressed check if its within the slider area (40×20)
If the mouse is in/on a slider then set the Y value of PVector whichSlider to this value
So we know when dragging the mouse which slider to move.
*/
void mousePressed() {
// always set to null unless the mouse is inside the handle area
whichSlider = null;
for (int i=0; i if (sliders[i].x-20 < mouseX && sliders[i].x+20 > mouseX &&
sliders[i].y-10 < mouseY && sliders[i].y+10 > mouseY) {
whichSlider = sliders[i];
}
}
// check to see if the mouse is clicked inside the lock sliders button
if (lockSliders.x-5 < mouseX && lockSliders.x+5 > mouseX &&
lockSliders.y-5 < mouseY && lockSliders.y+5 > mouseY) {
// if so then check the current state and set our boolean to the opposite value
if(locked) {
locked = false;
} else {
locked = true;
}
}
}
/* If the mouse is pressed and the value of whichSlider is not null – it will be null if the mouse is outside the slider area.
Then look to see if the mouseY is in range, so we dont want it to exceed a scale of 255
Then look to see if the sliders are locked, if they are then set all sliders to the mouse Y
*/
void mouseDragged() {
if (whichSlider != null)
{
if(mouseY > 30 && mouseY < 287 ) {
// set the Y value of the slider
if(!locked) {
whichSlider.y = mouseY;
} else {
for(int i=0; i sliders[i].y = mouseY;
}
}
}
}
}
/* following gradient code taken from:
http://processing.org/learning/basics/lineargradient.html
*/
void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ){
// calculate differences between color components
float deltaR = red(c2)-red(c1);
float deltaG = green(c2)-green(c1);
float deltaB = blue(c2)-blue(c1);
// choose axis
if(axis == Y_AXIS){
/*nested for loops set pixels
in a basic table structure */
// column
for (int i=x; i // row
for (int j = y; j color c = color(
(red(c1)+(j-y)*(deltaR/h)),
(green(c1)+(j-y)*(deltaG/h)),
(blue(c1)+(j-y)*(deltaB/h))
);
set(i, j, c);
}
}
}
else if(axis == X_AXIS){
// column
for (int i=y; i // row
for (int j = x; j color c = color(
(red(c1)+(j-x)*(deltaR/h)),
(green(c1)+(j-x)*(deltaG/h)),
(blue(c1)+(j-x)*(deltaB/h))
);
set(j, i, c);
}
}
}
}