WebSocket이 있는 Node.js Raspberry Pi RGB LED


펄스 폭 변조 사용

이전 장에서 WebSocket을 사용하는 방법과 GPIO를 사용하여 LED를 켜고 끄는 방법을 배웠습니다.

이 장에서는 WebSocket을 통한 사용자 입력을 기반으로 다양한 색상을 표시하기 위해 PWM(펄스 폭 변조)과 함께 RGB LED를 사용합니다.

RGB LED는 3가지 색상의 LED입니다. RED, GREEN, BLUE LED(RGB LED)가 있습니다.

그리고 PWM을 사용하여 3개의 LED의 개별 강도를 설정할 수 있습니다. 이렇게 하면 색상을 설정하기 위해 혼합할 수 있습니다.


우리는 무엇이 필요한가?

이 장에서는 WebSocket을 통해 웹 페이지에서 RGB LED를 제어하는 ​​예를 만듭니다.

이를 위해서는 다음이 필요합니다.

다양한 구성 요소에 대한 설명을 보려면 위 목록의 링크를 클릭하십시오.

참고: 필요한 저항기는 사용하는 LED 유형에 따라 사용하는 것과 다를 수 있습니다. 대부분의 소형 LED에는 약 200-500옴의 작은 저항만 있으면 됩니다. 일반적으로 사용하는 정확한 값은 중요하지 않지만 저항 값이 작을수록 LED가 더 밝게 빛납니다.


pigpio 모듈 설치

이전에 우리는 "onoff" 모듈을 사용했는데, 이것은 단순히 켜고 끄는 데 유용합니다. 이제 LED의 강도를 설정하려고 하므로 조금 더 많은 기능을 갖춘 GPIO 모듈이 필요합니다.

PWM을 허용하는 "pigpio" Node.js 모듈을 사용할 것입니다.

PWM을 사용하면 LED의 강도를 0에서 255까지 설정할 수 있습니다.

"pigpio" Node.js 모듈은 pigpio C 라이브러리를 기반으로 합니다.

Raspbian의 "Lite" 버전을 사용하는 경우 이것은 포함되지 않을 가능성이 높으며 수동으로 설치해야 합니다.

시스템 패키지 목록 업데이트:

pi@w3demopi:~ $ sudo apt-get update

pigpio C 라이브러리를 설치합니다.

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

이제 npm을 사용하여 "pigpio" Node.js 모듈을 설치할 수 있습니다.

pi@w3demopi:~ $ npm install pigpio

이제 "pigpio" 모듈을 설치해야 하며 이를 사용하여 Raspberry Pi의 GPIO와 상호 작용할 수 있습니다.

참고: "pigpio" 모듈은 pigpio C 라이브러리를 사용하기 때문에 GPIO와 같은 하드웨어 주변 장치에 액세스하려면 루트/sudo 권한이 필요합니다.


회로 구축

이제 브레드보드에 회로를 만들 차례입니다.

전자 제품을 처음 접하는 경우 Raspberry Pi의 전원을 끄는 것이 좋습니다. 정전기 방지 매트나 접지 스트랩을 사용하여 손상되지 않도록 하십시오.

다음 명령을 사용하여 Raspberry Pi를 올바르게 종료합니다.

pi@w3demopi:~ $ sudo shutdown -h now

Raspberry Pi에서 LED가 깜박임을 멈추면 Raspberry Pi에서 전원 플러그를 뽑습니다(또는 연결된 전원 스트립을 켭니다).

제대로 종료하지 않고 플러그를 뽑기만 하면 메모리 카드가 손상될 수 있습니다.

이 회로를 구축할 때 공통 양극 또는 공통 음극 RGB LED가 있는지 아는 것이 중요합니다.

공급자에게 확인하거나 직접 테스트할 수 있습니다.

케이블을 GND와 3.3V 핀에 연결합니다. GND를 RGB LED의 가장 긴 다리에 연결하고 3.3V를 다른 다리에 연결합니다. 불이 켜지면 RGB LED에 공통 음극이 있습니다. 그렇지 않은 경우 공통 양극이 있습니다.

브레드보드가 있는 라즈베리 파이 3.  RGB LED 공통 음극

위의 회로도를 보십시오.

  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에서 LED의 BLUE 다리가 있는 행의 왼쪽 및 오른쪽 접지 버스 열 사이에 저항을 연결합니다 . 이 예에서는 행 4, 열 E 및 F에 연결했습니다.

이제 회로가 완성되고 연결이 위의 그림과 매우 유사해야 합니다.

이제 Raspberry Pi를 부팅하고 Node.js 스크립트를 작성하여 상호 작용할 시간입니다.

브레드보드가 있는 라즈베리 파이 3.  RGB LED 공통 양극

위의 회로도를 보십시오.

  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. 브레드보드에서 네 번째 점퍼 와이어의 수 레그를 공통 양극을 연결한 오른쪽 접지 버스 열의 동일한 행에 연결합니다. 이 예에서 우리는 그것을 행 2 F 열에 연결했습니다.

이제 회로가 완성되고 연결이 위의 그림과 매우 유사해야 합니다.

이제 Raspberry Pi를 부팅하고 Node.js 스크립트를 작성하여 상호 작용할 시간입니다.



Raspberry Pi 및 Node.js RGB LED 및 WebSocket 스크립트

"nodetest" 디렉토리로 이동하여 " "라는 새 파일을 만듭니다 rgbws.js.

pi@w3demopi:~ $ nano rgbws.js

이제 파일이 열리고 내장된 Nano Editor로 편집할 수 있습니다.

다음을 작성하거나 붙여넣습니다.

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+x"를 눌러 코드를 저장합니다. " "로 확인하고 " y"로 이름을 확인하십시오 Enter.

다음을 작성하거나 붙여넣습니다.

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+x"를 눌러 코드를 저장합니다. " "로 확인하고 " y"로 이름을 확인하십시오 Enter.


Raspberry Pi 및 Node.js WebSocket UI

이제 WebSocket을 통한 사용자 입력을 허용하는 HTML을 추가할 차례입니다.

이를 위해 우리는 다음을 원합니다.

  • 3가지 색상 슬라이더, 각 색상(RGB)당 하나씩
  • 색상 선택기
  • 현재 색상을 보여주는 div

"공개" 폴더로 이동합니다.

pi@w3demopi:~/nodetest $ cd public

그리고 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>

"nodetest" 폴더로 돌아가십시오.

pi@w3demopi:~/nodetest $ cd ..

코드를 실행합니다.

pi@w3demopi:~ $ sudo node rgbws.js

참고: "pigpio" 모듈은 pigpio C 라이브러리를 사용하기 때문에 GPIO와 같은 하드웨어 주변 장치에 액세스하려면 루트/sudo 권한이 필요합니다.

http://[RaspberryPi_IP]:8080/을 사용하여 브라우저에서 웹사이트를 엽니다.

이제 RGB LED는 사용자 입력에 따라 색상이 변경되어야 합니다.

로 프로그램을 종료합니다 Ctrl+c.