Integrating Arduino with Three.js: Real-time 3D Visualization

Arduino is a popular open-source electronics platform that allows developers to create interactive projects using sensors, motors, and more. Three.js, a JavaScript library, enables the creation of 3D graphics in the browser. Integrating Arduino with Three.js can allow real-time visualization of sensor data, robotics control, and interactive web experiences.

In this article, we’ll explore how to connect an Arduino board with Three.js to create a 3D visualization that reacts to sensor inputs.

Project Overview

We will use an Arduino to send sensor data (e.g., from a potentiometer or accelerometer) to a web page via WebSockets or Serial communication. This data will be used to manipulate a 3D object in Three.js.

Requirements

  • Hardware:
  • Arduino board (Uno, Mega, or any compatible board)
  • Sensor (e.g., potentiometer, accelerometer, or ultrasonic sensor)
  • USB cable
  • Software:
  • Arduino IDE
  • Node.js (for WebSocket server)
  • Three.js (for 3D visualization)

Step 1: Setting Up the Arduino

First, connect a potentiometer to your Arduino as follows:

  • Potentiometer Wiring:
  • Middle pin → A0 (Analog Pin 0)
  • Left pin → 5V
  • Right pin → GND

Arduino Code

Upload the following code to your Arduino board:

cpp

Copy

Edit
void setup() {
  Serial.begin(9600); // Start serial communication
}

void loop() {
  int sensorValue = analogRead(A0); // Read the potentiometer
  Serial.println(sensorValue); // Send data to serial port
  delay(50); // Small delay to limit data rate
}

This will continuously send the potentiometer value to the serial port.

Step 2: Setting Up a WebSocket Server (Node.js)

We need a WebSocket server to relay data from Arduino to the browser.

Install Required Packages

First, install Node.js and run the following commands in your terminal:

sh

Copy

Edit
npm init -y
npm install express socket.io serialport

Create the WebSocket Server (server.js)

Create a server.js file and add this code:

js

Copy

Edit
const express = require("express");
const http = require("http");
const { SerialPort, ReadlineParser } = require("serialport");
const socketIo = require("socket.io");

// Initialize Express and HTTP Server
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// Serve static files (HTML + JS)
app.use(express.static("public"));

// Connect to Arduino via Serial Port
const port = new SerialPort({ path: "COM3", baudRate: 9600 }); // Change COM port as needed
const parser = port.pipe(new ReadlineParser({ delimiter: "n" }));

// When Arduino sends data, send it to the client via WebSockets
parser.on("data", (data) => {
  io.emit("sensorData", data.trim());
  console.log("Arduino:", data);
});

// Start the server
server.listen(3000, () => console.log("Server running on http://localhost:3000"));

Note: Replace "COM3" with the correct serial port for your Arduino.

Step 3: Creating the Three.js Frontend

Create a public/index.html file:

html

Copy

Edit
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Arduino & Three.js</title>
  <script type="importmap">
    {
      "imports": {
        "three": "https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js"
      }
    }
  </script>
</head>
<body>
  <script src="/socket.io/socket.io.js"></script>
  <script type="module" src="app.js"></script>
</body>
</html>

Three.js Script (app.js)

Create a public/app.js file with the following code:

js

Copy

Edit
import * as THREE from "three";

// Setup Scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create a Cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

// WebSocket Connection
const socket = io();

socket.on("sensorData", (data) => {
  const value = parseInt(data, 10);
  const rotation = (value / 1023) * Math.PI * 2; // Map sensor value to rotation
  cube.rotation.y = rotation;
});

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();

Step 4: Running the Project

  1. Start the WebSocket server:
sh

Copy

Edit
node server.js
  1. Open your browser and go to:
arduino

Copy

Edit
http://localhost:3000

Leave a comment

Your email address will not be published. Required fields are marked *