node.js + serial code not work consistently - javascript

i tried to calculate root mean square using node.js, trying to be smart to make some kind of high resolution realtime measurement of stuff from serial port.
the code doesnt really matter. but each time i try to run this multiple times but it output totally different rms output value, sometimes very big, sometimes very small, NaN, etc.
the question is:
why? how? is there any node.js quirk i miss? like inter-process shared memory allocation?
it's fixed after i rewrite the program(some edit) or waiting for some time
re running a program should do the same thing everytime, right?
btw i'm using nodeserial for serial communication, at 500k baud
actual code may be posted later if you want
edit: the code
var math = require('mathjs');
var fs = require('fs');
// serving the static html "client"
var http = require('http');
var finalhandler = require('finalhandler');
var serveStatic = require('serve-static');
var serve = serveStatic("./");
var server = http.createServer(function(req, res) {
var done = finalhandler(req, res);
serve(req, res, done);
});
// socket.io
var app = require('express')();
var http2 = require('http').Server(app);
var io = require('socket.io')(http2);
io.on('connection', function(socket) {
console.log('client connected');
});
/* CONSOLE INTERFACE, USED TO MANUALLY INSERT SOME KIND OF VARIABLES*/
//stdin interaction
var stdin = process.openStdin();
var command = '';
var commandmode = false;
var bufferdata;
var command = 0;
//serial stuff
var serialport = require('serialport');
var SerialPort = serialport.SerialPort;
//portName = process.argv[2];
portName = "COM4"
//parsing commandline argument as comport name
var myPort = new SerialPort(portName, {
baudRate: 500000, // choose between: 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, or 50
// look for return and newline at the end of each data packet:
parser: serialport.parsers.readline("\n")
});
myPort.on('open', showPortOpen);
myPort.on('data', sendSerialData);
myPort.on('close', showPortClose);
myPort.on('error', showError);
var datacount = 0;
function showPortOpen() {
console.log('port open. Data rate: ' + myPort.options.baudRate);
}
var timestamp;
var timestampold;
var dt;
function pad(num, size) {
var s = "0000" + num;
return s.substring(s.length - size);
}
function padd(num, size) {
var s = "00000000" + num;
return s.substring(s.length - size);
}
var vrms = [];
var irms = [];
var torq = [];
var speed = [];
var vraw = [];
var iraw = [];
function sendSerialData(data) {
if (datacount === 0) {
timestampold = Date.now();
}
if (datacount === 10) {
console.log(data);
}
if (datacount === 1000) {
timestamp = Date.now();
dt = timestamp - timestampold;
var samplerate;
var datalength = data.length + 1;
samplerate = datacount * 1000 / dt;
var troughput = datalength * samplerate;
var troughputp = 800 * troughput / 500000;
console.log(datacount + " data has been recorded. time elapsed:" + dt + ", samplerate:" + samplerate + " troughput:" + troughput + "/" + troughputp + "%");
}
var parseddata = data.split(",");
vraw.push(parseInt(parseddata[0], 16));
iraw.push(parseInt(parseddata[1], 16));
torq.push(parseInt(parseddata[2], 16));
speed.push(parseInt(parseddata[3], 16));
rmsfast(vraw[datacount], iraw[datacount]);
//var rawlog = padd(datacount,8) + "," + pad(vraw[datacount],4) + ","+ pad(iraw[datacount],4) +","+ pad(speed[datacount],4)+","+ pad(torq[datacount],4);
//var rawlog = padd(datacount, 8) + "," + vraw[datacount] + "," + iraw[datacount] + "," + speed[datacount] + "," + torq[datacount] + ">>" + vrms[datacount] + "," + irms[datacount];
//fs.appendFileSync('raw.txt', rawlog);
//console.log(rawlog);
++datacount;
}
function showPortClose() {
console.log('port closed.');
}
function showError(error) {
console.log('Serial port error: ' + error);
}
var varray = [0];
// zero setup;
var mid = 2048; //ideal; changed on zerocross detection
/* the data from microcontroller is as such: VVV,III,TTT,NNN
CC = COMMAND/RUNNING MODE
VVVV = VOLTAGE READING
IIII = CURRENT READING
TTTT = TORQUE READING
NNNN = SPEED (RPM) READING
Z = IS ZERO(0=false,1=voltage,2=current)
delta t between data (microsecond);
*/
var bufferV = [0];
var bufferI = [0];
var datacount;
var dataindex; // index of data called on the below stuff
var rmslength = 80;
var sigmaVsquared = 0;
var sigmaIsquared = 0;
var lastVvalue = 0;
var lastIvalue = 0;
var Vrms = 0;
var avgV = 0;
var avgI = 0;
function rmsfast(newVoltage, newCurrent) { // example use = rmsfast(data,buffer,)
var newSqVoltage = Math.pow(newVoltage, 2);
var newSqCurrent = Math.pow(newCurrent, 2);
bufferV.push(newSqVoltage);
if (bufferV.length === 80) {
lastVvalue = bufferV.shift();
} else {
//lastVvalue = newSqVoltage;
}
avgV += ((newSqVoltage - lastVvalue) / 80);
Vrms = math.sqrt(avgV);
bufferI.push(newSqCurrent);
lastIvalue = bufferI.shift();
avgI += (newSqCurrent - lastIvalue) / 80;
var Irms = math.sqrt(avgI);
var darn = math.sqrt(4000000);
if (datacount < 1000) {
var darz = Number.isInteger(newSqVoltage);
var vavg = avgV;
var vrmss = vrms;
console.log(newVoltage + "\t---" + avgV + "\t---" + Vrms);
}
if (datacount === 1000) {
myPort.close(process.exit());
}
vrms.push(Vrms);
irms.push(Irms);
}
server.listen(2000); // listening to the port
stdin.addListener("data", function(cons) { //"listening" to stdin
command = cons.toString().trim();
});

Related

Node JS: res.send is not a function

I'm in the midst of making my first simple counter strike api bot with nodeJS, however I'm running into some problems with the res.send function. When I use it it throws the following error: "res.send is not a function". I've tried moving the res.send outside of the request, however that only updates my data after I refresh the page. Any help would be appreciated as I've been stuck on this problem for a while now.
My code :
const path = require('path')
const express = require('express')
var request = require("request")
/*const getSkinfo = require('./wyrskin')*/
const app = express()
const publicDirectoryPath = path.join(__dirname, '/public')
var skins_str = "empty"
app.use(express.static(publicDirectoryPath))
/*var string_skin = (JSON.stringify(getSkinfo))*/
app.get('/skin', (req, res) => {
request('https://api.steamapis.com/market/items/730?api_key=xyz', { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
var skins = []
var score = 0
var i;
for (i = 0; i < body.data.length; i++) {
var name = body.data[i].market_name
var price = body.data[i].prices
var img_url = body.data[i].image
if (name.includes('Factory New') && !name.includes('StatTrak')) {
skins.push(name + "," + price.avg + "^" + img_url)
}
}
var num1 = Math.floor(Math.random() * 1215);
var num2 = Math.floor(Math.random() * 1215);
var out1 = "A : " + skins[num1]
var out2 = "B : " + skins[num2]
var mySubString1 = out1.substring(
out1.lastIndexOf(",") + 1,
out1.lastIndexOf("^")
);
var price1 = parseFloat(mySubString1)
var mySubString2 = out2.substring(
out2.lastIndexOf(",") + 1,
out2.lastIndexOf("^")
);
var price2 = parseFloat(mySubString2)
skins_str = (out1 + " ~ " + out2)
console.log(skins_str)
res.send({ skins: skins_str })
})
})
app.listen(3000, () => {
console.log('Server is up on port 3000.')
})
Thank you !
This isn't really how I would proxy a request from a node server. Checkout the node-fetch npm package. Promises really clean up the code.
But the error in your code is that you have another res variable in the scope of this function. If you rename it to response it should work?
Also use res.json() instead if you are just sending an object in your response.
Hope this helps!
app.get('/skin', (req, res) => {
request('https://api.steamapis.com/market/items/730?api_key=xyz', { json: true }, (err, response, body) => {
if (err) { return console.log(err); }
var skins = []
var score = 0
var i;
for (i = 0; i < body.data.length; i++) {
var name = body.data[i].market_name
var price = body.data[i].prices
var img_url = body.data[i].image
if (name.includes('Factory New') && !name.includes('StatTrak')) {
skins.push(name + "," + price.avg + "^" + img_url)
}
}
var num1 = Math.floor(Math.random() * 1215);
var num2 = Math.floor(Math.random() * 1215);
var out1 = "A : " + skins[num1]
var out2 = "B : " + skins[num2]
var mySubString1 = out1.substring(
out1.lastIndexOf(",") + 1,
out1.lastIndexOf("^")
);
var price1 = parseFloat(mySubString1)
var mySubString2 = out2.substring(
out2.lastIndexOf(",") + 1,
out2.lastIndexOf("^")
);
var price2 = parseFloat(mySubString2)
skins_str = (out1 + " ~ " + out2)
console.log(skins_str)
res.json({ skins: skins_str })
})
})
app.listen(3000, () => {
console.log('Server is up on port 3000.')
})

Join multiple room in kurento

I want to create an application that allows a user to join multiple video call rooms in kurento.
I wrote the following code:
function joinRooms() {
var userId = document.getElementById('expertid').value;
console.log("UserID = " + userId);
var roomIds = document.getElementById('roomids').value.split(",");//Assume that we have 2 rooms r1 & r2
var userIdAlias = [];
for (var i = 0; i < roomIds.length; i++) {
userIdAlias[i] = userId + "(" + i + ")";
console.log("User alias = " + userIdAlias[i]);
}
var wsUri = 'wss://' + location.host + '/room';
kurento = KurentoRoom(wsUri, function(error, kurento) {
if (error)
return console.log(error);
for (let i = 0; i < roomIds.length; i++) {
//console.log("Start loop Roomid = " + roomId);
rooms[i] = kurento.Room({
room : roomIds[i],
user : userIdAlias[i],
subscribeToStreams : true
});
localStreams[i] = kurento.Stream(rooms[i], {
audio : true,
video : true,
data : true
});
localStreams[i].addEventListener("access-accepted", function() {
var playVideo = function(stream) {
var participantId = stream.getParticipant().getID();
var userId = document.getElementById('expertid').value;
console.log("userId = " + userId + ", participantId = " + participantId);
if (!userIdAlias.includes(participantId)) {
var elementId = "video-" + stream.getGlobalID();
var div = document.createElement('div');
div.setAttribute("id", elementId);
document.getElementById("participants").appendChild(div);
stream.playThumbnail(elementId);
// Check color
var videoTag = document.getElementById("native-" + elementId);
var userId = stream.getGlobalID();
var canvas = document.createElement('CANVAS');
checkColor(videoTag, canvas, userId);
}
}
rooms[i].addEventListener("room-connected", function(){
var j = i;
return function(roomEvent) {
document.getElementById('room-header').innerText = 'ROOM \"'
+ roomIds[j] + '\"';
//document.getElementById('join').style.display = 'none';
document.getElementById('room').style.display = 'block';
localStreams[j].publish();
var streams = roomEvent.streams;
for (var streamsIdx = 0; streamsIdx < streams.length; streamsIdx++) {
playVideo(streams[streamsIdx]);
}
}
});
rooms[i].addEventListener("stream-added", function(streamEvent) {
playVideo(streamEvent.stream);
});
rooms[i].addEventListener("stream-removed", function(streamEvent) {
var element = document.getElementById("video-"
+ streamEvent.stream.getGlobalID());
if (element !== undefined) {
element.parentNode.removeChild(element);
}
});
playVideo(localStreams[i]);
rooms[i].connect();
});
localStreams[i].init();
}
});
}
However, the code does not work. The log in server said that there is only one user request to join room r2 but not r1.
I think the reason is Javascript works with too many asynchronous task so it worked incorrectly.
Can you give some advice about the way to joining multiple rooms in kurento?

Javascript with Ajax working fine in Mozilla but not in Chrome

I'm using XMLHTTPREQUEST synchronous and while the request is getting fulfilled, I hide everything on page and show a progress message. This works fine in Mozilla but doesn not in Chrome.
Mozilla firefox:
For chrome:
[after submit][3]
here is my javascript code:
if (valid) {
document.getElementById('contentwrapper').style.display="none";
document.getElementById('contentwrapper').style.visibility="hidden";
var cboxes = document.getElementsByName('items[]');
var len = cboxes.length;
var res1;
var res2;
var res3;
var res4;
var arrResult;
for (var i = 0; cboxes[i]; ++i) {
if (cboxes[i].checked) {
checkedValue = cboxes[i].value;
arrResult = checkedValue.split(',');
mobileNo=arrResult[0];
if(arrResult[0].trim().startsWith('0')){
res1 = arrResult[0].substring(1,arrResult[0].length);
}else{
res1 = arrResult[0];
}
res2 = arrResult[1];
res3 = arrResult[2];
res4 = arrResult[3];
requestSender(1, res1, res2, res3, res4);
}
}
function requestSender(code, mobile, operator, productCode, amount) {
var http = getHTTPObject();
var enterKeyHandler = true;
var reqNum = 0;
var seqNum = 0;
var dataCount = 0;
var Values = "";
var code;
var comments = "";
reqCode = code;
if (code == 1) {
var agentcode = '<%=payeeaccountno%>';
var pin = document.getElementById("mpin").value;
source = agentcode; // source and agent code both are same.
operator = operator;
destination = mobile;
productCode = productCode;
if (destination.charAt(0) == '0') {
destination = destination.replace(/^0+/, "");
}
var amt = amount;
var amtPrd = new Array();
amtPrd = amt.split("#");
if (amtPrd.length > 0)
{
amount = amtPrd[0];
// productCode = amtPrd[1];
}
else
{
amount = 0;
}
clienttype = "SELFCARE";
vendorcode = '<%=vendorcode%>';
dataCount = '<%=cryptHandler.encrypt("8",session.getId()+session.getId())%>';
reqNum = '<%=cryptHandler.encrypt("1",session.getId()+session.getId())%>';
seqNum = '<%=cryptHandler.encrypt("2",session.getId()+session.getId())%>';
Values = "&var1=" + escape(agentcode) + "&var2=" + escape(pin) + "&var3=" + escape(amount) + "&var4=" + escape(mobile) + "&var5=" + escape(productCode) + "&var6=" + escape(clienttype) + "&var7=" + escape(operator) + "&var8=" + escape(vendorcode);
}
var varReq = "../Comman/requestForwarder.jsp?page=" + escape("<%=reqPageName%>") + "&reqNum=" + escape(reqNum) + "&seqNum=" + escape(seqNum) + "&dataCount=" + escape(dataCount) + Values;
varReq = varReq.replace(/\+/g, "%2B");
http.open("GET", varReq, false);
httpBuffer = http;
reqCodeBuffer = reqCode;
http.onreadystatechange = responseHandler;
http.send(null);
}
You should actually post some code or at least print the messages in the developer console (ctr + shift + J)
However, the stem of your issue is probably the fact that you are trying to use a synchronous xmlhttpRequest on the "main" execution thread.
Its a bad practice (since It blocks all code from running until the server "answers" your request) and browsers are starting to phase it out. So, if you are using a newer version of chrome, its likely not running the code and complaining about the sync request.
Either use a Web Worker (js version of thread) to run the synchronous XMLHTTPRequest(s) or, better yet, if possible, use the asynchronous version.
Further reading:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests

Socket io vs Nodejs: died when 2k concurrent user?

My project have one module. It need to be real-time push data from json file from Server to Client. I am using Socket IO and Nodejs for listenning client. My idea is server nodejs setInterval every 5 second and check current time, and if valid then read json file and emit to all client. I try with 2k client and socket io and nodejs died. I read data from folder with name ttkqxs, file name format is 1.json, 2.json. Read and push very good but with 2k client and more i have trouble. Here is my code, what problem with it ???
// Dependencies
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var fs = require('fs');
var async = require('async');
// Time config
var MN_START_HOUR = 16,
MN_START_MIN = 5,
MN_END_MIN = 45,
MT_START_HOUR = 17,
MT_START_MIN = 5,
MT_END_MIN = 45,
MB_START_HOUR = 18,
MB_START_MIN = 5,
MB_END_MIN = 45;
var intervalTime = 5000;
var MB_ID = 22;
var MB = 1;
var MT = 2;
var MN = 3;
var firstTimeMb = true;
var firstTimeMt = true;
var firstTimeMn = true;
// Server ready
http.listen(3113, function () {
console.log('Server listening on port: 3113 ');
var timer = setInterval(function () {
var date = new Date();
var min = date.getMinutes();
var sec = date.getSeconds();
var hour = date.getHours();
console.log("CurrentTime: " + hour + ":" + min + ":" + sec);
// Mien Bac
if (hour === MB_START_HOUR && min >= MB_START_MIN && min <= MB_END_MIN) {
if (firstTimeMb) {
firstTimeMb = false;
emitRegionData(MB, 'first_time_' + MB);
}
emitRegionData(MB, 'return_g_result_' + MB);
emitProvincesData(MB);
}
// Miền Trung
if (hour === MT_START_HOUR && min >= MT_START_MIN && min <= MT_END_MIN) {
if (firstTimeMt) {
firstTimeMt = false;
emitRegionData(MT, 'first_time_' + MT);
}
emitRegionData(MT, 'return_g_result_' + MT);
emitProvincesData(MT);
}
//Miền Nam
if (hour === MN_START_HOUR && min >= MN_START_MIN && min <= MN_END_MIN) {
if (firstTimeMn) {
firstTimeMn = false;
emitRegionData(MN, 'first_time_' + MN);
}
emitRegionData(MN, 'return_g_result_' + MN);
emitProvincesData(MN);
}
// reset first time
if (hour == 23) {
firstTimeMb = true;
firstTimeMt = true;
firstTimeMn = true;
}
}, intervalTime);
});
/**
* Get province data from json file and emit to all client
* Desktop: Use in home page, province page
* Mobile: Only use in province page
* #param {int} pid Province id
* #returns
*/
function emitProvinceData(pid) {
var fileName = __dirname + '/ttkqxs/' + pid + '.json';
fs.exists(fileName, function () {
fs.readFile(fileName, function (err, content) {
if (err) {
throw err;
}
io.sockets.emit('return_p_result_' + pid, content);
});
});
}
/**
* Get province data from json file and emit to all client
* Desktop: Use in home page, province page
* Mobile: Only use in province page
* #param {int} pid Province id
* #returns
*/
function emitProvincesData(rid) {
var fileName = __dirname + '/ttkqxs/mien' + rid + '.json';
fs.exists(fileName, function () {
fs.readFile(fileName, function (err, content) {
if (err) {
throw err;
}
var ids = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(content)));
for (var i in ids) {
emitProvinceData(ids[i].id);
}
});
});
}
/**
* Emit Region data
* Use in mobile for multiple province
* #param {int} rid Region id
* #returns
*/
function emitRegionData(rid, eventName) {
var fileName = __dirname + '/ttkqxs/mien' + rid + '.json';
fs.exists(fileName, function () {
fs.readFile(fileName, function (err, content) {
if (err) {
throw err;
}
var ids = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(content)));
var files = [];
for (var i in ids) {
var pFileName = __dirname + '/ttkqxs/' + ids[i].id + '.json';
files.push(pFileName);
}
async.map(files, readAsync, function (err, results) {
io.sockets.emit(eventName, JSON.stringify(results));
});
});
});
}
/**
* Read file Async
* #param {string} file File Path
* #param {function} callback
* #returns
*/
function readAsync(file, callback) {
fs.readFile(file, 'utf8', callback);
}

how to run at command through chrome serial api

i want to run at command at my hardware thorugh crome serial api
I use this Opensource code
https://github.com/GoogleChrome/chrome-app-samples/tree/master/servo
this working only for only integer
i want to pass string in the serial port my code is like following
var connectionId = -1;
function setPosition(position) {
var buffer = new ArrayBuffer(1);
var uint8View = new Uint8Array(buffer);
uint8View[0] = '0'.charCodeAt(0) + position;
chrome.serial.write(connectionId, buffer, function() {});
};
function setTxt(data) {
// document.getElementById('txt').innerHTML = data;
var bf = str2ab(data)
chrome.serial.write(connectionId, bf, function() {});
};
function str2ab(str) {
len = str.length;
var buf = new ArrayBuffer(len*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function onRead(readInfo) {
var uint8View = new Uint8Array(readInfo.data);
var value1 = String.fromCharCode(uint8View[0])
var value = uint8View[0] - '0'.charCodeAt(0);
var rotation = value * 18.0;
// var dataarr = String.fromCharCode.apply(null, new Uint16Array(readInfo.data));
//alert(rotation);
if(uint8View[0])
document.getElementById('txt').innerHTML = document.getElementById('txt').innerHTML + value1;
document.getElementById('image').style.webkitTransform =
'rotateZ(' + rotation + 'deg)';
// document.getElementById('txt').innerHTML=uint8View[0];
// Keep on reading.
chrome.serial.read(connectionId, 1, onRead);
};
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function onOpen(openInfo) {
connectionId = openInfo.connectionId;
if (connectionId == -1) {
setStatus('Could not open');
return;
}
setStatus('Connected');
setPosition(0);
chrome.serial.read(connectionId, 1, onRead);
};
function setStatus(status) {
document.getElementById('status').innerText = status;
}
function buildPortPicker(ports) {
var eligiblePorts = ports.filter(function(port) {
return !port.match(/[Bb]luetooth/);
});
var portPicker = document.getElementById('port-picker');
eligiblePorts.forEach(function(port) {
var portOption = document.createElement('option');
portOption.value = portOption.innerText = port;
portPicker.appendChild(portOption);
});
portPicker.onchange = function() {
if (connectionId != -1) {
chrome.serial.close(connectionId, openSelectedPort);
return;
}
openSelectedPort();
};
}
function openSelectedPort() {
var portPicker = document.getElementById('port-picker');
var selectedPort = portPicker.options[portPicker.selectedIndex].value;
chrome.serial.open(selectedPort, onOpen);
}
onload = function() {
var tv = document.getElementById('tv');
navigator.webkitGetUserMedia(
{video: true},
function(stream) {
tv.classList.add('working');
document.getElementById('camera-output').src =
webkitURL.createObjectURL(stream);
},
function() {
tv.classList.add('broken');
});
document.getElementById('position-input').onchange = function() {
setPosition(parseInt(this.value, 10));
};
document.getElementById('txt-input').onchange = function() {
setTxt(this.value);
// document.getElementById('txt').innerHTML = this.value;
};
chrome.serial.getPorts(function(ports) {
buildPortPicker(ports)
openSelectedPort();
});
};
string is the passing through serial but this command not run without enter press how to do it any one know
thanks in advance :)
need a \n at the end of string
example:
writeSerial( '#;Bit_Test;*;1;' + '\n' );
take a look at this project http://www.dataino.it/help/document_tutorial.php?id=13

Categories

Resources