Skip to content

Commit

Permalink
Merge pull request #4 from aj-ptw/master
Browse files Browse the repository at this point in the history
FIX: Examples and time sync stuffs
  • Loading branch information
AJ Keller committed Oct 31, 2017
2 parents 575f957 + 0b8f6ae commit c7b49f4
Show file tree
Hide file tree
Showing 12 changed files with 1,576 additions and 60 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ hardwareVoltageOutputAll.txt

# Text editor temporary files
.*.sw* # vi/vim

# For python
examples/python/dist/*
examples/python/openbci_node_python.egg-info/*
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ Sample properties:
* `auxData` (`Buffer` filled with either 2 bytes (if time synced) or 6 bytes (not time synced))
* `stopByte` (`Number` should be `0xCx` where x is 0-15 in hex)
* `boardTime` (`Number` the raw board time)
* `timeStamp` (`Number` the `boardTime` plus the NTP calculated offset)
* `timestamp` (`Number` the `boardTime` plus the NTP calculated offset)

The power of this module is in using the sample emitter, to be provided with samples to do with as you wish.

Expand Down
9 changes: 9 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# 1.0.7

### Bug Fixes

* Add simulator back into this repo
* Fixed bug where timestamp was not calculated with timeOffset, big fail.
* Fixed the `python` example
* Fixed the `labstreaminglayer` example

# 1.0.6

### Bug Fixes
Expand Down
17 changes: 12 additions & 5 deletions examples/labstreaminglayer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ourBoard.autoFindOpenBCIBoard().then(portName => {
}

// Find out if you can even time sync, you must be using v2 and this is only accurate after a `.softReset()` call which is called internally on `.connect()`. We parse the `.softReset()` response for the presence of firmware version 2 properties.
timeSyncPossible = ourBoard.usingVersionTwoFirmware();
timeSyncPossible = ourBoard.usingAtLeastVersionTwoFirmware();

sendToPython({'numChans': numChans, 'sampleRate': ourBoard.sampleRate()});
if (timeSyncPossible) {
Expand Down Expand Up @@ -82,9 +82,9 @@ const sampleFunc = sample => {
});
}

if (sample.timeStamp) { // true after the first successful sync
if (sample.timeStamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
console.log(`Bad time sync ${sample.timeStamp}`);
if (sample.timestamp) { // true after the first successful sync
if (sample.timestamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
console.log(`Bad time sync ${sample.timestamp}`);
} else {
sendToPython({
action: 'process',
Expand Down Expand Up @@ -127,7 +127,14 @@ function exitHandler (options, err) {
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
ourBoard.disconnect()
.then(() => {
process.exit(0);
})
.catch((err) => {
console.log(err);
process.exit(0);
});
}
}

Expand Down
92 changes: 52 additions & 40 deletions examples/python/handoff.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

class Interface:
def __init__(self, verbose=False):
context = zmq.Context()
self._socket = context.socket(zmq.PAIR)
self._context = zmq.Context()
self._socket = self._context.socket(zmq.PAIR)
self._socket.connect("tcp://localhost:3004")

self.verbose = verbose
Expand Down Expand Up @@ -43,6 +43,13 @@ def recv(self):
"""
return self._socket.recv()

def close(self):
"""
Closes the zmq context
"""
self._backend.close()
self._context.term()


class RingBuffer(np.ndarray):
"""A multidimensional ring buffer."""
Expand Down Expand Up @@ -73,44 +80,49 @@ def main(argv):
interface = Interface(verbose=verbose)
# Signal buffer
signal = RingBuffer(np.zeros((nb_chan + 1, 2500)))

while True:
msg = interface.recv()
try:
dicty = json.loads(msg)
action = dicty.get('action')
command = dicty.get('command')
message = dicty.get('message')

if command == 'sample':
if action == 'process':
# Do sample processing here
try:
if type(message) is not dict:
print "sample is not a dict", message
raise ValueError
# Get keys of sample
data = np.zeros(9)

data[:-1] = message.get('channelData')
data[-1] = message.get('timeStamp')

# Add data to end of ring buffer
signal.append(data)

print message.get('sampleNumber')
except ValueError as e:
print e
elif command == 'status':
if action == 'active':
interface.send(json.dumps({
'action': 'alive',
'command': 'status',
'message': time.time() * 1000.0
}))

except BaseException as e:
print e
try:
while True:
msg = interface.recv()
print "woo"
try:
dicty = json.loads(msg)
action = dicty.get('action')
command = dicty.get('command')
message = dicty.get('message')

if command == 'sample':
if action == 'process':
# Do sample processing here
try:
if type(message) is not dict:
print "sample is not a dict", message
raise ValueError
# Get keys of sample
data = np.zeros(9)

data[:-1] = message.get('channelData')
data[-1] = message.get('timeStamp')

# Add data to end of ring buffer
signal.append(data)

print message.get('sampleNumber')
except ValueError as e:
print e
elif command == 'status':
if action == 'active':
interface.send(json.dumps({
'action': 'alive',
'command': 'status',
'message': time.time() * 1000.0
}))
except KeyboardInterrupt:
print "W: interrupt received, stopping"
print("Python ZMQ Link Clean Up")
interface.close()
raise ValueError("Peace")
except BaseException as e:
print e


if __name__ == '__main__':
Expand Down
26 changes: 18 additions & 8 deletions examples/python/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
* then `npm start`
*/
const portPub = 'tcp://127.0.0.1:3004';
const zmq = require('zmq-prebuilt');
const zmq = require('zeromq');
const socket = zmq.socket('pair');
const simulate = false; // Sends synthetic data
const simulate = true; // Sends synthetic data
const debug = false; // Pretty print any bytes in and out... it's amazing...
const verbose = true; // Adds verbosity to functions

const Cyton = require('openbci').Cyton;
const Cyton = require('../..');
let ourBoard = new Cyton({
simulate: simulate, // Uncomment to see how it works with simulator!
simulatorFirmwareVersion: 'v2',
Expand All @@ -41,7 +41,8 @@ ourBoard.autoFindOpenBCIBoard().then(portName => {
.then(() => {
ourBoard.on('ready', () => {
// Find out if you can even time sync, you must be using v2 and this is only accurate after a `.softReset()` call which is called internally on `.connect()`. We parse the `.softReset()` response for the presence of firmware version 2 properties.
timeSyncPossible = ourBoard.usingVersionTwoFirmware();
timeSyncPossible = ourBoard.usingAtLeastVersionTwoFirmware();
console.log(`timeSyncPossible: ${timeSyncPossible}`);

if (timeSyncPossible) {
ourBoard.streamStart()
Expand All @@ -63,6 +64,8 @@ ourBoard.autoFindOpenBCIBoard().then(portName => {
});

const sampleFunc = sample => {
console.log(JSON.stringify(sample));

if (sample._count % resyncPeriod === 0) {
ourBoard.syncClocksFull()
.then(syncObj => {
Expand All @@ -77,9 +80,9 @@ const sampleFunc = sample => {
});
}

if (sample.timeStamp) { // true after the first successful sync
if (sample.timeStamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
console.log(`Bad time sync ${sample.timeStamp}`);
if (sample.timestamp) { // true after the first successful sync
if (sample.timestamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
console.log(`Bad time sync ${sample.timestamp}`);
} else {
sendToPython({
action: 'process',
Expand Down Expand Up @@ -178,7 +181,14 @@ function exitHandler (options, err) {
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
ourBoard.disconnect()
.then(() => {
process.exit(0);
})
.catch((err) => {
console.log(err);
process.exit(0);
});
}
}

Expand Down
6 changes: 3 additions & 3 deletions examples/python/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
"author": "AJ Keller",
"license": "MIT",
"dependencies": {
"openbci": "^2.0.0",
"zmq-prebuilt": "^2.1.0"
"concurrently": "^3.1.0",
"zeromq": "^4.6.0"
},
"devEngines": {
"node": "<=6.x",
"npm": ">=3.x"
},
"devDependencies": {
"concurrently": "^3.1.0"

}
}
5 changes: 3 additions & 2 deletions openBCICyton.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const OpenBCIUtilities = require('openbci-utilities');
const obciUtils = OpenBCIUtilities.Utilities;
const k = OpenBCIUtilities.Constants;
const obciDebug = OpenBCIUtilities.Debug;
const OpenBCISimulator = OpenBCIUtilities.Simulator;
const OpenBCISimulator = require('./openBCISimulator');
const Sntp = require('sntp');
const bufferEqual = require('buffer-equal');
const math = require('mathjs');
Expand Down Expand Up @@ -1878,7 +1878,7 @@ Cyton.prototype._processBytes = function (data) {
this.buffer = obciUtils.stripToEOTBuffer(data);
}
} else {
if (_.eq(this.getBoardType(), this.options.boardType) && this.options.verbose) {
if (!_.eq(this.getBoardType(), this.options.boardType) && this.options.verbose) {
console.log(`Module detected ${this.getBoardType()} board type but you specified ${this.options.boardType}, use 'hardSet' to force the module to correct itself`);
}
this.curParsingMode = k.OBCIParsingNormal;
Expand Down Expand Up @@ -2122,6 +2122,7 @@ Cyton.prototype._processPacketTimeSyncSet = function (rawPacket, timeOfPacketArr
}

this.sync.curSyncObj.timeOffsetMaster = this.sync.timeOffsetMaster;
this._rawDataPacketToSample.timeOffset = this.sync.timeOffsetMaster;

if (this.options.verbose) {
console.log(`Master offset ${this.sync.timeOffsetMaster} ms`);
Expand Down
Loading

0 comments on commit c7b49f4

Please sign in to comment.