Node.js Raspberry Pi RGB LED met WebSocket
Gebruik polswydte-modulasie
In die vorige hoofstukke het ons geleer hoe om WebSocket te gebruik, en hoe om GPIO te gebruik om LED's aan en af te skakel.
In hierdie sal ons hoofstuk gebruik ons gebruik 'n RGB LED, met PWM (Pulse-width modulation) om verskillende kleure te vertoon gebaseer op gebruikersinvoer via WebSocket.
'n RGB LED is 'n LED met 3 verskillende kleure. Dit het 'n ROOI, GROEN en BLOU LED (RGB LED).
En met PWM kan ons die individuele sterkte van die 3 LED's stel. Dit sal ons toelaat om hulle te meng, om 'n kleur te stel.
Wat het ons nodig?
In hierdie hoofstuk sal ons 'n voorbeeld skep waar ons 'n RGB LED met 'n webblad via WebSocket beheer.
Hiervoor benodig jy:
- 'n Raspberry Pi met Raspian, internet, SSH, met Node.js geïnstalleer
- Die pigpio-module vir Node.js
- Die socket.io-module vir Node.js
- 1 x Broodbord
- 3 x 220 Ohm weerstand
- 1 x RGB LED (gewone anode of gemeenskaplike katode)
- 4 x vroulike tot manlike jumper drade
Klik op die skakels in die lys hierbo vir beskrywings van die verskillende komponente.
Let wel: Die weerstand wat u benodig, kan verskil van wat ons gebruik, afhangende van die tipe LED wat u gebruik. Die meeste klein LED's benodig net 'n klein weerstand, ongeveer 200-500 ohm. Dit is oor die algemeen nie krities watter presiese waarde jy gebruik nie, maar hoe kleiner die waarde van die weerstand, hoe helderder sal die LED skyn.
Installeer die pigpio-module
Ons het vroeër die "aan-af"-module gebruik, wat uitstekend werk om net aan en af te skakel. Nou wil ons die stel die sterkte van die LED's stel, so ons benodig 'n GPIO-module met 'n bietjie meer funksionaliteit.
Ons sal die "pigpio" Node.js-module gebruik, aangesien dit PWM toelaat.
Met PWM kan ons die sterkte van 'n LED van 0 tot 255 stel.
Die "pigpio" Node.js-module is gebaseer op die pigpio C-biblioteek.
As jy die "Lite" weergawe van Raspbian gebruik, is dit heel waarskynlik nie ingesluit nie en moet met die hand geïnstalleer word.
Dateer jou stelselpakketlys op:
pi@w3demopi:~ $ sudo apt-get update
Installeer die pigpio C-biblioteek:
pi@w3demopi:~ $ sudo apt-get install pigpio
Nou kan ons die "pigpio" Node.js-module installeer deur npm te gebruik:
pi@w3demopi:~ $ npm install pigpio
Nou moet die "pigpio"-module geïnstalleer word en ons kan dit gebruik om met die GPIO van die Raspberry Pi te kommunikeer.
Let wel: Aangesien die "pigpio"-module die pigpio C-biblioteek gebruik, vereis dit root/sudo-regte om toegang tot hardeware-randapparatuur (soos die GPIO) te verkry.
Bou die kring
Nou is dit tyd om die kring op ons Broodbord te bou.
As jy nuut is met elektronika, beveel ons aan dat jy die krag vir die Raspberry Pi afskakel. En gebruik 'n anti-statiese mat of 'n grondband om te verhoed dat dit beskadig word.
Skakel die Raspberry Pi behoorlik af met die opdrag:
pi@w3demopi:~ $ sudo shutdown -h now
Nadat die LED's op die Raspberry Pi ophou flikker, trek dan die kragprop uit die Raspberry Pi (of draai die kragstrook waaraan dit gekoppel is) uit.
Deur net die prop te trek sonder om behoorlik af te skakel, kan die geheuekaart beskadig word.
By die bou van hierdie stroombaan is dit belangrik om te weet of jy 'n gemeenskaplike anode, of gemeenskaplike katode, RGB LED het:
Jy kan by jou verskaffer nagaan, of dit self toets:
Koppel kabels aan GND en 3.3V pen. Koppel GND aan die langste been van die RGB LED en die 3,3 V aan enige ander been. As dit brand, het jou RGB LED 'n gemeenskaplike katode. Indien nie, het dit 'n gemeenskaplike anode.
Kyk na die bostaande illustrasie van die stroombaan.
- On the Breadboard, connect the RGB LED to the right ground bus column, and make sure that each leg connects to a different row. The longest leg is the common cathode leg. In this example we have connected the LED to rows 1-4, with the common cathode leg connected to row 2 column I. The RED leg is connected to row 1 column J, the GREEN leg is connected to row 3 column J, and the BLUE leg is connected to row 4 column J
- On the Raspberry Pi, connect the female leg of the first jumper wire to Ground. You can use any GND pin. In this example we used Physical Pin 9 (GND, row 5, left column)
- On the Breadboard, connect the male leg of the first jumper wire to the same row of the right ground bus column that you connected the common cathode to. In this example we connected it to row 2 column F
- On the Raspberry Pi, connect the female leg of the second jumper cable to a GPIO pin. We will use this for the RED leg, In this example we used Physical Pin 7 (GPIO 4, row 4, left column)
- On the Breadboard, connect the male leg of the second jumper wire to the left ground bus, same row as the RED leg of the LED is connected. In this example we connected it to row 1, column A
- On the Breadboard, connect a resistor between the left and right ground bus columns for the row with the RED leg of the LED. In this example we have attached it to row 1, column E and F
- On the Raspberry Pi, connect the female leg of the third jumper cable to a GPIO pin. We will use this for the GREEN leg, In this example we used Physical Pin 11 (GPIO 17, row 6, left column)
- On the Breadboard, connect the male leg of the third jumper wire to the left ground bus, same row as the GREEN leg of the LED is connected. In this example we connected it to row 3, column A
- On the Breadboard, connect a resistor between the left and right ground bus columns for the row with the GREEN leg of the LED. In this example we have attached it to row 3, column E and F
- On the Raspberry Pi, connect the female leg of the forth jumper cable to a GPIO pin. We will use this for the BLUE leg, In this example we used Physical Pin 13 (GPIO 27, row 7, left column)
- On the Breadboard, connect the male leg of the forth jumper wire to the left ground bus, same row as the BLUE leg of the LED is connected. In this example we connected it to row 4, column A
- Op die Broodbord, verbind 'n weerstand tussen die linker- en regtergrondbuskolomme vir die ry met die BLOU been van die LED. In hierdie voorbeeld het ons dit aan ry 4, kolom E en F geheg
Jou stroombaan behoort nou voltooi te wees, en jou verbindings behoort redelik soortgelyk aan die illustrasie hierbo te lyk.
Nou is dit tyd om die Raspberry Pi op te laai en die Node.js-skrip te skryf om daarmee te kommunikeer.
Kyk na die bostaande illustrasie van die stroombaan.
- On the Breadboard, connect the RGB LED to the right ground bus column, and make sure that each leg connects to a different row. The longest leg is the common anode leg. In this example we have connected the LED to rows 1-4, with the common cathode leg connected to row 2 column I. The RED leg is connected to row 1 column J, the GREEN leg is connected to row 3 column J, and the BLUE leg is connected to row 4 column J
- On the Raspberry Pi, connect the female leg of the first jumper cable to a GPIO pin. We will use this for the RED leg, In this example we used Physical Pin 7 (GPIO 4, row 4, left column)
- On the Breadboard, connect the male leg of the first jumper wire to the left ground bus, same row as the RED leg of the LED is connected. In this example we connected it to row 1, column A
- On the Breadboard, connect a resistor between the left and right ground bus columns for the row with the RED leg of the LED. In this example we have attached it to row 1, column E and F
- On the Raspberry Pi, connect the female leg of the second jumper cable to a GPIO pin. We will use this for the GREEN leg, In this example we used Physical Pin 11 (GPIO 17, row 6, left column)
- On the Breadboard, connect the male leg of the second jumper wire to the left ground bus, same row as the GREEN leg of the LED is connected. In this example we connected it to row 3, column A
- On the Breadboard, connect a resistor between the left and right ground bus columns for the row with the GREEN leg of the LED. In this example we have attached it to row 3, column E and F
- On the Raspberry Pi, connect the female leg of the third jumper cable to a GPIO pin. We will use this for the BLUE leg, In this example we used Physical Pin 13 (GPIO 27, row 7, left column)
- On the Breadboard, connect the male leg of the third jumper wire to the left ground bus, same row as the BLUE leg of the LED is connected. In this example we connected it to row 4, column A
- On the Breadboard, connect a resistor between the left and right ground bus columns for the row with the BLUE leg of the LED. In this example we have attached it to row 4, column E and F
- On the Raspberry Pi, connect the female leg of the forth jumper wire to 3.3V. In this example we used Physical Pin 1 (3.3V, row 1, left column)
- Op die broodbord, koppel die manlike been van die vierde springdraad aan dieselfde ry van die regtergrondbuskolom waaraan jy die gemeenskaplike anode gekoppel het. In hierdie voorbeeld het ons dit gekoppel aan ry 2 kolom F
Jou stroombaan behoort nou voltooi te wees, en jou verbindings behoort redelik soortgelyk aan die illustrasie hierbo te lyk.
Nou is dit tyd om die Raspberry Pi op te laai en die Node.js-skrip te skryf om daarmee te kommunikeer.
Raspberry Pi en Node.js RGB LED en WebSocket Script
Gaan na die "nodetest" gids, en skep 'n nuwe lêer genaamd " rgbws.js
":
pi@w3demopi:~ $ nano rgbws.js
Die lêer is nou oop en kan geredigeer word met die ingeboude Nano Editor.
Skryf, of plak die volgende:
rgbws.js
var http = require('http').createServer(handler); //require http server, and
create server with function handler()
var fs = require('fs'); //require
filesystem module
var io = require('socket.io')(http) //require socket.io
module and pass the http object (server)
var Gpio = require('pigpio').Gpio,
//include pigpio to interact with the GPIO
ledRed = new Gpio(4, {mode:
Gpio.OUTPUT}), //use GPIO pin 4 as output for RED
ledGreen = new Gpio(17,
{mode: Gpio.OUTPUT}), //use GPIO pin 17 as output for GREEN
ledBlue = new
Gpio(27, {mode: Gpio.OUTPUT}), //use GPIO pin 27 as output for BLUE
redRGB
= 0, //set starting value of RED variable to off (0 for common cathode)
greenRGB = 0, //set starting value of GREEN variable to off (0 for common
cathode)
blueRGB = 0; //set starting value of BLUE variable to off (0 for
common cathode)
//RESET RGB LED
ledRed.digitalWrite(0); // Turn RED
LED off
ledGreen.digitalWrite(0); // Turn GREEN LED off
ledBlue.digitalWrite(0); // Turn BLUE LED off
http.listen(8080);
//listen to port 8080
function handler (req, res) { //what to do on
requests to port 8080
fs.readFile(__dirname + '/public/rgb.html',
function(err, data) { //read file rgb.html in public folder
if (err) {
res.writeHead(404,
{'Content-Type': 'text/html'}); //display 404 on error
return res.end("404 Not Found");
}
res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
res.write(data); //write data from rgb.html
return
res.end();
});
}
io.sockets.on('connection', function
(socket) {// Web Socket Connection
socket.on('rgbLed',
function(data) { //get light switch status from client
console.log(data); //output data from WebSocket connection to console
//for common cathode RGB LED 0 is fully off, and 255 is fully on
redRGB=parseInt(data.red);
greenRGB=parseInt(data.green);
blueRGB=parseInt(data.blue);
ledRed.pwmWrite(redRGB); //set RED LED to specified
value
ledGreen.pwmWrite(greenRGB); //set GREEN LED to
specified value
ledBlue.pwmWrite(blueRGB); //set BLUE
LED to specified value
});
});
process.on('SIGINT',
function () { //on ctrl+c
ledRed.digitalWrite(0); // Turn RED LED
off
ledGreen.digitalWrite(0); // Turn GREEN LED off
ledBlue.digitalWrite(0); // Turn BLUE LED off
process.exit(); //exit
completely
});
Druk " Ctrl+x
" om die kode te stoor. Bevestig met " y
", en bevestig die naam met " Enter
".
Skryf, of plak die volgende:
rgbws.js
var http = require('http').createServer(handler); //require http server, and
create server with function handler()
var fs = require('fs'); //require
filesystem module
var io = require('socket.io')(http) //require socket.io
module and pass the http object (server)
var Gpio = require('pigpio').Gpio,
//include pigpio to interact with the GPIO
ledRed = new Gpio(4, {mode:
Gpio.OUTPUT}), //use GPIO pin 4 as output for RED
ledGreen = new Gpio(17,
{mode: Gpio.OUTPUT}), //use GPIO pin 17 as output for GREEN
ledBlue = new
Gpio(27, {mode: Gpio.OUTPUT}), //use GPIO pin 27 as output for BLUE
redRGB
= 255, //set starting value of RED variable to off (255 for common anode)
greenRGB = 255, //set starting value of GREEN variable to off (255 for common
anode)
blueRGB = 255; //set starting value of BLUE variable to off (255 for
common anode)
//RESET RGB LED
ledRed.digitalWrite(1); // Turn RED
LED off
ledGreen.digitalWrite(1); // Turn GREEN LED off
ledBlue.digitalWrite(1); // Turn BLUE LED off
http.listen(8080);
//listen to port 8080
function handler (req, res) { //what to do on
requests to port 8080
fs.readFile(__dirname + '/public/rgb.html',
function(err, data) { //read file rgb.html in public folder
if (err) {
res.writeHead(404,
{'Content-Type': 'text/html'}); //display 404 on error
return res.end("404 Not Found");
}
res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
res.write(data); //write data from rgb.html
return
res.end();
});
}
io.sockets.on('connection', function
(socket) {// Web Socket Connection
socket.on('rgbLed',
function(data) { //get light switch status from client
console.log(data); //output data from WebSocket connection to console
//for common anode RGB LED 255 is fully off, and 0 is fully on, so we
have to change the value from the client
redRGB=255-parseInt(data.red);
greenRGB=255-parseInt(data.green);
blueRGB=255-parseInt(data.blue);
console.log("rbg: "
+ redRGB + ", " + greenRGB + ", " + blueRGB); //output converted to console
ledRed.pwmWrite(redRGB); //set RED LED to specified
value
ledGreen.pwmWrite(greenRGB); //set GREEN LED to
specified value
ledBlue.pwmWrite(blueRGB); //set BLUE
LED to specified value
});
});
process.on('SIGINT',
function () { //on ctrl+c
ledRed.digitalWrite(1); // Turn RED LED
off
ledGreen.digitalWrite(1); // Turn GREEN LED off
ledBlue.digitalWrite(1); // Turn BLUE LED off
process.exit(); //exit
completely
});
Druk " Ctrl+x
" om die kode te stoor. Bevestig met " y
", en bevestig die naam met " Enter
".
Raspberry Pi en Node.js WebSocket UI
Nou is dit tyd om die HTML by te voeg wat gebruikersinvoer via WebSocket toelaat.
Hiervoor wil ons:
- 3 kleurglyers, een vir elke kleur (RGB)
- 'n Kleurkieser
- 'n Div wat die huidige kleur wys
Gaan na die gids "publiek":
pi@w3demopi:~/nodetest $
cd public
En skep 'n HTML-lêer, rgb.html:
pi@w3demopi:~/nodetest/public $
nano rgb.html
rgb.html:
<!DOCTYPE html>
<html>
<meta name="viewport"
content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://www.w3schools.com/w3css/4/w3.css">
<style>
.slider {
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition:
opacity .2s;
}
.slider:hover {opacity: 1;}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
cursor: pointer;
}
.slider::-moz-range-thumb {
width:
25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
#redSlider::-webkit-slider-thumb {background: red;}
#redSlider::-moz-range-thumb
{background: red;}
#greenSlider::-webkit-slider-thumb {background:
green;}
#greenSlider::-moz-range-thumb {background: green;}
#blueSlider::-webkit-slider-thumb
{background: blue;}
#blueSlider::-moz-range-thumb {background: blue;}
</style>
<body>
<div class="w3-container">
<h1>RGB Color</h1>
<div class="w3-cell-row">
<div class="w3-container w3-cell w3-mobile">
<p><input type="range" min="0" max="255" value="0" class="slider" id="redSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="greenSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="blueSlider"></p>
</div>
<div class="w3-container w3-cell w3-mobile" style="background-color:black"
id="colorShow">
<div></div>
</div>
</div>
<p>Or pick a color:
<input type="color" id="pickColor"></p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://www.w3schools.com/lib/w3color.js"></script>
<script>
var socket = io(); //load socket.io-client and connect to the host that
serves the page
var rgb = w3color("rgb(0,0,0)"); //we use the w3color.js
library to keep the color as an object
window.addEventListener("load",
function(){ //when page loads
var rSlider =
document.getElementById("redSlider");
var gSlider =
document.getElementById("greenSlider");
var bSlider =
document.getElementById("blueSlider");
var picker =
document.getElementById("pickColor");
rSlider.addEventListener("change",
function() { //add event listener for when red slider changes
rgb.red = this.value; //update the RED color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current
color"
socket.emit("rgbLed", rgb); //send the updated
color to RGB LED via WebSocket
});
gSlider.addEventListener("change", function() { //add event listener for
when green slider changes
rgb.green = this.value;
//update the GREEN color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current
color"
socket.emit("rgbLed", rgb); //send the updated
color to RGB LED via WebSocket
});
bSlider.addEventListener("change", function() { //add event listener for
when blue slider changes
rgb.blue = this.value;
//update the BLUE color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current
color"
socket.emit("rgbLed", rgb); //send the updated
color to RGB LED via WebSocket
});
picker.addEventListener("input", function() { //add event listener for when
colorpicker changes
rgb.red = w3color(this.value).red;
//Update the RED color according to the picker
rgb.green = w3color(this.value).green; //Update the GREEN color according to
the picker
rgb.blue = w3color(this.value).blue;
//Update the BLUE color according to the picker
colorShow.style.backgroundColor = rgb.toRgbString(); //update the
"Current color"
rSlider.value = rgb.red;
//Update the RED slider position according to the picker
gSlider.value = rgb.green; //Update the GREEN slider position
according to the picker
bSlider.value = rgb.blue;
//Update the BLUE slider position according to the picker
socket.emit("rgbLed", rgb); //send the updated color to RGB LED via
WebSocket
});
});
</script>
</body>
</html>
Keer terug na die "nodetest"-lêergids:
pi@w3demopi:~/nodetest $
cd ..
Begin die kode:
pi@w3demopi:~ $ sudo node rgbws.js
Let wel: Aangesien die "pigpio"-module die pigpio C-biblioteek gebruik, vereis dit root/sudo-regte om toegang tot hardeware-randapparatuur (soos die GPIO) te verkry.
Maak die webwerf in 'n blaaier oop met http://[RaspberryPi_IP]:8080/
Nou moet die RGB-LED van kleur verander na gelang van die gebruikerinvoer.
Beëindig die program met Ctrl+c
.