Level 3: Control an RGB LED
Using Arduino and Socket.io


Setting up the Project Directory for a Web App

We will now create a webpage and a server file to control the LED using Express and Socket.io.

  1. Create a new project directory and enter the new project directory.
    • New-Item -Path .\Project -ItemType Directory
    • cd Project
    • yarn init -y
  2. Create an HTML file, a CSS file and a JavaScript file in a new folder inside the directory.
    • New-Item -Path .\public -ItemType Directory
    • New-Item -Path .\public\index.html -ItemType File
    • New-Item -Path .\public\style.css -ItemType File
    • New-Item -Path .\public\code.js -ItemType File
  3. Create another JavaScript file in another new directory.
    • New-Item -Path .\server -ItemType Directory
    • New-Item -Path .\server\server.js -ItemType File
  4. Install the modules for Express & Socket.IO..
    • yarn add express
    • yarn add socket.io
    • A package.json file and a yarn.lock file will generated.
    • A node_modules folder will also be generated in the project directory.
  5. Install the modules for Johnny-Five & SerialPort
    • yarn add johnny-five serialport

The file directory should look like the file directory map shown.

          
Project/
├── node_modules/
├── public/
│   ├── code.js
│   ├── index.html
│   └── style.css
├── server/
│   └── server.js
├── package.json 
└── yarn.lock 
          
        

Setting Up the HTML File

The index.html file will serve as the interface for the controlling the RGB LED.

  • Open the HTML file and type "!" then "tab" to inject boilerplate template.
    • Comments can be added to HTML using <!-- comment -->.
  • Add the link to the stylesheet under the title within the <head> tags.
    • <link rel="stylesheet" href="style.css">
    • CSS can also be embeded in the <style> tags.
    • Comments can be added to a CSS file using /* comment */.
  • Add the link to the JavaScript code between the script tags in the body.
    • <script src="code.js"></script>
    • JavaScript code can be embeded in the <script> tags.
    • Comments can be added to a JavaScript file using /* comment */ or // comment.
  • Add the script tag with the link to the Socket.IO module under the title.
    • <script src="/socket.io/socket.io.js"></script>
          
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="/socket.io/socket.io.js"></script>
        <link rel="stylesheet" href="style.css">
        <style>
            /* CSS Styles */
        </style>
    </head>
    <body>
        <!-- HTML Template -->
        <script src="code.js"></script>
        <script>
            // JavaScript Code
        </script>
    </body>
    </html>
          
        

Adding the HTML template

Add the HTML template shown to the index.html file between the <body> tags.

          
    <!-- HTML Template -->
    <form>
        <fieldset>
            <legend>RGB Control</legend>
            <label for="redRange" id="redLabel">Red:</label>
            <input type="range" id="redRange" min="0" max="255" value="0"><br>
            <label for="greenRange" id="greenLabel">Green:</label>
            <input type="range" id="greenRange" min="0" max="255" value="0"><br>
            <label for="blueRange" id="blueLabel">Blue:</label>
            <input type="range" id="blueRange" min="0" max="255" value="0"><br>
            <br>
            <div id="rgbValue">rgb(0, 0, 0)</div>
            <div id="colorBox"></div>
        </fieldset>
    </form>
          
        

Adding the CSS Style Code

Open the file styles.css and insert the CSS style code shown.

          
    /* style.css */
    /* CSS Styles */
    body {
        font-family: Arial, Helvetica, sans-serif;
        font-size: 1rem;
        font-weight: bold;
        background-color: lightgray;
        color: seagreen;
    }
    fieldset {
        text-align: center;
        width: max-content;
        margin-left: auto;
        margin-right: auto;
    }
    legend {
        text-align: left;
        font-size: large;
    }
    #colorBox {
        width: 100px;
        height: 100px;
        margin-left: auto;
        margin-right: auto;
        margin-top: 10px;
        border: 2px solid darkgrey;
        border-radius: 50%;
    }
    #redLabel {
        color: red;
    }
    #greenLabel {
        color: green;
    }
    #blueLabel {
        color: blue;
    }
          
        

Adding the JavaScript Code

Open the file code.js and insert the JavaScript code shown.

          
    /* code.js */
    /* JavaScript Code */
    const redRange = document.getElementById("redRange");
    const greenRange = document.getElementById("greenRange");
    const blueRange = document.getElementById("blueRange");
    const rgbValue = document.getElementById("rgbValue");
    const colorBox = document.getElementById("colorBox");
    
    //const socket = io();
    function updateColor() {
        const red = redRange.value;
        const green = greenRange.value;
        const blue = blueRange.value;
        const rgb = `rgb(${red}, ${green}, ${blue})`;
        colorBox.style.backgroundColor = rgb;
        rgbValue.textContent = rgb;
        socket.emit('colorChange', { red:red, green:green, blue:blue });
    }
    
    redRange.addEventListener("input", updateColor);
    greenRange.addEventListener("input", updateColor);
    blueRange.addEventListener("input", updateColor);
          
        

To check if the button works, open a web browser and drag & drop the html file into a new tab.

Important Note: Remove the comment tags ("//") after testing the page on the browser.

  • const socket = io();

RGB Control




rgb(,,)


Setting Up the Express Server

Move the index.html file from the public folder to the server folder.

  • Move-Item -Path ./public/index.html -Destination ./server

The directory map should now look like the one shown below.

          
Project/
├── node_modules/
├── public/
│   ├── code.js
│   └── style.css
├── server/
│   ├── index.html
│   └── server.js
├── package.json 
└── yarn.lock 
          
        

Add the JavaScript code shown to the server.js file.

          
    /* server.js */
    const express = require('express');
    const app = express();
    const http = require('http');
    const server = http.createServer(app);
    const { Server } = require("socket.io");
    const io = new Server(server);
    const PORT = '3000';
    const { Board, Led } = require('johnny-five');
    
    const path = require('path');
    app.use(express.static(path.join(__dirname, '../public')));
    app.get('/', (req, res) => {
        res.sendFile(__dirname + '/index.html');
    });

    const board = new Board();
    board.on('ready', () => {
        console.log('Board is ready!');
        // Requires pins that support PWM (denoted by ~)
        const redPin = 11;
        const greenPin = 10;
        const bluePin = 9;
        const rgb = new Led.RGB({
            pins:{
                red:redPin,
                green:greenPin,
                blue:bluePin
            },
            isAnode: false // true if common anode
        });
        io.on('connection', function(socket) {
            console.log('connected!');
            socket.on('colorChange', function(data) {
                console.log(data);
                const { red, green, blue } = data;
                const rgbColor = [red , green, blue];
                rgb.color(rgbColor);
            });
            socket.on('disconnect', () => {
                console.log('disconnected');
            });
        });
    });
    server.listen(PORT, () => {
        console.log('Server started at http://localhost:' + PORT)
    });
            
          

Set up the RGB LED Circuit

Arduino RGB LED Circuit

Uploading the Firmata sketch using Arduino IDE

The Firmata sketch allows an Arduino board to interpret JavaScript code.

  1. Open the Arduino IDE
  2. Connect your Arduino Uno board to the USB port.
  3. Go to "File", then "Examples", then "Firmata" and select "StandardFirmata".
  4. Go to "Tools", then "Board", and select "Arduino Uno".
  5. Go to "Tools", then "Port", and select "COM#:Arduino Uno".
  6. Go to "Sketch", and select "Upload" or click the arrow button.
  7. You can close the Arduino IDE after you upload Firmata.

Running the Node.js Express Server

  • Connect the Arduino Board with the RGB LED circuit to the computer.
  • Upload the Firmata sketch to the board using Arduino IDE.
  • Run the Node.js Express server.
    • node server/server.js
    • Use "ctrl"+"c" to stop the running the server.
  • The console should display Server started at http://localhost:3000.
  • Open a web browser and go to http://localhost:3000 to view the page.
    • The console should display connected!.
    • Interact with the Arduino RGB LED circuit using the sliders.
  • In the package.json file, edit the scripts section as shown.
  • Start the server using yarn start.
          
    "scripts": {
        "start": "node server/server.js"
    }