Home >Web Front-end >JS Tutorial >Getting Started with the Raspberry Pi GPIO Pins in Node.js

Getting Started with the Raspberry Pi GPIO Pins in Node.js

Lisa Kudrow
Lisa KudrowOriginal
2025-02-17 12:58:10332browse

Getting Started with the Raspberry Pi GPIO Pins in Node.js

Getting Started with the Raspberry Pi GPIO Pins in Node.js

SitePoint Internet of Things Week Special! This week we will publish a series of articles about the intersection of the Internet and the physical world, so please keep an eye on IoT tags for the latest updates.

The Internet of Things is all the rage nowadays. In the field of physical computing, we have many ideas that can be put into practice, and it is easy to indulge in programming the world we live in! With the Raspberry Pi and Breadboard, what’s next?

This article will explore how to use Node.js to access the GPIO pins of a Raspberry Pi. With the GPIO pin, you can program the hardware directly. The JavaScript API makes this process seamless. These APIs are abstractions of common techniques and are accessible from anywhere. The Node.js interpreter runs in a single process, which opens up new ways to write testable code. The most exciting part for me is that you can write unit tests, hit breakpoints and check code like you would any other JavaScript program, all of which can be done on your computer.

Let's get started.

Key Points

  • The common input/output (GPIO) pins of the Raspberry Pi can be accessed using Node.js, allowing the hardware to be programmed directly. These pins are like switches, receiving input or sending output to the physical world, and the JavaScript API makes this process seamless.
  • GPIO API is a wrapper for reading or writing device files, and the file system API may be a concept you are already familiar with. In Unix-like systems, GPIO behaves like any other normal file, which provides freedom in how to handle solutions.
  • The test-driven method is very suitable for the Internet of Things. In physical computing, you don't want to ship hardware around the world to debug code. Using a test-driven approach, you can get feedback immediately and ensure that the solution works.
  • Using the GPIO API, it can be simplified into a wrapper around the fs module, creating clean and testable code. This article demonstrates this by using the effective scintillator demonstration of the API shown.

What is GPIO?

GPIO stands for general input/output. They are the pins next to the Raspberry Pi side, the yellow video output socket. Here are what they look like.

Getting Started with the Raspberry Pi GPIO Pins in Node.js

Source: Raspberry Pi
Those can be considered as a way to connect from a Raspberry Pi to the outside world. This allows you to write programs that are not running on your computer screen. Each pin looks like a switch that can be turned on or off. You can receive input from the physical world, or send output. The base board has 26 pins, 9 of which are power or ground pins. The ground pin is located at the end of each circuit where current must flow. The updated Raspberry Pi board also adds an additional set of 14 pins.

If you want to learn more about the GPIO pins, this online chart provides everything you need to know about each pin for use. There are countless input/output and ground pins. These pins are the basis of physical computing. Depending on your goal, you can use as many pins as you want.

Simulate fs!

I know what you are thinking, what exactly is FS, and why do I need to care about it? In a Unix-like operating system, a device file is a driver that looks like a file. Simply put, the device driver is a file! Guess what? The GPIO API is a wrapper for reading or writing device files. File system APIs may be concepts you are already familiar with. If you have never used files in Node.js, I suggest you review the fs module and file system in Node.js. fs is the abbreviation for "file system", allowing you to read or write to normal files. There is nothing fancy here, all we do is for example writeFile(), letting the GPIO handle the rest. The trick is to know which file to write what to write.

There is a convenient npm package called mock-fs, which can help us with unit testing. Using this library, you can simulate any file on any file system in memory. The most important thing is that we only process files, and that's all we need to do. In Unix-like systems, GPIO behaves the same as any other normal file. This gives us the freedom to choose how to deal with this solution.

The core of the mock-fs library is the mock({}) function. It receives a parameter which is a JavaScript object. In this parameter you can create any file you want. The beauty here is that it all runs in memory, so you can do unit testing as much as you want. The interpreter runs in a single process, which means that the fs module can be overwritten at runtime. JavaScript is a dynamic language, so we can simulate any modules available in the current process.

Once you have written good unit tests on GPIO, the GPIO interface makes more sense. What I like is that you can get automated test coverage and a clean solution. Unit testing improves the readability of the code because it clearly shows you what the API is for.

So let's do it.

Unit Test All Content

Let's open a pin with "out" and test it:

<code class="language-javascript">it('opens a pin with out', function (done) {
  mock({
    '/sys/class/gpio/gpio23/direction': ''
  });

  gpio.open(16, 'out', function () {
    const direction = fs.readFileSync('/sys/class/gpio/gpio23/direction').toString();

    should(direction).equal('out');

    done();
  });
});</code>

The implementation of this test should map physical pin 16 to BCM pin 23 in the GPIO. The BCM number is the Broadcom pin number the kernel sees in the device driver. The GPIO device driver outlines the location of the device file. As shown, to turn on the pin, write the string "out" to /direction. This tells the GPIO we want to write this pin. Once done, check if the file contains the required content. mock comes from the mock-fs library, which is the standard file system in Node.js. The kernel indicates where the path is - 3.18.x and later is located in /sys/class/gpio.

To write to a pin on the board and test it, you can do the following:

<code class="language-javascript">it('writes to a pin with a high value', function (done) {
    mock({
      '/sys/class/gpio/gpio23/value': '0'
    });

    gpio.write(16, 5, function () {
      const value = fs.readFileSync('/sys/class/gpio/gpio23/value').toString();

      should(value).equal('1');

      done();
    });
  });</code>

There are similarities between gpio.open() and gpio.write(). Use a write operation, which writes to the /value file. For integrity checking, I wrote a very high value of 5, but we only expect the test result to be 1. GPIO only receives high or low values, just like binary.

I got implementation details from pi-gpio. This library provides you with a good overview of each pin position. You can also look for device files on the kernel. Either way, my goal is to give you a good grasp of the basics so you can get a clear picture.

Let's go crazy, how do you hit breakpoints in unit tests? I use WebStorm to do this, and again, use any way to make you feel comfortable:

Getting Started with the Raspberry Pi GPIO Pins in Node.js

The key to using a reasonable programming method is to shorten the feedback loop required to find errors. Unit testing is a great way to tighten the loop and get instant feedback.

For simplicity, I'm writing to a single pin. The rest of the GPIO is summarized in the same way. Open a pin and tell it what you want to do with it. Read or write pins, whatever you need to do. The low-level API is the device file, so you can choose how to program each pin.

Flashing Demo

To enrich each unit test, let's look at some common variables:

<code class="language-javascript">var sysFsPath = '/sys/class/gpio/gpio';
var pinMapping = {
  '16': 23
};</code>

Above, I have defined the pin map and path to the device driver in GPIO. The following code sees the code for opening and writing pins:

<code class="language-javascript">function open(pinNumber, direction, callback) {
  const path = sysFsPath + pinMapping[pinNumber] + '/direction';

  fs.writeFile(path, direction, (callback || noOp));
}

function write(pinNumber, value, callback) {
  const path = sysFsPath + pinMapping[pinNumber] + '/value';
  value = !!value ? '1' : '0';

  fs.writeFile(path, value, 'utf8', callback);
}

function noOp() {}</code>

As shown, all operations are to write writeFile() to the device file. If there are no callbacks, noOp is a virtual callback. With this implementation detail, I got the pass test and was sure that this would work. The value in the write operation ensures that it will be set to high or low ('0' or '1').

Lastly, a valid scintillator demonstration using the API shown above:

<code class="language-javascript">gpio.open(16, 'out', function () {
  var on = 0;

  var blinker = setInterval(function () {
    gpio.write(16, on, function () {
      on = (on + 1) % 2;

      console.log('ON = ' + on);
    });
  }, 1000);

  setTimeout(function () {
    clearInterval(blinker);
  }, 12000);
});</code>

setInterval() is called once a second, and in the callback I tell it to switch pins using the modulus. The scintillator has intervals, setTimeout() uses this to clear it after 12 seconds. The callback in setTimeOut() completes the work and ends the program.

To run the sample code, type:

<code class="language-bash">sudo npm start</code>

(You need administrator permission to access GPIO on the Raspberry Pi)

I hope that from this demo, the GPIO looks more intuitive. It expects to use direction to turn on a pin. You then write the pins and let the GPIO handle the rest of the details.

Conclusion

The test-driven method is very suitable for the Internet of Things. In the Internet of Things, your imagination is the limit. The Raspberry Pi can be deployed anywhere in the world—in physical computing, you don't want to ship hardware around the world to debug code. Using a test-driven approach, you can get feedback immediately and ensure that the solution works. You can increase productivity and tighten the feedback loop.

What I like about the GPIO API is that it can be simplified into a wrapper around the fs module. This gives you complete freedom to write clean and testable code.

The remaining sample demos have been uploaded to GitHub.

FAQs on using Node.js and GPIO pins on Raspberry Pi

  • What is Node.js and how to use it with the GPIO pins of the Raspberry Pi? Node.js is a JavaScript runtime environment that allows you to run JavaScript code on a Raspberry Pi. You can use it to control and interact with GPIO (General Purpose Input/Output) pins that are used to connect external hardware components to a Raspberry Pi.

  • Is using Node.js and GPIO pins on a Raspberry Pi require any special hardware? You need a Raspberry Pi board, and possibly some external components such as LEDs, sensors, or relays, depending on your project. To get started, you should also have a breadboard and some jumpers for connecting these components to the GPIO pins.

  • How to install Node.js on a Raspberry Pi? You can use the apt package manager or download and install it from the Node.js website to install Node.js on the Raspberry Pi. Make sure you use the ARM-compatible version of Node.js for your specific Raspberry Pi model.

  • What are GPIO pins and how do you identify them on a Raspberry Pi board? The GPIO pin is a pin on the Raspberry Pi that can be used for digital inputs or outputs. They are marked with numbers and can be identified using GPIO pin diagrams specific to your Raspberry Pi model.

  • How to access GPIO pins in Node.js? You can access GPIO pins in Node.js using libraries like rpi-gpio, onoff, or pigpio. These libraries provide APIs for controlling and interacting with GPIO pins in JavaScript code.

  • In my Node.js project, is it possible to use GPIO pins for both input and output? Yes, you can configure the GPIO pins as input and output in your Node.js project. You can read the number of sensors connected to the input pin and control LEDs, motors or other devices connected to the output pins.

  • Is it possible to use the GPIO pin in Node.js for PWM (pulse width modulation) to control tasks such as brightness or speed? Yes, you can PWM using some GPIO pins on the Raspberry Pi to control brightness, motor speed, and more. Library such as pigpio provides support for PWM and is compatible with Node.js.

The above is the detailed content of Getting Started with the Raspberry Pi GPIO Pins in Node.js. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn