572 lines
15 KiB
JavaScript
572 lines
15 KiB
JavaScript
/**
|
|
*
|
|
* User: Martin Donnelly
|
|
* Date: 2016-05-20
|
|
* Time: 10:13
|
|
*
|
|
*/
|
|
/* global CAPABILITY, inheritsFrom, capabilityManager */
|
|
/* global ble */
|
|
/* jshint browser: true , devel: true*/
|
|
|
|
var CC2650_ACCEL;
|
|
CC2650_ACCEL = function(p) {
|
|
'use strict';
|
|
this.name = 'Accelerometer';
|
|
this.deviceID = p.deviceID || null;
|
|
this.target = p.target || null;
|
|
|
|
this.capabilityID = 'F000AA80-0451-4000-B000-000000000000';
|
|
this.serviceDef = {
|
|
service: 'F000AA80-0451-4000-B000-000000000000',
|
|
data: 'F000AA81-0451-4000-B000-000000000000', // Read/notify 3 bytes X : Y : Z
|
|
notification: 'F0002902-0451-4000-B000-000000000000',
|
|
configuration: 'F000AA82-0451-4000-B000-000000000000', // Read/write 1 byte
|
|
period: 'F000AA83-0451-4000-B000-000000000000' // Read/write 1 byte Period = [Input*10]ms
|
|
};
|
|
this.frames = {};
|
|
|
|
this.$id = {};
|
|
this.$result = {};
|
|
this.data = {
|
|
gyro: {x: [], y: [], z: []},
|
|
accel: {x: [], y: [], z: []},
|
|
mag: {x: [], y: [], z: []}
|
|
};
|
|
|
|
this.setFrame();
|
|
|
|
this.sensorMpu9250GyroConvert = function(data) {
|
|
return (data * 1.0) / (65536 / 500);
|
|
};
|
|
|
|
this.sensorMpu9250AccConvert = function(data) {
|
|
// Change /2 to match accel range...i.e. 16 g would be /16
|
|
return (data * 1.0) / (32768 / 2);
|
|
};
|
|
|
|
this.processData = function(data) {
|
|
var a = new Int16Array(data);
|
|
var calcData = {
|
|
gyro: {
|
|
x: this.sensorMpu9250GyroConvert(a[0]),
|
|
y: this.sensorMpu9250GyroConvert(a[1]),
|
|
z: this.sensorMpu9250GyroConvert(a[2])
|
|
}, accel: {
|
|
x: this.sensorMpu9250AccConvert(a[3]),
|
|
y: this.sensorMpu9250AccConvert(a[4]),
|
|
z: this.sensorMpu9250AccConvert(a[5])
|
|
}, mag: {
|
|
x: a[6], y: a[7], z: a[8]
|
|
}
|
|
};
|
|
|
|
return calcData;
|
|
};
|
|
this.onAccelerometerData = function(data) {
|
|
// Console.log(data);
|
|
var message;
|
|
var calcData;
|
|
|
|
function gString(v) {
|
|
return [v.toFixed(3),'G'].join('');
|
|
}
|
|
|
|
function aString(v) {
|
|
return [v.toFixed(3),'\'/s'].join('');
|
|
}
|
|
|
|
function mString(v) {
|
|
return [v.toFixed(3),'mT'].join('');
|
|
}
|
|
calcData = this.processData(data);
|
|
|
|
message = 'Gyro <br/>' + 'X: ' + calcData.gyro.x + '<br/>' + 'Y: ' + calcData.gyro.y + '<br/>' + 'Z: ' + calcData.gyro.z + '<br/>' + 'Accel <br/>' + 'X: ' + calcData.accel.x + '<br/>' + 'Y: ' + calcData.accel.y + '<br/>' + 'Z: ' + calcData.accel.z + '<br/>' + 'Mag <br/>' + 'X: ' + calcData.mag.x + '<br/>' + 'Y: ' + calcData.mag.y + '<br/>' + 'Z: ' + calcData.mag.z + '<br/>';
|
|
|
|
this.state = message;
|
|
|
|
this.$result[this.frames.gyroID + '-x'].text(gString(calcData.gyro.x));
|
|
this.$result[this.frames.gyroID + '-y'].text(gString(calcData.gyro.y));
|
|
this.$result[this.frames.gyroID + '-z'].text(gString(calcData.gyro.z));
|
|
|
|
this.$result[this.frames.accelID + '-x'].text(aString(calcData.accel.x));
|
|
this.$result[this.frames.accelID + '-y'].text(aString(calcData.accel.y));
|
|
this.$result[this.frames.accelID + '-z'].text(aString(calcData.accel.z));
|
|
|
|
this.$result[this.frames.magID + '-x'].text(mString(calcData.mag.x));
|
|
this.$result[this.frames.magID + '-y'].text(mString(calcData.mag.y));
|
|
this.$result[this.frames.magID + '-z'].text(mString(calcData.mag.z));
|
|
|
|
this.data.gyro.x = this.storeData(calcData.gyro.x, this.data.gyro.x);
|
|
this.data.gyro.y = this.storeData(calcData.gyro.y, this.data.gyro.y);
|
|
this.data.gyro.z = this.storeData(calcData.gyro.z, this.data.gyro.z);
|
|
|
|
this.data.accel.x = this.storeData(calcData.accel.x, this.data.accel.x);
|
|
this.data.accel.y = this.storeData(calcData.accel.y, this.data.accel.y);
|
|
this.data.accel.z = this.storeData(calcData.accel.z, this.data.accel.z);
|
|
|
|
this.data.mag.x = this.storeData(calcData.mag.x, this.data.mag.x);
|
|
this.data.mag.y = this.storeData(calcData.mag.y, this.data.mag.y);
|
|
this.data.mag.z = this.storeData(calcData.mag.z, this.data.mag.z);
|
|
|
|
// Console.log(JSON.stringify(this.data));
|
|
// Console.log(this.state);
|
|
};
|
|
|
|
this.startService = function() {
|
|
|
|
this.maxLength = 500;
|
|
if (this.deviceID !== null) {
|
|
|
|
console.log('Starting CC2650 Accelerometer Service on ', this.deviceID);
|
|
console.log(this.serviceDef);
|
|
|
|
this.setInternalID();
|
|
this.insertFrame('gyro');
|
|
this.insertFrame('accel');
|
|
this.insertFrame('mag');
|
|
|
|
ble.startNotification(this.deviceID,
|
|
this.serviceDef.service,
|
|
this.serviceDef.data,
|
|
this.onAccelerometerData.bind(this),
|
|
this.onError);
|
|
|
|
// Turn accelerometer on
|
|
var configData = new Uint16Array(1);
|
|
// Turn on gyro, accel, and mag, 2G range, Disable wake on motion
|
|
configData[0] = 0x007F;
|
|
ble.write(this.deviceID,
|
|
this.serviceDef.service,
|
|
this.serviceDef.configuration,
|
|
configData.buffer,
|
|
function() { console.log('Started accelerometer.'); },
|
|
this.onError);
|
|
|
|
var periodData = new Uint8Array(1);
|
|
periodData[0] = 0x0A;
|
|
ble.write(this.deviceID,
|
|
this.serviceDef.service,
|
|
this.serviceDef.period,
|
|
periodData.buffer,
|
|
function() { console.log('Configured accelerometer period.'); },
|
|
this.onError);
|
|
}
|
|
|
|
};
|
|
|
|
this.advancedGraphFFT = function(mode, data, subID) {
|
|
var xstep;
|
|
var scalePos;
|
|
var lm;
|
|
var ceiling;
|
|
var elm;
|
|
var text2ID;
|
|
var ceilingLimit;
|
|
var calcArray;
|
|
var floor;
|
|
var _subID;
|
|
var _data;
|
|
var text1ID;
|
|
var lineID;
|
|
var max;
|
|
var yscale = 125;
|
|
var height = 125;
|
|
|
|
var yOffset = 71;
|
|
|
|
var reducer = function(p, v) {
|
|
return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
|
|
};
|
|
|
|
|
|
var parts = ['x', 'y', 'z'];
|
|
var _newData = {x: [],y: [],z: []};
|
|
|
|
if (subID === 'gyro') {
|
|
height = 300;
|
|
yscale = 300;
|
|
}
|
|
|
|
|
|
|
|
_data = data || this.data;
|
|
|
|
_subID = subID || '';
|
|
|
|
// LineID = [this.frameID , _subID , '-line'].join('');
|
|
text1ID = [this.frameID, _subID, '-txt1'].join('');
|
|
text2ID = [this.frameID, _subID, '-txt2'].join('');
|
|
ceiling = 0;
|
|
if (_data.x.length > 0) {
|
|
|
|
max = 2;
|
|
|
|
for (var lineMode = 0; lineMode < parts.length; lineMode++) {
|
|
|
|
|
|
lm = parts[lineMode];
|
|
|
|
var data = new complex_array.ComplexArray(_data[lm]);
|
|
|
|
|
|
data.FFT();
|
|
|
|
data.forEach(function(c_value, i) {
|
|
ceiling = reducer(c_value.real ,ceiling);
|
|
_newData[lm].push(c_value.real);
|
|
});
|
|
|
|
//Ceiling = _data[lm].reduce(reducer);
|
|
|
|
console.log('ceiling:', ceiling);
|
|
|
|
|
|
}
|
|
|
|
if (ceiling > 500) {
|
|
max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 50) * 50) : max;
|
|
} else {
|
|
max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 10) * 10) : max;
|
|
}
|
|
ceiling = max;
|
|
|
|
floor = ceiling * -1;
|
|
ceilingLimit = ceiling;
|
|
console.log('ceiling:',ceiling);
|
|
|
|
|
|
|
|
scalePos = (yscale / 2) / ceiling;
|
|
|
|
xstep = (680 - 46) / this.maxLength;
|
|
|
|
yOffset = ((height - (14 + 12)) / 2) + 12;
|
|
|
|
|
|
|
|
//Var xstep = 2.34;
|
|
|
|
for (lineMode = 0; lineMode < parts.length; lineMode++) {
|
|
|
|
lm = parts[lineMode];
|
|
var startX = 46 + (this.maxLength - _newData[lm].length) * xstep;
|
|
|
|
calcArray = [];
|
|
|
|
lineID = this.frameID + _subID + '-' + lm + '-line';
|
|
for (var x = 0; x < _newData[lm].length; x++) {
|
|
|
|
calcArray.push((startX + (x * xstep)).toFixed(2) + ',' + (yOffset - ((_newData[lm][x]) * scalePos)).toFixed(
|
|
2));
|
|
|
|
}
|
|
|
|
elm = document.getElementById(lineID);
|
|
|
|
elm.setAttribute('points', calcArray.join(' '));
|
|
|
|
}
|
|
|
|
elm = document.getElementById(text1ID);
|
|
elm.textContent = ceilingLimit;
|
|
|
|
elm = document.getElementById(text2ID);
|
|
elm.textContent = floor;
|
|
|
|
}
|
|
|
|
this.previousCeil = ceiling;
|
|
};
|
|
|
|
|
|
this.advancedGraph = function(mode, data, subID) {
|
|
|
|
var xstep;
|
|
var scalePos;
|
|
var lm;
|
|
var ceiling;
|
|
var elm;
|
|
var text2ID;
|
|
var ceilingLimit;
|
|
var calcArray;
|
|
var floor;
|
|
var _subID;
|
|
var _data;
|
|
var text1ID;
|
|
var lineID;
|
|
var max;
|
|
var yscale = 125;
|
|
var height = 125;
|
|
|
|
var yOffset = 71;
|
|
|
|
var reducer = function(p, v) {
|
|
return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
|
|
};
|
|
|
|
|
|
var parts = ['x', 'y', 'z'];
|
|
|
|
_data = data || this.data;
|
|
|
|
_subID = subID || '';
|
|
|
|
// LineID = [this.frameID , _subID , '-line'].join('');
|
|
text1ID = [this.frameID, _subID, '-txt1'].join('');
|
|
text2ID = [this.frameID, _subID, '-txt2'].join('');
|
|
|
|
if (mode === 'gyro') {
|
|
height = 300;
|
|
yscale = 300;
|
|
}
|
|
|
|
|
|
if (_data.x.length > 0) {
|
|
|
|
max = 2;
|
|
|
|
for (var lineMode = 0; lineMode < parts.length; lineMode++) {
|
|
lm = parts[lineMode];
|
|
/*Ceiling = _data[lm].reduce(function(p, v) {
|
|
return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
|
|
});*/
|
|
|
|
ceiling = _data[lm].reduce(reducer);
|
|
|
|
if (ceiling > 500) {
|
|
max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 50) * 50) : max;
|
|
} else {
|
|
max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 10) * 10) : max;
|
|
}
|
|
}
|
|
|
|
ceiling = max;
|
|
|
|
floor = ceiling * -1;
|
|
ceilingLimit = ceiling;
|
|
|
|
scalePos = (yscale / 2) / ceiling;
|
|
|
|
xstep = (680 - 46) / this.maxLength;
|
|
|
|
yOffset = ((height - (14 + 12)) / 2) + 12;
|
|
//Var xstep = 2.34;
|
|
|
|
for (lineMode = 0; lineMode < parts.length; lineMode++) {
|
|
|
|
lm = parts[lineMode];
|
|
var startX = 46 + (this.maxLength - _data[lm].length) * xstep;
|
|
|
|
calcArray = [];
|
|
|
|
lineID = this.frameID + _subID + '-' + lm + '-line';
|
|
for (var x = 0; x < _data[lm].length; x++) {
|
|
|
|
calcArray.push((startX + (x * xstep)).toFixed(2) + ',' + (71 - ((_data[lm][x]) * scalePos)).toFixed(
|
|
2));
|
|
|
|
}
|
|
|
|
elm = document.getElementById(lineID);
|
|
|
|
elm.setAttribute('points', calcArray.join(' '));
|
|
|
|
}
|
|
|
|
elm = document.getElementById(text1ID);
|
|
elm.textContent = ceilingLimit;
|
|
|
|
elm = document.getElementById(text2ID);
|
|
elm.textContent = floor;
|
|
|
|
}
|
|
|
|
this.previousCeil = ceiling;
|
|
};
|
|
|
|
this.animateGraph = function() {
|
|
// Nothing to animate yet
|
|
|
|
// return -1;
|
|
this.advancedGraphFFT(0, this.data.gyro, 'gyro');
|
|
this.advancedGraph(0, this.data.accel, 'accel');
|
|
this.advancedGraph(0, this.data.mag, 'mag');
|
|
// This.simpleGraph(this.data.temp, 'temp');
|
|
// this.simpleGraph(this.data.pressure, 'pressure');
|
|
|
|
};
|
|
|
|
this.generateBlankGraphBase = function(subID, settings) {
|
|
|
|
var _subID = subID || '';
|
|
var xmlns = 'http://www.w3.org/2000/svg';
|
|
|
|
var svgID = this.frameID + _subID + '-svg';
|
|
var text1ID = this.frameID + _subID + '-txt1';
|
|
var text2ID = this.frameID + _subID + '-txt2';
|
|
|
|
var _width = settings.width || 300;
|
|
var _height = settings.height || 150;
|
|
var _fill = settings.fill || 'blue';
|
|
|
|
var viewbox = [0,0,_width, _height].join(' ');
|
|
|
|
var svg = document.createElementNS(xmlns, 'svg');
|
|
|
|
svg.setAttribute('id', svgID);
|
|
// Svg.setAttribute(xmlns, 'version', '1.1');
|
|
svg.setAttribute('width', _width.toString());
|
|
svg.setAttribute('height', _height.toString());
|
|
svg.setAttribute('fill', _fill);
|
|
|
|
|
|
svg.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
|
|
|
|
svg.setAttributeNS(xmlns, 'viewBox', viewbox);
|
|
// Svg.setAttributeNS(xmlns, 'style', 'width:700px;height:150px;');
|
|
|
|
|
|
svg = this.graphAddXAxis(svg, {y: 12, x2: 680, colour: '#004c6d', id: text1ID});
|
|
svg = this.graphAddXAxis(svg, {y: _height - 14, x2: 680, colour: '#004c6d', id: text2ID});
|
|
svg = this.graphAddXAxis(svg, {y: ((_height - (14 + 12)) / 2) + 12, x2: 680, colour: '#004c6d', text: '0'});
|
|
|
|
return svg;
|
|
|
|
};
|
|
|
|
this.generateBlankGraph = function(subID, height) {
|
|
|
|
var _height = height || 150;
|
|
var _subID = subID || '';
|
|
var xlineID = this.frameID + _subID + '-x-line';
|
|
var ylineID = this.frameID + _subID + '-y-line';
|
|
var zlineID = this.frameID + _subID + '-z-line';
|
|
|
|
var svg = this.generateBlankGraphBase(_subID,{width: '700',height: height});
|
|
|
|
svg = this.graphAddLine(svg, xlineID, 'rgba(255,0,99,1)');
|
|
svg = this.graphAddLine(svg, ylineID, 'rgba(46,255,0,1)');
|
|
svg = this.graphAddLine(svg, zlineID, 'rgba(0,191,255,1)');
|
|
|
|
return svg;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.startCalibrate = function() {
|
|
console.log('Start calibrate');
|
|
|
|
alert('Mag Calibration: Wave device in a figure eight until done!');
|
|
};
|
|
|
|
this.insertFrame = function(mode) {
|
|
|
|
var _graph;
|
|
var row;
|
|
var button;
|
|
var elm;
|
|
var frame;
|
|
var title;
|
|
var modeID = mode + 'ID';
|
|
var height = 150;
|
|
this.frames[modeID] = this.frameID + '-' + mode;
|
|
|
|
|
|
var titles = {
|
|
gyro: 'Gyroscope', accel: 'Accelerometer', mag: 'Magnetometer'
|
|
};
|
|
|
|
console.log('FrameID: ', this.frames[modeID]);
|
|
|
|
title = [titles[mode], ' - ', this.deviceID].join(' ');
|
|
|
|
frame = $('<div />', {
|
|
class: 'mui-panel', id: this.frames[modeID]
|
|
});
|
|
|
|
if (mode === 'gyro') {
|
|
height = 300;
|
|
}
|
|
|
|
if (mode === 'mag') {
|
|
|
|
elm = $('<div />', {class: 'mui-row'});
|
|
button = $('<button />', {
|
|
class: 'mui-btn mui-btn--raised',
|
|
id: modeID + '-cal',
|
|
text: 'Calibrate',
|
|
click: this.startCalibrate.bind(this)
|
|
});
|
|
|
|
elm.append($('<div />', { class: 'mui-col-xs-8 mui--text-title mui-ellipsis-2', text: title}));
|
|
|
|
// Elm.append($('<div />', {class: 'mui-col-xs-4 mui--text-right'}).append(button));
|
|
|
|
frame.append(elm);
|
|
|
|
} else {
|
|
$('<div />', {class: 'mui-row'}).append($('<div />', {
|
|
class: 'mui-col-xs-12 mui--text-title mui-ellipsis-2', text: title
|
|
})).appendTo(frame);
|
|
|
|
}
|
|
this.$frame.append(frame);
|
|
this.$id[modeID] = $('#' + this.frames[modeID]);
|
|
|
|
// Call the parent displayForm first...
|
|
|
|
row = $('<div />', {class: 'mui-row'});
|
|
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-accent mui--text-center', text: 'X'
|
|
}).appendTo(row);
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-accent mui--text-center', text: 'Y'
|
|
}).appendTo(row);
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-accent mui--text-center', text: 'Z'
|
|
}).appendTo(row);
|
|
|
|
this.$id[modeID].append(row);
|
|
|
|
row = $('<div />', {class: 'mui-row'});
|
|
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-light mui--text-center',
|
|
text: '--',
|
|
id: this.frames[modeID] + '-x'
|
|
}).appendTo(row);
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-light mui--text-center',
|
|
text: '--',
|
|
id: this.frames[modeID] + '-y'
|
|
}).appendTo(row);
|
|
$('<div />', {
|
|
class: 'mui-col-xs-4 mui--text-light mui--text-center',
|
|
text: '--',
|
|
id: this.frames[modeID] + '-z'
|
|
}).appendTo(row);
|
|
|
|
this.$id[modeID].append(row);
|
|
|
|
this.$result[this.frames[modeID] + '-x'] = $('#' + this.frames[modeID] + '-x');
|
|
this.$result[this.frames[modeID] + '-y'] = $('#' + this.frames[modeID] + '-y');
|
|
this.$result[this.frames[modeID] + '-z'] = $('#' + this.frames[modeID] + '-z');
|
|
|
|
row = $('<div />', {class: 'mui-row'});
|
|
|
|
_graph = this.generateBlankGraph(mode, height);
|
|
row.append($('<div>', {class: 'mui-col-sm-12'}).append(_graph));
|
|
|
|
this.$id[modeID].append(row);
|
|
};
|
|
|
|
};
|
|
|
|
|
|
inheritsFrom(CC2650_ACCEL, CAPABILITY);
|
|
|
|
capabilityManager.register({id: 'F000AA80-0451-4000-B000-000000000000', module: CC2650_ACCEL});
|