Node.js Raspberry Pi RVB LED avec WebSocket


Utilisation de la modulation de largeur d'impulsion

Dans les chapitres précédents, nous avons appris à utiliser WebSocket et à utiliser GPIO pour allumer et éteindre les LED.

Dans ce chapitre, nous utiliserons une LED RVB, avec PWM (modulation de largeur d'impulsion) pour afficher différentes couleurs en fonction de l'entrée de l'utilisateur via WebSocket.

Une LED RVB est une LED avec 3 couleurs différentes. Il a une LED ROUGE, VERTE et BLEUE (LED RVB).

Et en utilisant PWM, nous pouvons régler la force individuelle des 3 LED. Cela nous permettra de les mélanger, de fixer une couleur.


De quoi avons nous besoin?

Dans ce chapitre, nous allons créer un exemple où nous contrôlons une LED RVB avec une page Web via WebSocket.

Pour cela, vous avez besoin de :

Cliquez sur les liens dans la liste ci-dessus pour obtenir les descriptions des différents composants.

Remarque : La résistance dont vous avez besoin peut être différente de celle que nous utilisons selon le type de LED que vous utilisez. La plupart des petites LED n'ont besoin que d'une petite résistance, d'environ 200 à 500 ohms. La valeur exacte que vous utilisez n'est généralement pas critique, mais plus la valeur de la résistance est petite, plus la LED brillera.


Installer le module pigpio

Auparavant, nous avons utilisé le module "onoff", qui fonctionne très bien pour simplement allumer et éteindre. Maintenant, nous voulons définir la force des LED, nous avons donc besoin d'un module GPIO avec un peu plus de fonctionnalités.

Nous utiliserons le module "piggio" Node.js, car cela permet le PWM.

Avec PWM, nous pouvons régler la force d'une LED de 0 à 255.

Le module "pigpio" Node.js est basé sur la bibliothèque pigpio C.

Si vous utilisez la version "Lite" de Raspbian, celle-ci n'est probablement pas incluse et doit être installée manuellement.

Mettez à jour votre liste de packages système :

pi@w3demopi:~ $ sudo apt-get update

Installez la bibliothèque Pigpio C :

pi@w3demopi:~ $ sudo apt-get install pigpio

Nous pouvons maintenant installer le module "pigbio" Node.js en utilisant npm :

pi@w3demopi:~ $ npm install pigpio

Maintenant, le module "piggio" doit être installé et nous pouvons l'utiliser pour interagir avec le GPIO du Raspberry Pi.

Remarque : Le module "pigpio" utilisant la bibliothèque pigpio C, il nécessite des privilèges root/sudo pour accéder aux périphériques matériels (comme le GPIO).


Construire le circuit

Il est maintenant temps de construire le circuit sur notre Breadboard.

Si vous débutez en électronique, nous vous recommandons de couper l'alimentation du Raspberry Pi. Et utilisez un tapis antistatique ou un bracelet de mise à la terre pour éviter de l'endommager.

Éteignez correctement le Raspberry Pi avec la commande :

pi@w3demopi:~ $ sudo shutdown -h now

Une fois que les voyants cessent de clignoter sur le Raspberry Pi, débranchez la prise d'alimentation du Raspberry Pi (ou éteignez la multiprise à laquelle il est connecté).

Le simple fait de débrancher la fiche sans l'éteindre correctement peut entraîner la corruption de la carte mémoire.

Lors de la construction de ce circuit, il est important de savoir si vous avez une anode commune ou une cathode commune, une LED RVB :

Vous pouvez vérifier auprès de votre fournisseur ou le tester vous-même :

Connectez les câbles à la broche GND et 3,3 V. Connectez GND à la jambe la plus longue de la LED RVB et le 3,3 V à n'importe quelle autre jambe. S'il s'allume, votre LED RVB a une cathode commune. Sinon, il a une anode commune.

Raspberry Pi 3 avec planche à pain.  Cathode commune LED RVB

Regardez l'illustration ci-dessus du circuit.

  1. 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
  2. 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)
  3. 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
  4. 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)
  5. 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
  6. 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
  7. 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)
  8. 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
  9. 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
  10. 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)
  11. 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
  12. Sur la planche à pain, connectez une résistance entre les colonnes de bus de masse gauche et droite pour la rangée avec la jambe BLEUE de la LED. Dans cet exemple, nous l'avons attaché à la ligne 4, aux colonnes E et F

Votre circuit devrait maintenant être terminé et vos connexions devraient ressembler assez à l'illustration ci-dessus.

Il est maintenant temps de démarrer le Raspberry Pi et d'écrire le script Node.js pour interagir avec lui.

Raspberry Pi 3 avec planche à pain.  Anode commune à LED RVB

Regardez l'illustration ci-dessus du circuit.

  1. 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
  2. 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)
  3. 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
  4. 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
  5. 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)
  6. 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
  7. 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
  8. 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)
  9. 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
  10. 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
  11. 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)
  12. Sur la planche à pain, connectez la patte mâle du quatrième fil de raccordement à la même rangée de la colonne de bus de terre droite à laquelle vous avez connecté l'anode commune. Dans cet exemple, nous l'avons connecté à la ligne 2 colonne F

Votre circuit devrait maintenant être terminé et vos connexions devraient ressembler assez à l'illustration ci-dessus.

Il est maintenant temps de démarrer le Raspberry Pi et d'écrire le script Node.js pour interagir avec lui.



Raspberry Pi et LED RVB Node.js et script WebSocket

Allez dans le répertoire "nodetest" et créez un nouveau fichier nommé " rgbws.js" :

pi@w3demopi:~ $ nano rgbws.js

Le fichier est maintenant ouvert et peut être modifié avec le Nano Editor intégré.

Écrivez ou collez ce qui suit :

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
});

Appuyez sur " Ctrl+x" pour enregistrer le code. Confirmez avec " y", et confirmez le nom avec " Enter".

Écrivez ou collez ce qui suit :

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
});

Appuyez sur " Ctrl+x" pour enregistrer le code. Confirmez avec " y", et confirmez le nom avec " Enter".


Interface utilisateur Raspberry Pi et Node.js WebSocket

Il est maintenant temps d'ajouter le HTML qui permet la saisie de l'utilisateur via WebSocket.

Pour cela nous voulons :

  • 3 curseurs de couleur, un pour chaque couleur (RVB)
  • Un sélecteur de couleurs
  • Un div montrant la couleur actuelle

Allez dans le dossier "public":

pi@w3demopi:~/nodetest $ cd public

Et créez un fichier HTML, 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>

Retournez dans le dossier "nodetest":

pi@w3demopi:~/nodetest $ cd ..

Exécutez le code :

pi@w3demopi:~ $ sudo node rgbws.js

Remarque : Le module "pigpio" utilisant la bibliothèque pigpio C, il nécessite des privilèges root/sudo pour accéder aux périphériques matériels (comme le GPIO).

Ouvrez le site Web dans un navigateur en utilisant http://[RaspberryPi_IP]:8080/

Maintenant, la LED RVB devrait changer de couleur en fonction de l'entrée de l'utilisateur.

Terminez le programme avec Ctrl+c.