Arduino Daten an HTML-Seite?
Ich habe gerade ein Projekt, indem ich versuche Daten vom Arduino auf eine HTML-Seite zu übertragen. Dabei benutze ich node.js.
Jedoch bin ich noch relativ neu in dem Thema und kenne mich nicht so gut mit Servern und node aus.
Im Moment erhalte ich ständig die Fehlermeldung: Server is not a consructor (const io = new Server('COM3'))
Quelltext aus app.js:
var http = require("http");
var fs = require("fs");
var index = fs.readFileSync("index.html");
var SerialPort = require("serialport");
const parsers = SerialPort.parsers;
const parser = new parsers.Readline({
delimiter: "\r\n",
});
var port = new SerialPort("COM3", {
baudRate: 9600,
dataBits: 8,
parity: "none",
stopBits: 1,
flowControl: false,
});
port.pipe(parser);
var app = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(index);
});
const Server = require('socket.io');
const io = new Server('COM3');
io.on("connection", function (socket) {
console.log("Node is listening to port");
});
parser.on("data", function (data) {
console.log("Received data from port: " + data);
io.emit("data", data);
});
app.listen(3000);
Quelltext aus index.html:
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
</head>
<body>
<h1> Communicating between an arduino and a html website</h1>
<div id='sample'></div>
<script>
var socket = io();
socket.on('data',function(data){
console.log(data);
document.getElementById('sample').innerHTML = data;
});
</script>
</body>
</html>
1 Antwort
Du versuchst eine Socket-Verbindung auf einem seriellen Port (COM3) herzustellen, obwohl Sockets eher für die Kommunikation über Netzwerke genutzt werden. Du benötigst jedoch das SerialPort-Modul um mit lokalen Geräten zu kommunizieren.
const http = require("http");
const fs = require("fs");
const SerialPort = require("serialport");
const parsers = SerialPort.parsers;
const parser = new parsers.Readline({ delimiter: "\r\n" });
const port = new SerialPort("COM3", { baudRate: 9600 });
let index = fs.readFileSync("index.html");
const app = http.createServer(function (req, res) {
res.writeHead(200, { "Content-Type": "text/html" });
res.end(index);
});
const io = require('socket.io')(app);
io.on("connection", function (socket) {
console.log("Node is listening to port");
});
parser.on("data", function (data) {
console.log("Received data from port: " + data);
io.emit("data", data);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Ich habe es dir mal eingebunden und mal bei testweise laufen lassen kannst. Du könntest auch die nativen Node.js-Sockets verwenden, sprich ohne HTTP zu nutzen. Vielleicht reicht es dir aber schon so. Probier es einfach mal aus.
Nachtrag: Wenn es noch kürzer sein soll, kannst du auch bloß das Socket.io-Modul verwenden. In dem Fall dann alles über dieses Modul verwaltet wird, also der Socket-Server und die Kommunikation zu deinem Frontend (index.html).
JavaScript:
const fs = require("fs");
const SerialPort = require("serialport");
const parsers = SerialPort.parsers;
const parser = new parsers.Readline({ delimiter: "\r\n" });
const port = new SerialPort("COM3", { baudRate: 9600 });
const io = require("socket.io")();
parser.on("data", function(data) {
console.log("Received data from port: " + data);
io.emit("data", data);
});
io.on("connection", function(socket) {
console.log("Node is listening to port");
});
io.listen(3000, () => {
console.log('Server is running on port 3000');
});
HTML:
const socket = io('http://localhost:3000');
socket.on('data', function(data) {
const dataList = document.getElementById('sample');
const listItem = document.createElement('li');
listItem.textContent = data;
dataList.appendChild(listItem);
});
Kein Ding und gern geschehen. Und was den HTML Block (oben) angeht, müsste dieser innerhalb eines <script> Elements stehen. Hat es funktioniert oder werden keine Daten zurückgegeben? Ich konnte es jetzt nicht selber bei mir testen.
Also ich hatte jetzt nur das zweite und dritte genommen und es funktioniert leider nicht. Im Terminal wird nichts angezeigt und die Seite lädt gar nicht... Musste ich das erste mit einbinden?
Es sind/waren zwei Lösungsansätze, einmal mit HTTP und das letzte (was zusammengehört) direkt über das Socket.io-Modul. Ich kann dir aus der Ferne schwer sagen, woran bei dir liegt.
Ich habe mich noch nicht viel mit Arduino beschäftigt und es bei mir gerade nicht testen kann. Der Node.js-Server müsste soweit passen und Mal schauen kannst, ob dir ein Eventlistener weiterhilft.
<div id="data"></div>
<script>
const output = document.querySelector('#data');
const eventSrc = new EventSource('/events');
eventSrc.addEventListener('data', (event) => {
const data = JSON.parse(event.data);
output.innerHTML = `Sensorwert: ${data}`;
});
</script>
Vielen Dank :))