Gjorde ett Proof of Concept lite snabbt, det ovan blev resultatet.
Använder Webduino, och typ två ihopsatta exempel från den.
Web-delen hostas för närvarande på min server, styrkommando skickas via POST-requests till arduinon, och live-rutan pollar regelbundet arduinon som skickar ut JSON-data med färgernas värde, allt är 0-255.
Web-delen kommer från en modifierad version av denna:html5-color-picker-canvas
Har inte kommenterat koden särskilt mycket, men pastear in den här under för dem som vill se.
Arduino:
Kod: Markera allt
/* Web_AjaxRGB.pde - example sketch for Webduino library */
#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"
// CHANGE THIS TO YOUR OWN UNIQUE VALUE
static uint8_t mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
/* all URLs on this server will start with /rgb because of how we
* define the PREFIX value. We also will listen on port 80, the
* standard HTTP service port */
#define PREFIX "/rgb"
WebServer webserver(PREFIX, 8080);
#define RED_PIN 6
#define GREEN_PIN 5
#define BLUE_PIN 9
int red = 0; //integer for red darkness
int blue = 0; //integer for blue darkness
int green = 0; //integer for green darkness
// no-cost stream operator as described at
// http://sundial.org/arduino/?page_id=119
template<class T>
inline Print &operator <<(Print &obj, T arg)
{ obj.print(arg); return obj; }
/* This command is set as the default command for the server. It
* handles both GET and POST requests. For a GET, it returns a simple
* page with some buttons. For a POST, it saves the value posted to
* the red/green/blue variable, affecting the output of the speaker */
void rgbCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
if (type == WebServer::POST)
{
bool repeat;
char name[16], value[16];
do
{
/* readPOSTparam returns false when there are no more parameters
* to read from the input. We pass in buffers for it to store
* the name and value strings along with the length of those
* buffers. */
repeat = server.readPOSTparam(name, 16, value, 16);
/* this is a standard string comparison function. It returns 0
* when there's an exact match. We're looking for a parameter
* named red/green/blue here. */
if (strcmp(name, "red") == 0)
{
/* use the STRing TO Unsigned Long function to turn the string
* version of the color strength value into our integer red/green/blue
* variable */
red = strtoul(value, NULL, 10);
}
if (strcmp(name, "green") == 0)
{
green = strtoul(value, NULL, 10);
}
if (strcmp(name, "blue") == 0)
{
blue = strtoul(value, NULL, 10);
}
} while (repeat);
// after procesing the POST data, tell the web browser to reload
// the page using a GET method.
server.httpSeeOther(PREFIX);
// Serial.print(name);
// Serial.println(value);
return;
}
/* for a GET or HEAD, send the standard "it's all OK headers" */
server.httpSuccess();
/* we don't output the body for a HEAD request */
if (type == WebServer::GET)
{
/* store the HTML in program memory using the P macro */
P(message) =
"<!DOCTYPE html><html><head>"
"<title>Webduino AJAX RGB Example</title>"
"<link href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css' rel=stylesheet />"
"<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>"
"<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js'></script>"
"<style> body { background: black; } #red, #green, #blue { margin: 10px; } #red { background: #f00; } #green { background: #0f0; } #blue { background: #00f; } </style>"
"<script>"
// change color on mouse up, not while sliding (causes much less traffic to the Arduino):
// "function changeRGB(event, ui) { var id = $(this).attr('id'); if (id == 'red') $.post('/rgb', { red: ui.value } ); if (id == 'green') $.post('/rgb', { green: ui.value } ); if (id == 'blue') $.post('/rgb', { blue: ui.value } ); } "
// "$(document).ready(function(){ $('#red, #green, #blue').slider({min: 0, max:255, change:changeRGB}); });"
// change color on slide and mouse up (causes more traffic to the Arduino):
"function changeRGB(event, ui) { jQuery.ajaxSetup({timeout: 110}); /*not to DDoS the Arduino, you might have to change this to some threshold value that fits your setup*/ var id = $(this).attr('id'); if (id == 'red') $.post('/rgb', { red: ui.value } ); if (id == 'green') $.post('/rgb', { green: ui.value } ); if (id == 'blue') $.post('/rgb', { blue: ui.value } ); } "
"$(document).ready(function(){ $('#red, #green, #blue').slider({min: 0, max:255, change:changeRGB, slide:changeRGB}); });"
"</script>"
"</head>"
"<body style='font-size:62.5%;'>"
"<div id=red></div>"
"<div id=green></div>"
"<div id=blue></div>"
"</body>"
"</html>";
server.printP(message);
}
}
void jsonCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
if (type == WebServer::POST)
{
server.httpFail();
return;
}
//server.httpSuccess(false, "application/json");
server.httpSuccess("application/json");
if (type == WebServer::HEAD)
return;
int i;
server << "{ ";
server << "\"red\": " << red << ", ";
server << "\"green\": " << green << ", ";
server << "\"blue\": " << blue;
server << " }";
}
void setup()
{
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
//Serial.begin(9600);
// setup the Ehternet library to talk to the Wiznet board
Ethernet.begin(mac);
/* register our default command (activated with the request of
* http://x.x.x.x/rgb */
webserver.setDefaultCommand(&rgbCmd);
webserver.addCommand("json", &jsonCmd);
/* start the server to wait for connections */
webserver.begin();
}
void loop()
{
// process incoming connections one at a time forever
webserver.processConnection();
//Serial.print(red);
//Serial.print(" ");
//Serial.print(green);
//Serial.print(" ");
//Serial.println(blue);
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
}
Kod: Markera allt
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>Duino-Color</title>
<!-- add styles -->
<link href="css/main.css" rel="stylesheet" type="text/css" />
<!-- add scripts -->
<script src="js/jquery.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<div class="container">
<!-- colorpicker element -->
<div class="colorpicker" style="display:true">
<canvas id="picker" var="4" width="300" height="300"></canvas>
<div class="controls">
<div><label>R</label> <input type="text" id="rVal" /></div>
<div><label>G</label> <input type="text" id="gVal" /></div>
<div><label>B</label> <input type="text" id="bVal" /></div>
<div><label>RGB</label> <input type="text" id="rgbVal" /></div>
<div><label>HEX</label> <input type="text" id="hexVal" /></div>
<div class="preview">Preview</div>
<div class="live">Live</div>
<div><select name="colorpick" size="1" id="colorpick">
<option value=1>Wheel1</option>
<option value=2>Wheel2</option>
<option value=3>Wheel3</option>
<option value=4>Wheel4</option>
<option value=5>Wheel5</option>
</select></div>
</div>
</div>
</div>
</body>
</html>
script.js
Kod: Markera allt
/**
*
* HTML5 Color Picker
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2012, Script Tutorials
* http://www.script-tutorials.com/
*/
$(function(){
var bCanPreview = true; // can preview
// create canvas and context objects
var canvas = document.getElementById('picker');
var ctx = canvas.getContext('2d');
// drawing active image
var image = new Image();
image.onload = function () {
ctx.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
}
// select desired colorwheel
var imageSrc = 'images/colorwheel1.png';
switch ($(canvas).attr('var')) {
case '2':
imageSrc = 'images/colorwheel2.png';
break;
case '3':
imageSrc = 'images/colorwheel3.png';
break;
case '4':
imageSrc = 'images/colorwheel4.png';
break;
case '5':
imageSrc = 'images/colorwheel5.png';
break;
}
image.src = imageSrc;
$('#picker').mousemove(function(e) { // mouse move handler
if (bCanPreview) {
// get coordinates of current position
var canvasOffset = $(canvas).offset();
var canvasX = Math.floor(e.pageX - canvasOffset.left);
var canvasY = Math.floor(e.pageY - canvasOffset.top);
// get current pixel
var imageData = ctx.getImageData(canvasX, canvasY, 1, 1);
var pixel = imageData.data;
// update preview color
var pixelColor = "rgb("+pixel[0]+", "+pixel[1]+", "+pixel[2]+")";
$('.preview').css('backgroundColor', pixelColor);
// update controls
$('#rVal').val(pixel[0]);
$('#gVal').val(pixel[1]);
$('#bVal').val(pixel[2]);
$('#rgbVal').val(pixel[0]+','+pixel[1]+','+pixel[2]);
var dColor = pixel[2] + 256 * pixel[1] + 65536 * pixel[0];
$('#hexVal').val('#' + ('0000' + dColor.toString(16)).substr(-6));
}
});
$('#picker').click(function(e) { // click event handler
changeRGB();
});
var updateColors = function(){
$.getJSON(
/*dataType: "jsonp",*/
"http://example.com:8080/rgb/json",
function(json) {
// update preview color
var pixelColor = "rgb("+json.red+", "+json.green+", "+json.blue+")";
$('.live').css('backgroundColor', pixelColor);
}
);
}
setInterval(updateColors,1000);
$('#colorpick').change(function(e) { // click event handler
var canvas = document.getElementById('picker');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// drawing active image
var image = new Image();
image.onload = function () {
ctx.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
}
// select desired colorwheel
switch ($('#colorpick').val()) {
case '1':
var imageSrc = 'images/colorwheel1.png';
break;
case '2':
var imageSrc = 'images/colorwheel2.png';
break;
case '3':
var imageSrc = 'images/colorwheel3.png';
break;
case '4':
var imageSrc = 'images/colorwheel4.png';
break;
case '5':
var imageSrc = 'images/colorwheel5.png';
break;
}
var image = new Image();
image.src = imageSrc;
image.onload = function () {
ctx.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
}
});
});
function changeRGB() {
$.ajaxSetup({
timeout: 400
}); /*not to DDoS the Arduino, you might have to change this to some threshold value that fits your setup*/
/*red = $('#rVal').value; */
red = document.getElementById("rVal").value;
green = document.getElementById("gVal").value;
blue = document.getElementById("bVal").value;
$.post('http://example.com:8080/rgb', {
red: red,
green: green,
blue: blue
});
}
Och css-filen.
main.css
Kod: Markera allt
* {
margin: 0;
padding: 0;
}
html {
background-color: #eee;
}
header {
background-color:rgba(33, 33, 33, 0.9);
color:#fff;
display:block;
font: 14px/1.3 Arial,sans-serif;
height:50px;
position:relative;
}
header h2{
font-size: 22px;
margin: 0px auto;
padding: 10px 0;
width: 80%;
text-align: center;
}
header a, a:visited {
text-decoration:none;
color:#fcfcfc;
}
.container {
margin: 20px auto;
text-align: justify;
width: 600px;
}
.jtv_player_div {
margin: 20px auto;
position: center;
}
/* colorpicker styles */
.colorpicker {
background-color: #222222;
border-radius: 5px 5px 5px 5px;
box-shadow: 2px 2px 2px #444444;
color: #FFFFFF;
font-size: 12px;
position: absolute;
width: 460px;
}
#picker {
cursor: crosshair;
float: left;
margin: 10px;
border: 0;
}
.controls {
float: right;
margin: 10px;
}
.controls > div {
border: 1px solid #2F2F2F;
margin-bottom: 5px;
overflow: hidden;
padding: 5px;
}
.controls label {
float: left;
}
.controls > div input {
background-color: #121212;
border: 1px solid #2F2F2F;
color: #DDDDDD;
float: right;
font-size: 10px;
height: 14px;
margin-left: 6px;
text-align: center;
text-transform: uppercase;
width: 75px;
}
.preview {
/*background: url("../images/select.png") repeat scroll center center transparent;*/
border-radius: 3px;
box-shadow: 2px 2px 2px #444444;
cursor: pointer;
height: 40px;
width: 90%;
}
.live{
/*background: url("../images/select.png") repeat scroll center center transparent;*/
border-radius: 3px;
box-shadow: 2px 2px 2px #444444;
cursor: pointer;
height: 40px;
width: 90%;
}
Så, vad tycker ni?
