Arduino Ethernet PoC WEB-styrd RGB, med kod!

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
007sweden
Inlägg: 3500
Blev medlem: 3 mars 2005, 20:18:12
Skype: oo7sweden

Arduino Ethernet PoC WEB-styrd RGB, med kod!

Inlägg av 007sweden »



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);
}
Web nedanför, först index.html:

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>
Javascriptet, OBS att smärre förbättringar kan göras, för närvarande är länkarna hårdkodade i ajax-anropen, sök efter example.com.
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%;
}
jQuery.js är standard jQuery JavaScript Library v1.6.1.


Så, vad tycker ni? :)
Användarvisningsbild
swapper
Inlägg: 1076
Blev medlem: 14 augusti 2012, 23:18:15
Ort: Helsingborg

Re: Arduino Ethernet PoC WEB-styrd RGB, med kod!

Inlägg av swapper »

Det var snyggt!
Har varit lite inne på att labba med HTML5 och Arduino ett tag, retar mig dock på att alla lösningar verkar innefatta att man kör koden för sidan på en annan server, skulle vilja klämma in det på arduinon så det blir en egen enhet.
Men antar att det blir för mkt kod.

Vet du om sidan du får upp fungerar på en iphone eller dyl som kan läsa html5 ?
Användarvisningsbild
007sweden
Inlägg: 3500
Blev medlem: 3 mars 2005, 20:18:12
Skype: oo7sweden

Re: Arduino Ethernet PoC WEB-styrd RGB, med kod!

Inlägg av 007sweden »

Man skulle kunna klämma in det på arduinon om man använder sd-kortplatsen, vet dock inte hur mycket extra utrymme som krävs för det kodmässigt.


Testade med min Sony Xperia U, kör android 4.0.3. Den klarar det galant.
Skriv svar