Skip to content

Arduino and Node.js with WebSocket

FA25 Kannai Dev Board
alt text alt text

Arduino

const int buttonPin = 4; // Button on pin 4

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);               // Start USB serial communication
}

void loop() {
  // Send button state to Processing
  if (digitalRead(buttonPin) == LOW) {
    Serial.println("P"); // Send "P" = Pressed
  } else {
    Serial.println("R"); // Send "R" = Released
  }

  delay(100); // Wait to avoid flooding serial port
}

Serial Port name

% ls /dev/tty.usb*
/dev/tty.usbmodem101

JS

% tree
.
├── index.html
└── server.js

server.js

const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');
const WebSocket = require('ws');

const serial = new SerialPort({ path: '/dev/tty.usbmodem101', baudRate: 9600 });

serial.on('open', () => {
  console.log('Serial port opened');
});

const parser = serial.pipe(new ReadlineParser({ delimiter: '\n' }));

const wss = new WebSocket.Server({ port: 8080 }, () => {
  console.log('WebSocket server started on ws://localhost:8080');
});

wss.on('connection', (ws) => {
  console.log('WebSocket client connected');

  parser.on('data', (data) => {
    const trimmed = data.trim();
    console.log('From Xiao:', trimmed);
    ws.send(trimmed); // Send data to the client
  });
});

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Xiao Button Viewer</title>
</head>
<body>
  <h1>Xiao Button</h1>
  <p>Status: <span id="status">Not connected</span></p>
  <p>Button: <span id="button">---</span></p>

  <script>
    const ws = new WebSocket('ws://localhost:8080');

    ws.onopen = () => {
      document.getElementById("status").textContent = "Connected";
    };

    ws.onmessage = (event) => {
      const val = event.data.trim();
      let message = val === "P" ? "Pressed" : "Released";
      document.getElementById("button").textContent = message;
      console.log("Received from Xiao:", val);
    };

    ws.onclose = () => {
      document.getElementById("status").textContent = "Disconnected";
    };
  </script>
</body>
</html>

Install packages

Check node/npm

% node -v
v22.15.0
% npm -v
9.5.1

Install ws, serialport, @serialport/parser-readline

% cd to/the/path
% tree
.
├── index.html
└── server.js
% npm install ws serialport @serialport/parser-readline

Note

Package name
ws WebSocket Server library
serialport Libraries for serial communication between Arduino and PC
@serialport/parser-readline A parser to easily handle data line by line from serial communication
% tree -L 1
.
├── index.html
├── node_modules
├── package-lock.json
├── package.json
└── server.js
% node server.js 
WebSocket server started on ws://localhost:8080
Serial port opened

Open index.html in Chrome