Commit 066e8ed7 authored by Max-Ferdinand Suffel's avatar Max-Ferdinand Suffel
Browse files

enhance serial port protocol to enable led controlling from the webbrowser...

enhance serial port protocol to enable led controlling from the webbrowser while audio data is streamed by the webaudio api
parent 67535016
......@@ -44,7 +44,7 @@ rl = readline.createInterface(process.stdin, process.stdout);
rl.on('close', function() {
if (nmwSerialPortOpen) {
// Disconnect from the Neurosky MindWave.
nmwSerialPort.write(new Buffer([DISCONNECT], 'hex'), function(error, results) { // TODO: remove results!
nmwSerialPort.write(new Buffer([DISCONNECT]), function(error, results) { // TODO: remove results!
if (error || results != 1) {
console.log("Could not disconnect from the Neurosky MindWave." + err);
process.exit(1);
......@@ -71,7 +71,7 @@ nmwSerialPort.on("open", function (error) {
nmwSerialPort.on("data", receivePackets);
// Autoconnect to the first discovered Neurosky MindWave.
nmwSerialPort.write(new Buffer([AUTOCONNECT], 'hex'), function(error, results) {
nmwSerialPort.write(new Buffer([AUTOCONNECT]), function(error, results) {
if (error || results != 1) {
console.log("Could not autoconnect to the Neurosky MindWave." + err);
process.exit(1);
......@@ -132,7 +132,7 @@ function receivePackets (data) {
if (DEBUG) console.log("PAYLOAD == SYNC");
} else { // Pre-Condition: payLoadLength < 170
// Create a suitable payload buffer for the upcoming serial data.
payloadBuffer = new Buffer(payloadLength, 'hex');
payloadBuffer = new Buffer(payloadLength);
payloadIndex = 0;
checksum = 0;
state = ProcessState.PAYLOAD;
......
......@@ -18,15 +18,58 @@
socket.binaryType = "arraybuffer";
socket.onopen = function(e) {
function array2str(ua) {
var h = '';
for (var i = 0; i < ua.length; i++) {
h += "\\0x" + ua[i].toString(16);
}
return h;
}
function concatBuffers(buffer1, buffer2) {
//console.log(buffer1.byteLength + buffer2.byteLength); // 4097
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
//console.log(array2str(tmp));
return tmp.buffer;
}
function sendLightData(color, brightness) {
if (brightness < 0 || brightness > 255) {
throw new Error('Brightness must be between 0 and 255 (inclusive)');
}
var outputBuffer;
if (color == "red") {
outputBuffer = new Uint8Array([0x01, brightness]);
} else if (color == "blue") {
outputBuffer = new Uint8Array([0x02, brightness]);
} else {
throw new Error('Color must be \'red\' or \'blue\'');
}
socket.send(outputBuffer);
}
function float32To16bitPCM(input) {
var output = new Int16Array(input.length);
for (var i = 0; i < input.length; ++i) {
var sample = input[i]; //Math.max(-1, Math.min(1, buffer[l]));
var sample = input[i]; //saturation: Math.max(-1, Math.min(1, buffer[l]));
output[i] = (sample < 0) ? (sample * 0x8000) : (sample * 0x7FFF);
}
return output.buffer;
}
function sendAudioData(data) {
var pcmBuffer = float32To16bitPCM(data);
var header = new Uint8Array([0x00]);
//console.log(array2str(header));
//console.log(array2str(new Uint8Array(pcmBuffer)));
var outputBuffer = concatBuffers(header.buffer, pcmBuffer);
socket.send(outputBuffer);
}
bufferLoader = new BufferLoader(audioCxt, ['techno.mp3'], finishedLoading);
bufferLoader.load();
......@@ -43,15 +86,41 @@
var audioProcessor = audioCxt.createScriptProcessor(0, 1, 1);
audioProcessor.onaudioprocess = function(e) {
var leftChannelData = e.inputBuffer.getChannelData(0);
socket.send(float32To16bitPCM(leftChannelData));
sendAudioData(e.inputBuffer.getChannelData(0));
};
//merge.connect(audioProcessor);
source1.connect(audioProcessor);
audioProcessor.connect(audioCxt.destination);
source1.start(0);
}
function test_light () {
var brightness_red = 0;
var red_dir = 1;
var brightness_blue = 255;
var blue_dir = -1;
return function () {
sendLightData("red", brightness_red);
sendLightData("blue", brightness_blue);
brightness_red += red_dir*5;
if (brightness_red >= 255) {
red_dir = -1;
} else if (brightness_red <= 0) {
red_dir = 1;
}
brightness_blue += blue_dir*5;
if (brightness_blue >= 255) {
blue_dir = -1;
} else if (brightness_blue <= 0) {
blue_dir = 1;
}
};
}
setInterval(test_light(), 10); // Refresh the light every 10 milliseconds.
};
}
</script>
......
......@@ -3,17 +3,47 @@
// Create serial port object.
var SerialPort = require("serialport").SerialPort;
var teensySerialPort = new SerialPort("/dev/ttyACM0", {
baudRate : 115200 // USB full-speed.
});
var teensySerialPort;
var serialPortReconnectAttempt = 0;
var serialPortConnected = false;
teensySerialPort.on("open", function (err) {
if (err) throw err;
teensySerialPort.on("data", receiveSerialData);
console.log("Serial port /dev/ttyACM0 successfully openend.");
});
function connectToSerialPort () {
if (!serialPortConnected) {
++serialPortReconnectAttempt;
if (serialPortReconnectAttempt > 3) {
console.log('Cannot connect to Teensy via serial port');
process.exit(0);
}
console.log("Connect to Teensy via serial port attempt: #" + serialPortReconnectAttempt);
teensySerialPort = new SerialPort("/dev/ttyACM0", {
baudRate : 115200 // USB full-speed.
});
teensySerialPort.on("open", serialPortOnOpen);
teensySerialPort.on("error", serialPortOnError);
}
}
function serialPortOnOpen (err) {
if (err) throw err;
serialPortConnected = true;
serialPortReconnectAttempt = 0;
teensySerialPort.on("data", serialPortOnData);
teensySerialPort.on("close", function(err) {
if (err) throw err;
serialPortConnected = false;
serialPortReconnectAttempt = 0;
setTimeout(connectToSerialPort, 1000);
});
console.log('Serial port /dev/ttyACM0 to Teensy successfully openend');
}
function serialPortOnError (err) {
if (err) console.log(err);
serialPortConnected = false;
setTimeout(connectToSerialPort, 1000);
};
function receiveSerialData (data) {
function serialPortOnData (data) {
console.log(data.toString('ascii'));
//for (var i = 0; i < data.length; i++) {
// var next_byte = data.readUInt8(i);
......@@ -21,10 +51,12 @@ function receiveSerialData (data) {
//}
}
function writeAndDrain (data, callback) {
teensySerialPort.write(data, function () {
teensySerialPort.drain(callback);
});
function writeAndDrainSerialPort (data, callback) {
if (serialPortConnected) {
teensySerialPort.write(data, function () {
teensySerialPort.drain(callback);
});
}
}
// Create WebSocket server object.
......@@ -40,7 +72,7 @@ wsServer = ws.createServer(function (conn) {
stream.on('data', function(data) {
//speaker.write(data);
writeAndDrain(data, function(err) {
writeAndDrainSerialPort(data, function(err) {
if (err) throw err;
len += data.length;
console.log(len);
......@@ -55,3 +87,5 @@ wsServer = ws.createServer(function (conn) {
}).listen(port);
console.log('Websocket server listening on port: ', port);
connectToSerialPort ();
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment