I'm willing to do a simple dialogue between my Arduino and a web interface.
I've been able to do this in the command line so now I'm trying to do the same with some buttons.
I've been using socket.io to manage the sockets and I can emit a socket to Arduino but when I try to emit a socket from Arduino to the server it doesn't seem to work.
Here's my code.
server.js:
var fs = require('fs');
var http = require('http');
var io = require('socket.io');
var url = require("url");
var SerialPort = require("serialport").SerialPort;
var socketServer;
var serialport;
var portName = '/dev/ttyACM0'; //change this to your Arduino port
var sendData = "";
function startServer(route,handle,debug) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received");
var content = route(handle,pathname,response,request,debug);
}
var httpServer = http.createServer(onRequest).listen(1337, function(){
console.log("Listening at: http://localhost:1337");
});
initSocketIO(httpServer,debug);
}
function initSocketIO(httpServer,debug) {
socketServer = io.listen(httpServer);
if(debug == false) socketServer.set('log level', 1);
socketServer.on('connection', function (socket) {
console.log("Connected");
socket.emit('onconnection', {msg:sendData});
socket.on('buttonval', function(data) {
console.log('A letter ' + data + ' was sent');
serialport.write(data);
});
socket.on('update', function(data) {
console.log('Yaaaaayaaa');
socket.emit('updateData',{msg:data.buffer});
});
socket.on('error', function(err) {
console.log(err);
});
serialListener(debug, socket);
});
}
// Listen to serial port
function serialListener(debug, socket) {
var receivedData = "";
serialport = new SerialPort(portName, {
baudrate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
serialport.on('open', function(){
var buffer = "";
serialport.on('data', function(data){
var match = /\r|\n/.exec(data);
if (match) {
buffer += data;
console.log("%s", buffer);
sendData = buffer;
socket.emit('update', {msg:buffer});
buffer = "";
} else buffer += data;
});
});
}
exports.start = startServer;
index.html:
<!DOCTYPE HTML>
<html>
<head>
<style>
</style>
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var iosocket;
function initSocketIO() {
iosocket = io.connect();
iosocket.on('onconnection', function(value) {
initButton();
//recieve changed values by other client from server
iosocket.on('updateData', function (recievedData) {
alert(recievedData.msg);
$("#result").html(recievedData.msg);
});
});
}
function initButton(){$( "#check" ).button();}
window.onload = function() {initSocketIO();};
$(document).ready(function() {
$('#check').click(function() {
iosocket.emit('buttonval', 'S');
});
});
</script>
</head>
<body>
<div id="rData">
<h2>Data from Arduino</h2>
<div id="result"></div>
</div>
<input type="button" id="check" value="Measure"/></div>
</div>
</body>
</html>
arduino.ino:
float rP = 0;
float lP = 0;
float cP = 0;
void initMeasurement() {
Serial.println("Ready for measures");
}
void doMeasure() {
rP = 0.1;
lP = 0.2;
cP = 0.35;
}
boolean start = false;
void setup() {
// initialize serial:
Serial.begin(9600);
// init something
initMeasurement();
}
void loop() {
// Recieve data from Node and write it to a String
if (Serial.available() && !start) {
char inChar = (char)Serial.read();
if(inChar == 'S'){ // end character for led
start = true;
}
} else if (start) {
Serial.println("Measuring...");
doMeasure();
Serial.println("Results are:");
Serial.print("Rp = ");
Serial.println(rP);
Serial.print("Lp = ");
Serial.println(lP);
Serial.print("Cp = ");
Serial.println(cP);
start = false;
Serial.println("Ready again");
}
//delay(50); // give the Arduino some breathing room.
}
Related
I tried to implement the w3schools demo of web worker on nodejs, but it doesn't work. The OS is Windows 10 (v10.0.18363.1256), Chrome (v88.0.4324.104) is set on developer mode and nodejs (x64-v14.15.4). No errors appear both on the browser and command prompt, which tells me that it's all ok (Server running at http://127.0.0.1:80/). The web page appears, but the buttons don't work. You can read the code below. The file myapp.js to start the node is in my own user folder, whereas demo_worker.js and index.html are in the folder c:\nodejsworker.
Thank you in advance for your help.
// demo_workers.js
var i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()", 500);
}
timedCount();
//myapp.js
const http = require('http');
var fs = require('fs');
const hostname = '127.0.0.1';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
// res.end('Hello World');
var myReadStream = fs.createReadStream('C:/nodejsworker/index.html', 'utf8');
myReadStream.pipe(res);
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
<!DOCTYPE html>
<html>
<body>
<p>Count numbers: <output id="result"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
var w;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("./demo_workers.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker() {
w.terminate();
w = undefined;
}
</script>
</body>
</html>
When I go to an image all I get is a square box
This is running latest node as of today I've tried opening the binary file in utf8 and tried not specifying the encoding
var fs = require("fs");
var net = require("net");
var tls = require("tls");
var config = require("config");
var clients = [];
mount = ";";
function get(data) {
var r = /GET\s(.+)\sHTTP/gms;
var rt = r.exec(data)
if (rt != null) { return rt[1] }
}
function handle_data(data, socket) {
if (get(data) == "/") {
var read = fs.readFile("index.html", function(err, data) {
if (err){
console.log(err);
}
var data = data.toString();
var content = data.replace("{port}", config.JCasterPort).replace("{mount}", mount);
var length = content.length
var header = config.HTTP_RESP.replace("{length}", length).replace("{cts}", content).replace("{type}", "text/html");
socket.write(header)
});
}
if (get(data) == "/img/content-bg.png") {
var read = fs.readFile("img/content-bg.png", "utf8", function(err, data) {
if (err){
console.log(err);
}
var data = data.toString();
var content = data;
var length = content.length
var header = config.HTTP_RESP.replace("{length}", length).replace("{cts}", content).replace("{type}", "image/png");
socket.write(header)
});
}
if (get(data) == "/img/background.gif") {
var read = fs.readFile("img/background.gif", "utf8", function(err, data) {
if (err){
console.log(err);
}
var data = data.toString();
var content = data;
var length = content.length
var header = config.HTTP_RESP.replace("{length}", length).replace("{cts}", content).replace("{type}", "image/gif");
socket.write(header)
});
}
if (get(data) == "/img/background.jpg") {
var read = fs.readFile("img/background.jpg", function(err, data) {
if (err){
console.log(err);
}
var data = data.toString()
var content = data;
var length = content.length
var header = config.HTTP_RESP.replace("{length}", length).replace("{cts}", content).replace("{type}", "image/jpg");
socket.write(header)
});
}
}
if (config.JCasterSSL) {
var key = config.JCasterKey;
var cert = config.JCasterCert;
var options = {
key: fs.readFileSync(key),
cert: fs.readFileSync(cert)
};
var server = tls.createServer(options, function(socket) {
socket.on("data", function(data) {
var data = data.toString();
handle_data(data, socket)
});
});
server.listen(config.JCasterPort, function(){
console.log("Listening on port: " + config.JCasterPort)
});
} else {
}
//HTTP_RESP = HTTP/1.1 200 OK\r\nContent-Type: {type}\r\nContent-Length: {length}\r\n\r\n{cts}
My goal is to display the images I know I can use the built in http/https library but I need it to be able to broadcast audio data
the only thing I haven't tried was encoding to ASCII
What I'm trying to do: Real time speech to text conversion during a video chat
Using: Webrtc, web speech api, node js v9.9.0
What happens: index.html loads > the video element shows up appropriately with a button that begins speech to text on click > Button is clicked and speech to text works normally
BUT
when I open another tab, open localhost, the second video element also shows up appropriately next to the first, however, the speech to text aborted
Reason: Because there's another program with higher priority that starts executing. I'm guessing this other program is the node js program.
What I need to know, is if there's a way the html script can continue executing even after the node js program, or whatever program is currently aborting it, begins its execution.
I have tried using web workers in HTML but that just ended up not executing the speech to text script at all.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Realtime communication with WebRTC</title>
<style>
body {
font-family: monospace;
font-size: 22px;
}
</style>
<link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<span id="speech"></span>
<span id="interim"></span>
<div id="videos">
<video id="localVideo" autoplay></video>
<video id="remoteVideo" autoplay></video>
</div>
<script id = "STT">
function upgrade() {
alert('Please use Google Chrome for best experience');
}
window.onload = function() {
if (!(window.webkitSpeechRecognition) && !(window.speechRecognition)) {
upgrade();
} else {
var recognizing,
transcription = document.getElementById('speech'),
interim_span = document.getElementById('interim');
interim_span.style.opacity = '0.5';
function reset() {
//recognizing = false;
interim_span.innerHTML = '';
transcription.innerHTML = '';
speech.start();
}
var speech = new webkitSpeechRecognition() || speechRecognition();
speech.continuous = true;
speech.interimResults = true;
speech.lang = 'en-US'; // check google web speech example source for more lanuages
speech.start(); //enables recognition on default
speech.onstart = function() {
// When recognition begins
recognizing = true;
};
speech.onresult = function(event) {
// When recognition produces result
var interim_transcript = '';
var final_transcript = '';
// main for loop for final and interim results
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
} else {
interim_transcript += event.results[i][0].transcript;
}
}
transcription.innerHTML = final_transcript;
interim_span.innerHTML = interim_transcript;
};
speech.onerror = function(event) {
// Either 'No-speech' or 'Network connection error'
console.error(event.error);
};
speech.onend = function() {
// When recognition ends
reset();
};
}
};
</script>
<button onclick="STT">click</button>
<script src="/socket.io/socket.io.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
index.js:
'use strict';
var os = require('os');
var nodeStatic = require('node-static');
var http = require('http');
var socketIO = require('socket.io');
var fs = require('fs');
var Connect = require('connect');
const threads = require('webworker-threads');
console.log("in index.js");
var fileServer = new(nodeStatic.Server)();
console.log(' var fileServer = new(nodeStatic.Server)();' + fileServer);
var app = http.createServer(function(req, res){
console.log("creating a server");
/*
var worker = new threads.Worker(function(){
function voiceRex(){
console.log('at voiceRex');
fs.readFile('./js/speechreg.html', function (err, html) {
if (err) {
throw err;
}
});
/*res.writeHeader(200, {"Content-Type": "text/html"});
res.write(html);
res.end();
}
this.onmessage = function(event){
res.writeHeader(200, {"Content-Type": "text/html"});
res.write(html);
}
});
worker.onmessage = function(event) {
res.end();
};*/
fileServer.serve(req, res);
}).listen(8000);
console.log('app:' + app);
var io = socketIO.listen(app);
console.log('io:' + io);
io.sockets.on('connection', function(socket) {
console.log('io.sockets.on(connection, function(socket)');
console.log('recieved connection ');
// convenience function to log server messages on the client
function log() {
console.log('in log in index.js');
var array = ['Message from server:'];
console.log('message from server:' + array);
array.push.apply(array, arguments);
socket.emit('log', array);
}
socket.on('message', function(message) {
console.log('Client said: ', message);
log('Client said: ', message);
// for a real app, would be room-only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', function(room) {
console.log('Received request to create or join room ' + room);
log('Received request to create or join room ' + room);
var clientsInRoom = io.sockets.adapter.rooms[room];
console.log(clientsInRoom);
var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
console.log(numClients);
log('Room ' + room + ' now has ' + numClients + ' client(s)');
console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
if (numClients === 0) {
console.log('number of clients is 0');
socket.join(room);
log('Client ID ' + socket.id + ' created room ' + room);
socket.emit('created', room, socket.id);
} else if (numClients === 1) {
console.log('number of clients is 1');
log('Client ID ' + socket.id + ' joined room ' + room);
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room, socket.id);
io.sockets.in(room).emit('ready');
} else { // max two clients
console.log('number of clients is max');
socket.emit('full', room);
}
}, );
socket.on('ipaddr', function() {
console.log('in ipaddr');
var ifaces = os.networkInterfaces();
for (var dev in ifaces) {
ifaces[dev].forEach(function(details) {
if (details.family === 'IPv4' && details.address !== '127.0.0.1') {
socket.emit('ipaddr', details.address);
}
});
}
});
});
index.html: With web worker
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Realtime communication with WebRTC</title>
<style>
body {
font-family: monospace;
font-size: 22px;
}
</style>
<link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<span id="speech"></span>
<span id="interim"></span>
<div id="videos">
<video id="localVideo" autoplay></video>
<video id="remoteVideo" autoplay></video>
</div>
<script id="worker" type="javascript/worker">
var voice = function(transcription, interim_span){
var recognizing;
function reset() {
//recognizing = false;
interim_span.innerHTML = "";
transcription.innerHTML = "";
speech.start();
}
var speech = new webkitSpeechRecognition() || speechRecognition();
speech.lang = "en"; // check google web speech example source for more lanuages
speech.continuous = true;
speech.interimResults = true;
speech.start(); //enables recognition on default
speech.onstart = function() {
// When recognition begins
recognizing = true;
};
speech.onresult = function(event) {
// When recognition produces result
var interim_transcript = '';
var final_transcript = '';
var interim_transcript_post = interim_transcript;
var final_transcript_post = final_transcript;
var final_transcript_post = JSON.parse(JSON.stringify(final_transcript_post));
// main for loop for final and interim results
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
final_transcript_post += JSON.parse(JSON.stringify(final_transcript));
} else {
interim_transcript += event.results[i][0].transcript;
interim_transcript_post += JSON.parse(JSON.stringify(interim_transcript));
}
}
self.postMessage({
'final_transcript_post': final_transcript_post,
'interim_transcript_post': interim_transcript_post
});
};
speech.onerror = function(event) {
// Either 'No-speech' or 'Network connection error'
console.error(event.error);
};
speech.onend = function() {
// When recognition ends
reset();
};
};
</script>
<script>
var transcription = document.getElementById('speech');
var interim_span = document.getElementById('interim');
var transcription = JSON.parse(JSON.stringify(transcription));
var interim_span = JSON.parse(JSON.stringify(interim_span));
document.getElementById('interim').style.opacity = '0.5';
var blob = new Blob([document.getElementById('worker').textContent]);
var w = new Worker(window.URL.createObjectURL(blob));
w.postMessage({
'transcription': transcription,
'interim_span':interim_span
});
w.onmessage = function(event){
transcription.innerHTML = event.data.final_transcript_post;
interim_span.innerHTML = event.data.interim_transcript_post;
};
</script>
<script src="/socket.io/socket.io.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
When one tab is open. speech to text works fine
Two tabs are open and speech to text is aborted
Web speech api can not access microphone simultaneously with the video chat. If you want transcription inside video chat you should just stream the audio recorded to the external transcription service and display the results. Google Speech API supports streams for example, but it pretty expensive.
Running an autobahn websocket server in Python and picking up json updates in the html frontend. The value (in this case "temp") is being displayed as a number with innerHTML when message arrive and that part works fine.
We also got a dial chart (d3js) but the update is initiated by the setInterval function at the end of the code which is far from ideal. How can I make the gauge update 'onmessage' through the websocket?
<script type="text/javascript">
//---the websocket part--
var sock = null;
var displaynumber = null;
var tempdata = null;
window.onload = function () {
var wsuri;
displaynumber = document.getElementById('disp');
if (window.location.protocol === "file:") {
wsuri = "ws://...:9000";
} else {
wsuri = "ws://" + window.location.hostname + ":9000";
}
//set up a new websocket
if ("WebSocket" in window) {
sock = new WebSocket(wsuri);
} else if ("MozWebSocket" in window) {
sock = new MozWebSocket(wsuri);
} else {
disp("Browser does not support WebSocket!");
window.location = "http://autobahn.ws/unsupportedbrowser";
}
if (sock) {
//sock.onopen = function() {};
sock.onclose = function(e) {
sock = null;
};
sock.onmessage = function(e) {
// e.data will be sent as a string and need to be converted to object
var jsondata = JSON.parse(e.data);
tempdata = jsondata.temp;
disp(tempdata + " C");
};
}
function disp(m) {
displaynumber.innerHTML = m;
}
//----This is the dial chart part
dialChart();
function dialChart() {
var powerGauge = gauge('#power-gauge', {
size: 300,
clipWidth: 300,
clipHeight: 300,
ringWidth: 60,
minValue: 0,
maxValue: 100,
transitionMs: 1000,
});
powerGauge.render();
function updateReadings() {
powerGauge.update(tempdata);
}
updateReadings();
setInterval(function() {
updateReadings();
}, 2 * 1000);
}
}
</script>
At the end of the definition of dialChart, add return powerGauge. Then when you call dialChart();, save the result to a variable. Then, instead of writing to tempdata in the socket callback, call powerGaugeVariable.update(jsondata.temp).
What i'm trying to do here is to broadcast a file to other clients connected to the server via websocket/binaryjs using a binaryjs client/server system.
The problem comes with large files (or maybe is totally random?!?!). The client stops sending data to the server giving an error.
This is the first time i try something like this and i'm pretty new to socket programming so i might be missing something.... or everything.
Here is the client
<html>
<head>
<script src="http://cdn.binaryjs.com/0/binary.js" type="text/javascript" language="javascript"></script>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" language="javascript"></script>
<script>
$(document).ready(start);
function upload(e){
var file = e.target.files[0];
var chunkSize = 1024 * 1024; //1mb in this case but the problem seems to be uneffected by the chunk size
var fileSize = file.size;
var start = 0;
var end = chunkSize;
var s = client.createStream({name: file.name, size: file.size});
while(start < fileSize) {
w = s.write(file.slice(start, end));
console.log(w);
start = end;
end = start + chunkSize;
}
/*
//the client.send way
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
client.send(contents, {name: file.name, size: file.size});
};
reader.readAsArrayBuffer(file);
*/
}
var client = new BinaryClient('ws://0.0.0.0');
function start() {
var o = $('#output');
client.on('stream', function(stream, meta){
var parts = [];
var meta = meta;
var downloaded = 0;
var element = $('<div />');
o.append(element);
stream.on('data', function(data){
downloaded += data.byteLength;
element.html(meta.name+' '+(Math.round(downloaded/meta.size*100 *100)/100)+'% ');
parts.push(data);
});
stream.on('end', function(){
var a = document.createElement("a");
a.innerHTML='download';
a.href = (window.URL || window.webkitURL).createObjectURL(new Blob(parts));
a.download = meta.name;
a.target = '_blank';
element.append(a);
});
});
}
</script>
</head>
<body>
<input type="file" id="files" name="files" />
<div id="output"></div>
<script>
document.getElementById('files').addEventListener('change', upload, false);
</script>
</body>
</html>
And then comes the server code
var BinaryServer = require('binaryjs').BinaryServer;
var server = BinaryServer({port:80});
var clients = [];
server.on('connection', function(client){
clients.push(client);
console.log(clients.length);
client.on('stream', function(stream, meta){
var s = [];
var d = 0;
for (var i=0;i<clients.length;i++) {
if (clients[i].id == client.id) {
} else {
s.push(clients[i].createStream(meta));
}
}
var name = meta;
var parts = [];
stream.on('data', function(data){
d += data.length;
console.log('data in '+d);
for (var i=0;i<s.length;i++) {
s[i].write(data);
}
});
stream.on('end', function(){
console.log('end');
for (var i=0;i<s.length;i++) {
s[i].end();
}
});
});
client.on('close', function() {
for (var i=0;i<clients.length;i++) {
if(clients[i].id == client.id) {
clients.splice(i, 1);
}
}
client.close();
});
client.on('error', function(){
console.log('error');
});
});
While uploading from the client, i get this error message at random moments (client binary.js)
WebSocket connection to 'ws://0.0.0.0/' failed: Failed to send WebSocket frame. binary.js:1341
WebSocket connection to 'ws://0.0.0.0/' failed: Failed to load Blob: error code = 3 binary.js:1341
No problem with small files (for instance it NEVER fails broadcasting a 25mb wmv). Dunno if it's just a coincidence.
Any help would be appreciated.