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
- Start the WebSocket server:
sh Copy Edit node server.js
- Open your browser and go to:
arduino Copy Edit http://localhost:3000