WebSocket ile Node.js Raspberry Pi RGB LED


Darbe Genişliği Modülasyonunu Kullanma

Önceki bölümlerde WebSocket'in nasıl kullanılacağını ve LED'leri açıp kapatmak için GPIO'nun nasıl kullanılacağını öğrendik.

Bu bölümde, WebSocket aracılığıyla kullanıcı girişine dayalı olarak farklı renkleri görüntülemek için PWM (Darbeli genişlik modülasyonu) ile bir RGB LED kullanacağız.

RGB LED, 3 farklı renge sahip bir LED'dir. KIRMIZI, YEŞİL ve MAVİ LED'e (RGB LED) sahiptir.

Ve PWM kullanarak 3 LED'in bireysel gücünü ayarlayabiliriz. Bu, onları karıştırmamıza, bir renk belirlememize izin verecektir.


Neye ihtiyacımız var?

Bu bölümde bir RGB LED'i WebSocket üzerinden bir web sayfası ile kontrol ettiğimiz bir örnek oluşturacağız.

Bunun için ihtiyacınız olan:

Farklı bileşenlerin açıklamaları için yukarıdaki listedeki bağlantıları tıklayın.

Not: İhtiyacınız olan direnç, kullandığınız LED türüne bağlı olarak kullandığımızdan farklı olabilir. Çoğu küçük LED, yalnızca 200-500 ohm civarında küçük bir dirence ihtiyaç duyar. Tam olarak hangi değeri kullandığınız genellikle kritik değildir, ancak direncin değeri ne kadar küçük olursa, LED o kadar parlak olur.


Pigpio Modülünü kurun

Daha önce, sadece açıp kapatmak için harika çalışan "onoff" modülünü kullandık. Şimdi LED'lerin gücünü ayarlamak istiyoruz, bu yüzden biraz daha fazla işlevselliğe sahip bir GPIO Modülüne ihtiyacımız var.

PWM'ye izin verdiği için "pigpio" Node.js modülünü kullanacağız.

PWM ile bir LED'in gücünü 0'dan 255'e ayarlayabiliriz.

"pigpio" Node.js modülü, pigpio C kitaplığını temel alır.

Raspbian'ın "Lite" sürümünü kullanıyorsanız, bu büyük olasılıkla dahil değildir ve manuel olarak kurulmalıdır.

Sistem paketi listenizi güncelleyin:

pi@w3demopi:~ $ sudo apt-get update

Pigpio C kitaplığını kurun:

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

Artık "pigpio" Node.js modülünü npm kullanarak kurabiliriz:

pi@w3demopi:~ $ npm install pigpio

Şimdi "pigpio" modülü kurulmalı ve onu Raspberry Pi'nin GPIO'su ile etkileşim kurmak için kullanabiliriz.

Not: "pigpio" modülü, pigpio C kitaplığını kullandığından, donanım çevre birimlerine (GPIO gibi) erişmek için kök/sudo ayrıcalıkları gerektirir.


Devreyi Kurmak

Şimdi devreyi Breadboard'umuza kurmanın zamanı geldi.

Elektronikte yeniyseniz, Raspberry Pi'nin gücünü kapatmanızı öneririz. Ve zarar görmemesi için antistatik bir paspas veya topraklama kayışı kullanın.

Raspberry Pi'yi şu komutla düzgün bir şekilde kapatın:

pi@w3demopi:~ $ sudo shutdown -h now

Raspberry Pi'de LED'lerin yanıp sönmesi durduktan sonra, Raspberry Pi'den elektrik fişini çekin (veya bağlı olduğu uzatma kablosunu çevirin).

Düzgün kapatmadan sadece fişi çekmek, hafıza kartının bozulmasına neden olabilir.

Bu Devreyi oluştururken, ortak bir anotunuz veya ortak katodunuz olan RGB LED'iniz olup olmadığını bilmek önemlidir:

Sağlayıcınıza danışabilir veya kendiniz test edebilirsiniz:

Kabloları GND'ye ve 3.3V pinine bağlayın. GND'yi RGB LED'in en uzun ayağına ve 3,3 V'u diğer herhangi bir ayağa bağlayın. Yanıyorsa, RGB LED'inizin ortak bir katodu vardır. Değilse, ortak bir anot vardır.

Breadboard ile Raspberry Pi 3.  RGB LED ortak Katot

Devrenin yukarıdaki resmine bakın.

  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. Breadboard'da, LED'in MAVİ ayağı ile sıra için sol ve sağ toprak veri yolu sütunları arasına bir direnç bağlayın . Bu örnekte 4. satır, E ve F sütunlarına ekledik.

Devreniz şimdi tamamlanmış olmalı ve bağlantılarınız yukarıdaki çizime oldukça benzer görünmelidir.

Şimdi Raspberry Pi'yi başlatma ve onunla etkileşim kurmak için Node.js betiğini yazma zamanı.

Breadboard ile Raspberry Pi 3.  RGB LED ortak Anot

Devrenin yukarıdaki resmine bakın.

  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. Breadboard'da, dördüncü atlama telinin erkek bacağını, ortak anodu bağladığınız sağ toprak veri yolu sütununun aynı satırına bağlayın. Bu örnekte, onu 2. satır F sütununa bağladık.

Devreniz şimdi tamamlanmış olmalı ve bağlantılarınız yukarıdaki çizime oldukça benzer görünmelidir.

Şimdi Raspberry Pi'yi başlatma ve onunla etkileşim kurmak için Node.js betiğini yazma zamanı.



Raspberry Pi ve Node.js RGB LED ve WebSocket Komut Dosyası

"nodetest" dizinine gidin ve " " adlı yeni bir dosya oluşturun rgbws.js:

pi@w3demopi:~ $ nano rgbws.js

Dosya artık açıktır ve yerleşik Nano Düzenleyici ile düzenlenebilir.

Aşağıdakileri yazın veya yapıştırın:

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

Ctrl+xKodu kaydetmek için " " tuşuna basın . " y" ile onaylayın ve adı " Enter" ile onaylayın.

Aşağıdakileri yazın veya yapıştırın:

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

Ctrl+xKodu kaydetmek için " " tuşuna basın . " y" ile onaylayın ve adı " Enter" ile onaylayın.


Raspberry Pi ve Node.js WebSocket Kullanıcı Arayüzü

Şimdi WebSocket aracılığıyla kullanıcı girişine izin veren HTML'yi ekleme zamanı.

Bunun için istiyoruz:

  • Her renk için bir tane olmak üzere 3 renk kaydırıcısı (RGB)
  • Bir renk seçici
  • Geçerli rengi gösteren bir div

"Genel" klasörüne gidin:

pi@w3demopi:~/nodetest $ cd public

Ve bir HTML dosyası oluşturun, 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>

"nodetest" klasörüne dönün:

pi@w3demopi:~/nodetest $ cd ..

Kodu çalıştırın:

pi@w3demopi:~ $ sudo node rgbws.js

Not: "pigpio" modülü, pigpio C kitaplığını kullandığından, donanım çevre birimlerine (GPIO gibi) erişmek için kök/sudo ayrıcalıkları gerektirir.

http://[RaspberryPi_IP]:8080/ kullanarak web sitesini bir tarayıcıda açın

Artık RGB LED, kullanıcı girişine bağlı olarak renk değiştirmelidir.

ile programı sonlandırın Ctrl+c.