← Back to Tutorials Chapter 13

Hardware & IoT with Node.js

Overview

Node.js can interact with hardware, making it a great choice for IoT (Internet of Things) applications. The combination of JavaScript's ease of use and Node.js's event-driven model works well for sensor data collection, device control, and real-time dashboards.

Raspberry Pi Setup

The Raspberry Pi is the most popular board for Node.js IoT projects.

# Install Node.js on Raspberry Pi (Raspberry Pi OS)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify
node --version
npm --version

GPIO (General Purpose Input/Output)

GPIO pins allow you to read sensors and control actuators. Use the onoff or pigpio library.

// Install: npm install onoff

const Gpio = require('onoff').Gpio;

// Setup LED on GPIO 17
const led = new Gpio(17, 'out');

// Setup button on GPIO 18
const button = new Gpio(18, 'in', 'both');

// Blink LED
let state = 0;
setInterval(() => {
  state = state ? 0 : 1;
  led.writeSync(state);
}, 1000);

// Read button
button.watch((err, value) => {
  if (err) return console.error(err);
  console.log('Button pressed! Value:', value);
});

// Cleanup on exit
process.on('SIGINT', () => {
  led.unexport();
  button.unexport();
  process.exit();
});

LED Projects

Traffic Light Simulation

const Gpio = require('onoff').Gpio;

const red = new Gpio(17, 'out');
const yellow = new Gpio(27, 'out');
const green = new Gpio(22, 'out');

function setLights(r, y, g) {
  red.writeSync(r);
  yellow.writeSync(y);
  green.writeSync(g);
}

// Simulate traffic light cycle
async function trafficCycle() {
  setLights(1, 0, 0); // Red
  await sleep(3000);
  setLights(1, 1, 0); // Red + Yellow
  await sleep(1000);
  setLights(0, 0, 1); // Green
  await sleep(3000);
  setLights(0, 1, 0); // Yellow
  await sleep(1000);
  trafficCycle();
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

trafficCycle();

Sensor Reading

// Temperature sensor (DS18B20 on Raspberry Pi)
const fs = require('fs');

const sensorPath = '/sys/bus/w1/devices/28-xxxx/w1_slave';

function readTemperature() {
  const data = fs.readFileSync(sensorPath, 'utf8');
  const match = data.match(/t=(-?\d+)/);
  if (match) {
    const tempC = parseInt(match[1]) / 1000;
    const tempF = tempC * 9 / 5 + 32;
    return { celsius: tempC, fahrenheit: tempF };
  }
  return null;
}

setInterval(() => {
  const temp = readTemperature();
  if (temp) {
    console.log(`Temperature: ${temp.celsius.toFixed(1)}°C / ${temp.fahrenheit.toFixed(1)}°F`);
  }
}, 5000);

WebSocket Integration

Combine hardware with WebSockets for real-time browser dashboards.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const Gpio = require('onoff').Gpio;

const app = express();
const server = http.createServer(app);
const io = new Server(server);

const sensor = new Gpio(4, 'in', 'both');

// Serve static files
app.use(express.static('public'));

io.on('connection', (socket) => {
  console.log('Dashboard connected');

  // Send sensor data when it changes
  sensor.watch((err, value) => {
    if (err) return;
    socket.emit('sensor', { value, timestamp: Date.now() });
  });

  socket.on('toggle-led', (state) => {
    const led = new Gpio(17, 'out');
    led.writeSync(state ? 1 : 0);
  });
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

IoT Components Guide

ComponentPurposeGPIO Pin Type
LEDVisual outputOutput (digital)
ButtonUser inputInput (digital)
DHT11/DHT22Temperature & humidityInput (digital)
HC-SR04Distance / ultrasonicInput/Output (digital)
Servo MotorPrecise movementPWM output
BuzzerSound outputOutput (digital/PWM)
Exercise: Create a weather station on a Raspberry Pi that reads temperature and humidity from a DHT11 sensor every 10 seconds and serves the data on a real-time web dashboard using Socket.IO. Include a button to toggle an LED.