Node.js: Node.js Raspberry Pi RGB LED với WebSocket


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Sử dụng Điều chế độ rộng xung

Trong các phần trước, chúng ta đã học cách sử dụng WebSocket và cách sử dụng GPIO để bật và tắt đèn LED và trong phần này, chúng ta sẽ sử dụng đèn LED RGB, với PWM (Điều chế độ rộng xung) để hiển thị các màu khác nhau dựa trên đầu vào của người dùng thông qua WebSocket.

W3Schools Node.js Raspberry Pi RGB LED controlled by browser

Đèn LED RGB là đèn LED có 3 màu khác nhau bao gồm: ĐỎ, XANH LÁ CÂYXANH DƯƠNG (ĐÈN LED RGB), đồng thời sử dụng PWM, chúng ta có thể đặt cường độ riêng của 3 đèn LED. Điều này sẽ cho phép chúng ta từ ba màu trên dể tạo ra vô vàn những màu khác!

Vậy chúng ta cần gì?

Trong phần này, chúng ta sẽ xem một ví dụ trong đó chúng ta điều khiển đèn LED RGB bằng một trang web thông qua WebSocket.

Để làm được điều này, bạn cần:

  • Raspberry Pi với Raspian, internet, SSH, đã cài đặt Node.js
  • Mô-đun pigpio cho Node.js
  • Mô-đun socket.io cho Node.js
  • Breadboard (x1)
  • Điện trở 220 Ohm (x3)
  • LED RGB (cực dương chung hoặc cực âm chung) (x1)
  • dây cắm có hai đầu (đầu đực - đầu cái) (x4)

Nhấp vào liên kết trong danh sách trên để biết mô tả về các thành phần khác nhau.

Lưu ý: Điện trở bạn cần có thể khác với điện trở trong hướng dẫn đang sử dụng, tùy thuộc vào loại đèn LED bạn sử dụng. Hầu hết các đèn LED nhỏ chỉ cần một điện trở nhỏ, khoảng 200-500 ohms. Nói chung, giá trị chính xác mà bạn sử dụng không quan trọng, nhưng giá trị của điện trở càng nhỏ thì đèn LED càng sáng. 

Cài đặt Mô-đun pigpio

Trước đó, chúng ta đã sử dụng mô-đun "bật", hoạt động khi chỉ cần bật và tắt. Bây giờ nếu chúng ta muốn đặt cường độ của đèn LED thì ta cần Mô-đun GPIO có thêm một chút chức năng.

Chúng ta sẽ sử dụng mô-đun Node.js "pigpio", vì điều này cho phép PWM. Đồng thời, với PWM, chúng ta có thể đặt cường độ của đèn LED từ 0 đến 255 và Mô-đun Node.js "pigpio" dựa trên thư viện pigpio C.Nếu bạn đang sử dụng phiên bản "Lite" của Raspbian, rất có thể phiên bản này không được bao gồm và phải được cài đặt thủ công.

Cập nhật danh sách gói hệ thống của bạn:

pi@w3demopi:~ $ sudo apt-get update

Cài đặt thư viện pigpio C:

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

Bây giờ chúng ta có thể cài đặt mô-đun Node.js "pigpio" bằng cách sử dụng npm:

pi@w3demopi:~ $ npm install pigpio 

 Bây giờ, mô-đun "pigpio" sẽ được cài đặt và chúng ta có thể sử dụng nó để tương tác với GPIO của Raspberry Pi.

Lưu ý: Vì mô-đun "pigpio" sử dụng thư viện pigpio C nên nó yêu cầu quyền root/sudo để truy cập các thiết bị ngoại vi phần cứng (như GPIO).

Xây dựng mạch

Bây giờ là lúc để xây dựng mạch trên Breadboard (theo hướng dẫn). Chúng ta sẽ sử dụng mạch mà chúng ta đã tạo trong phần trước làm điểm bắt đầu.Nếu bạn chưa quen với thiết bị điện tử, có một lời khuyễn dành cho bạn là nên tắt nguồn Raspberry Pi và sử dụng thảm chống tĩnh điện hoặc dây nối đất để tránh làm hỏng nó.

Tắt Raspberry Pi đúng cách bằng lệnh:

pi@w3demopi:~ $ sudo shutdown -h now

Sau khi đèn LED ngừng nhấp nháy trên Raspberry Pi, sau đó rút phích cắm nguồn khỏi Raspberry Pi (hoặc vặn dải nguồn mà nó được kết nối).

 Chỉ rút phích cắm mà không tắt đúng cách có thể gây hỏng thẻ nhớ.

Khi xây dựng Mạch này, điều quan trọng là bạn phải có cực dương chung hay cực âm chung, đèn LED RGB:

Bạn có thể kiểm tra với nhà cung cấp của mình hoặc tự kiểm tra:

Kết nối cáp với chân GND và 3,3V. Kết nối GND với chân dài nhất của đèn LED RGB và 3,3 V với bất kỳ chân nào khác. Nếu nó sáng lên, đèn LED RGB của bạn có cực âm chung. Nếu không, nó có một cực dương chung.

Xây dựng mạch - Cathode chung

Raspberry Pi 3 with Breadboard. RGB LED common Cathode

Nhìn vào hình minh họa trên của mạch.

  1. Trên Breadboard, kết nối đèn LED RGB với cột Ground bus bên phải và đảm bảo rằng mỗi chân kết nối với một hàng khác nhau. Chân dài nhất là chân cực âm chung. Trong ví dụ này, ta sẽ kết nối đèn LED với hàng 1-4, với chân cực âm chung được kết nối với hàng 2 cột I. Chân ĐỎ được kết nối với hàng 1 cột J, chân XANH LÁ được kết nối với hàng 3 cột J và chân Chân XANH DƯƠNG nối với hàng 4 cột J
  2. Trên Raspberry Pi, kết nối chân cái của dây đầu tiên với Ground. Bạn có thể sử dụng bất kỳ chân GND nào. Trong ví dụ này sẽ sử dụng Chân vật lý 9 (GND, hàng 5, cột bên trái)
  3. Trên Breadboard, kết nối chân đực của dây đầu tiên với cùng một hàng của cột Ground bus bên phải mà bạn đã kết nối cực âm chung. Trong ví dụ này, kết nối nó với hàng 2 cột F
  4. Trên Raspberry Pi, kết nối chân cái của cáp thứ hai với chân GPIO. Chúng tôi sẽ sử dụng chân này cho chân ĐỎ, Trong ví dụ này, chúng ta sẽ sử dụng Chân vật lý 7 (GPIO 4, hàng 4, cột bên trái)
  5. Trên Breadboard, kết nối chân đực của dây nhảy thứ hai với Ground bus bên trái, cùng hàng với chân ĐỎ của đèn LED được kết nối. Trong ví dụ này sẽ kết nối nó với hàng 1, cột A
  6. Trên Breadboard, kết nối một điện trở giữa các cột Gound bus bên trái và bên phải cho hàng với chân ĐỎ của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 1, cột E và F
  7. Trên Raspberry Pi, kết nối chân cái của cáp thứ ba với chân GPIO. Chúng tôi sẽ sử dụng chân này cho chân XANH LÁ, Trong ví dụ này sẽ sử dụng Chân vật lý 11 (GPIO 17, hàng 6, cột bên trái)
  8. Trên Breadboard, kết nối chân đực của dây thứ ba với Ground bus bên trái, cùng hàng với chân XANH LÁ của đèn LED được kết nối. Trong ví dụ này, chúng ta sẽ kết nối nó với hàng 3, cột A
  9. Trên Breadboard, kết nối một điện trở giữa các cột Ground bus bên trái và bên phải cho hàng với chân XANH LÁ của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 3, cột E và F
  10. Trên Raspberry Pi, kết nối chân cái của cáp nhảy thứ tư với chân GPIO. Ta sẽ sử dụng chân này cho chân XANH DƯƠNG, Trong ví dụ này, chúng ta sẽ sử dụng Chân vật lý 13 (GPIO 27, hàng 7, cột bên trái)
  11. Trên Breadboard, kết nối chân đực của dây nhảy thứ tư với bus nối đất bên trái, cùng hàng với chân XANH DƯƠNG của đèn LED được kết nối. Trong ví dụ này sẽ kết nối nó với hàng 4, cột A
  12. Trên Breadboard, kết nối một điện trở giữa các cột bus nối đất bên trái và bên phải cho hàng với chân XANH DƯƠNG của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 4, cột E và F

Bây giờ mạch của bạn đã hoàn tất và các kết nối của bạn sẽ trông khá giống với hình minh họa ở trên.

Bây giờ là lúc khởi động Raspberry Pi và viết tập lệnh Node.js để tương tác với nó.

Xây dựng mạch - Anode chung

Raspberry Pi 3 with Breadboard. RGB LED common Anode

Nhìn vào hình minh họa trên của mạch.

  1. Trên Breadboard, kết nối đèn LED RGB với cột Ground bus bên phải và đảm bảo rằng mỗi chân kết nối với một hàng khác nhau. Chân dài nhất là chân anode chung. Trong ví dụ này, chúng ta sẽ kết nối đèn LED với hàng 1-4, với chân cực âm chung được kết nối với hàng 2 cột I. Chân ĐỎ được kết nối với hàng 1 cột J, chân XANH LÁ được kết nối với hàng 3 cột J và chân Chân XANH DƯƠNG nối với hàng 4 cột J
  2. Trên Raspberry Pi, kết nối chân cái của cáp đầu tiên với chân GPIO. Chúng tôi sẽ sử dụng chân này cho chân ĐỎ, Trong ví dụ này, chúng tôi đã sử dụng Chân vật lý 7 (GPIO 4, hàng 4, cột bên trái)
  3. Trên Breadboard, kết nối chân đực của dây nhảy đầu tiên với ground bus bên trái, cùng hàng với chân ĐỎ của đèn LED được kết nối. Trong ví dụ này, chúng ta sẽ kết nối nó với hàng 1, cột A
  4. Trên Breadboard, kết nối một điện trở giữa các cột grouns bus bên trái và bên phải cho hàng với chân ĐỎ của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 1, cột E và F
  5. Trên Raspberry Pi, kết nối chân cái của cáp nhảy thứ hai với chân GPIO. Chúng tôi sẽ sử dụng chân này cho chân XANH LÁ, Trong ví dụ này, chúng ta sẽ sử dụng Chân vật lý 11 (GPIO 17, hàng 6, cột bên trái)
  6. Trên Breadboard, kết nối chân đực của dây nhảy thứ hai với ground bus bên trái, cùng hàng với chân XANH LÁ của đèn LED được kết nối. Trong ví dụ này, chúng ta sẽ kết nối nó với hàng 3, cột A
  7. Trên Breadboard, kết nối một điện trở giữa các cột ground bus bên trái và bên phải cho hàng với chân XANH LÁ của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 3, cột E và F
  8. Trên Raspberry Pi, kết nối chân cái của cáp thứ ba với chân GPIO. Chúng tôi sẽ sử dụng chân này cho chân XANH DƯƠNG, Trong ví dụ này, chúng ta sẽ sử dụng Chân vật lý 13 (GPIO 27, hàng 7, cột bên trái)
  9. Trên Breadboard, kết nối chân đực của dây thứ ba với bus nối đất bên trái, cùng hàng với chân XANH DƯƠNG của đèn LED được kết nối. Trong ví dụ này, chúng ta sẽ kết nối nó với hàng 4, cột A
  10. Trên Breadboard, kết nối một điện trở giữa các cột ground bus bên trái và bên phải cho hàng với chân XANH DƯƠNG của đèn LED. Trong ví dụ này, chúng ta sẽ gắn nó vào hàng 4, cột E và F
  11. Trên Raspberry Pi, kết nối chân cái của dây thứ tư với 3,3V. Trong ví dụ này, chúng ta sẽ sử dụng Chân vật lý 1 (3,3V, hàng 1, cột bên trái)
  12. Trên Breadboard, kết nối chân đực của dây thứ tư với cùng một hàng của cột ground bus bên phải mà bạn đã kết nối cực dương chung. Trong ví dụ này, chúng ta sẽ kết nối nó với hàng 2 cột F

Bây giờ mạch của bạn đã hoàn tất và các kết nối của bạn sẽ trông khá giống với hình minh họa ở trên.

Bây giờ là lúc khởi động Raspberry Pi và viết tập lệnh Node.js để tương tác với nó.

Raspberry Pi và Node.js RGB LED và WebSocket (đoạn mã lệnh)

Chuyển đến thư mục "nodetest" và tạo một tệp mới có tên "rgbws.js":

pi@w3demopi:~ $ nano rgbws.js

Tệp hiện đang mở và có thể được chỉnh sửa bằng Trình chỉnh sửa Nano tích hợp sẵn.

Sử dụng đèn LED RGB Cathode chung

Viết hoặc dán lại đoạn mã sau:

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

Nhấn "Ctrl+x" để lưu mã. Xác nhận bằng "y" và xác nhận tên bằng "Enter". 

Sử dụng đèn LED RGB Anode chung

Viết hoặc dán lại đoạn mã sau:

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

Nhấn "Ctrl+x" để lưu mã. Xác nhận bằng "y" và xác nhận tên bằng "Enter". 

Giao diện người dùng Raspberry Pi và Node.js WebSocket

Bây giờ là lúc thêm HTML cho phép người dùng nhập thông qua WebSocket.

Để làm được điều này, chúng ta cần:

  • 3 thanh trượt màu, một cho mỗi màu (RGB)
  • Bộ chọn màu
  • Một div hiển thị màu hiện tại

Chuyển đến thư mục "public":

pi@w3demopi:~/nodetest $ cd public

Và tạo một tệp 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>

Quay trở lại thư mục "nodetest": 

pi@w3demopi:~/nodetest $ cd ..

Chạy mã: 

pi@w3demopi:~ $ sudo node rgbws.js

Lưu ý: Vì mô-đun "pigpio" sử dụng thư viện pigpio C nên nó yêu cầu quyền root/sudo để truy cập các thiết bị ngoại vi phần cứng (như GPIO).

Mở trang web trong trình duyệt bằng http://[RaspberryPi_IP]:8080/

Bây giờ đèn LED RGB sẽ thay đổi màu sắc tùy thuộc vào đầu vào của người dùng và cuối cùng, ết thúc chương trình bằng Ctrl+c.

 

« Trước: Truy vấn dữ liệu trong bộ sưu tập (Query)
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!