Refactor intval library to use object. The nature of the GPIO module in use breaks references to this

This commit is contained in:
mmcw-dev 2017-10-19 21:52:13 -04:00
parent 15d9225c04
commit 6218d8d585
4 changed files with 280 additions and 1386 deletions

View File

@ -1,54 +1,54 @@
<a name="Intval"></a> <a name="intval"></a>
## Intval ## intval
Class representing the intval3 features Object representing the intval3 features
**Kind**: global class **Kind**: global constant
* [Intval](#Intval) * [intval](#intval)
* [._declarePins()](#Intval+_declarePins) * [._declarePins()](#intval._declarePins)
* [._undeclarePins()](#Intval+_undeclarePins) * [._undeclarePins()](#intval._undeclarePins)
* [._startFwd()](#Intval+_startFwd) * [._startFwd()](#intval._startFwd)
* [._startBwd()](#Intval+_startBwd) * [._startBwd()](#intval._startBwd)
* [._stop()](#Intval+_stop) * [._stop()](#intval._stop)
* [._watchMicro(err, val)](#Intval+_watchMicro) * [._watchMicro(err, val)](#intval._watchMicro)
* [._watchRelease(err, val)](#Intval+_watchRelease) * [._watchRelease(err, val)](#intval._watchRelease)
* [.setDir([dir])](#Intval+setDir) * [.setDir([dir])](#intval.setDir)
* [.frame([dir], [time])](#Intval+frame) * [.frame([dir], [time])](#intval.frame)
* [.sequence()](#Intval+sequence) * [.sequence()](#intval.sequence)
<a name="Intval+_declarePins"></a> <a name="intval._declarePins"></a>
### intval._declarePins() ### intval._declarePins()
(internal function) Declares all Gpio pins that will be used (internal function) Declares all Gpio pins that will be used
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
<a name="Intval+_undeclarePins"></a> <a name="intval._undeclarePins"></a>
### intval._undeclarePins() ### intval._undeclarePins()
(internal function) Undeclares all Gpio in event of uncaught error (internal function) Undeclares all Gpio in event of uncaught error
that interupts the node process that interupts the node process
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
<a name="Intval+_startFwd"></a> <a name="intval._startFwd"></a>
### intval._startFwd() ### intval._startFwd()
Start motor in forward direction by setting correct pins in h-bridge Start motor in forward direction by setting correct pins in h-bridge
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
<a name="Intval+_startBwd"></a> <a name="intval._startBwd"></a>
### intval._startBwd() ### intval._startBwd()
Start motor in backward direction by setting correct pins in h-bridge Start motor in backward direction by setting correct pins in h-bridge
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
<a name="Intval+_stop"></a> <a name="intval._stop"></a>
### intval._stop() ### intval._stop()
Stop motor by setting both motor pins to 0 (LOW) Stop motor by setting both motor pins to 0 (LOW)
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
<a name="Intval+_watchMicro"></a> <a name="intval._watchMicro"></a>
### intval._watchMicro(err, val) ### intval._watchMicro(err, val)
Callback for watching relese switch state changes. Callback for watching relese switch state changes.
@ -61,14 +61,14 @@ Microswitch + 10K ohm resistor
* 1 === open * 1 === open
* 0 === closed * 0 === closed
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| err | <code>object</code> | Error object present if problem reading pin | | err | <code>object</code> | Error object present if problem reading pin |
| val | <code>integer</code> | Current value of the pin | | val | <code>integer</code> | Current value of the pin |
<a name="Intval+_watchRelease"></a> <a name="intval._watchRelease"></a>
### intval._watchRelease(err, val) ### intval._watchRelease(err, val)
Callback for watching relese switch state changes. Callback for watching relese switch state changes.
@ -76,48 +76,48 @@ Using GPIO 05 on Raspberry Pi Zero W.
1) If closed, start timer. 1) If closed, start timer.
2) If opened, check timer AND 2) If opened, check timer AND
3) If `press` (`NOW - this._state.release.time`) greater than minimum and less than `this._releaseSequence`, start frame 3) If `press` (`now - intval._state.release.time`) greater than minimum and less than `intval._releaseSequence`, start frame
4) If `press` greater than `this._releaseSequence`, start sequence 4) If `press` greater than `intval._releaseSequence`, start sequence
Button + 10K ohm resistor Button + 10K ohm resistor
* 1 === open * 1 === open
* 0 === closed * 0 === closed
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| err | <code>object</code> | Error object present if problem reading pin | | err | <code>object</code> | Error object present if problem reading pin |
| val | <code>integer</code> | Current value of the pin | | val | <code>integer</code> | Current value of the pin |
<a name="Intval+setDir"></a> <a name="intval.setDir"></a>
### intval.setDir([dir]) ### intval.setDir([dir])
Set the default direction of the camera. Set the default direction of the camera.
* forward = true * forward = true
* backward = false * backward = false
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
| Param | Type | Default | Description | | Param | Type | Default | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| [dir] | <code>boolean</code> | <code>true</code> | Direction of the camera | | [dir] | <code>boolean</code> | <code>true</code> | Direction of the camera |
<a name="Intval+frame"></a> <a name="intval.frame"></a>
### intval.frame([dir], [time]) ### intval.frame([dir], [time])
Begin a single frame with set variables or defaults Begin a single frame with set variables or defaults
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)
| Param | Type | Default | Description | | Param | Type | Default | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| [dir] | <code>boolean</code> | <code>&quot;null&quot;</code> | (optional) Direction of the frame | | [dir] | <code>boolean</code> | <code>&quot;null&quot;</code> | (optional) Direction of the frame |
| [time] | <code>integer</code> | <code>&quot;null&quot;</code> | (optional) Exposure time, 0 = minimum | | [time] | <code>integer</code> | <code>&quot;null&quot;</code> | (optional) Exposure time, 0 = minimum |
<a name="Intval+sequence"></a> <a name="intval.sequence"></a>
### intval.sequence() ### intval.sequence()
Start a sequence of frames, using defaults or explicit instructions Start a sequence of frames, using defaults or explicit instructions
**Kind**: instance method of [<code>Intval</code>](#Intval) **Kind**: static method of [<code>intval</code>](#intval)

View File

@ -32,256 +32,256 @@ const PINS = {
} }
} }
/** Class representing the intval3 features */ /** Object representing the intval3 features */
class Intval { const intval = {}
constructor () {
this._pin = {}
this._state = {
dir : true, //forward
frame : {
start : 0, //time frame started, timestamp
active : false, //should frame be running
time : 0, //length of frame, in ms
delay : 0, //delay before start of frame, in ms
expected : 1000 //expected length of frame, in ms intval.init = function () {
}, intval._pin = {}
release : { intval._state = {
time: 0, dir : true, //forward
active : false //is pressed frame : {
}, start : 0, //time frame started, timestamp
micro : { active : false, //should frame be running
time : 0, time : 0, //length of frame, in ms
primed : false //is ready to stop frame delay : 0, //delay before start of frame, in ms
}
}
this._releaseMin = 50 expected : 1000 //expected length of frame, in ms
this._releaseSequence = 1000 },
this._microDelay = 10 // delay after stop signal before stopping motors release : {
time: 0,
this._declarePins() active : false //is pressed
process.on('SIGINT', this._undeclarePins) },
process.on('uncaughtException', this._undeclarePins) micro : {
} time : 0,
/** primed : false //is ready to stop frame
* (internal function) Declares all Gpio pins that will be used
*
*/
_declarePins () {
let pin
for (let p in PINS) {
pin = PINS[p]
if (pin.edge) this._pin[p] = Gpio(pin.pin, pin.dir, pin.edge)
if (!pin.edge) this._pin[p] = Gpio(pin.pin, pin.dir)
log.info('_declarePins', { pin : pin.pin, dir : pin.dir, edge : pin.edge })
} }
this._pin.release.watch(this._watchRelease)
}
/**
* (internal function) Undeclares all Gpio in event of uncaught error
* that interupts the node process
*
*/
_undeclarePins (e) {
log.error(e)
if (!this._pin) {
log.warn('_undeclarePins', { reason : 'No pins'})
return process.exit()
}
log.warn('_undeclarePins', { pin : PINS.fwd.pin, val : 0, reason : 'exiting'})
this._pin.fwd.writeSync(0)
log.warn('_undeclarePins', { pin : PINS.bwd.pin, val : 0, reason : 'exiting'})
this._pin.bwd.writeSync(0)
this._pin.fwd.unexport()
this._pin.bwd.unexport()
this._pin.micro.unexport()
this._pin.release.unexport()
process.exit()
}
/**
* Start motor in forward direction by setting correct pins in h-bridge
*
*/
_startFwd () {
this._pin.fwd.writeSync(1)
this._pin.bwd.writeSync(0)
//start high-cpu watch
}
/**
* Start motor in backward direction by setting correct pins in h-bridge
*
*/
_startBwd () {
this._pin.fwd.writeSync(0)
this._pin.bwd.writeSync(1)
}
/**
* Stop motor by setting both motor pins to 0 (LOW)
*
*/
_stop () {
this._pin.fwd.writeSync(0)
this._pin.bwd.writeSync(0)
let len = (+new Date()) - this._state.frame.start
log.info(`Frame stopped ${len}ms`)
this._pin.micro.unwatch()
this._state.frame.active = false
this._state.frame.start = 0
}
/**
* Callback for watching relese switch state changes.
* Using GPIO 06 on Raspberry Pi Zero W.
*
* 1) If closed AND frame active, start timer, set state primed to `true`.
* 1) If opened AND frame active, stop frame
*
* Microswitch + 10K ohm resistor
* * 1 === open
* * 0 === closed
*
*
* @param {object} err Error object present if problem reading pin
* @param {integer} val Current value of the pin
*
*/
_watchMicro (err, val) {
const NOW = +new Date()
if (err) {
log.error('_watchMicro', err)
}
//determine when to stop
if (val === 0 && this._state.frame.active) {
if (!this._state.micro.primed) {
this._state.micro.primed = true
this._state.micro.time = NOW
log.info('Mircoswitch primed to stop motor')
}
} else if (val === 1 && this._state.frame.active) {
if (this._state.micro.primed) {
this._state.micro.primed = false
this._state.micro.time = 0
setTimeout( () => {
log.info(`Stopped frame after ${NOW - this._state.micro.time}ms`)
}, this._microDelay)
}
}
}
/**
* Callback for watching relese switch state changes.
* Using GPIO 05 on Raspberry Pi Zero W.
*
* 1) If closed, start timer.
* 2) If opened, check timer AND
* 3) If `press` (`now - this._state.release.time`) greater than minimum and less than `this._releaseSequence`, start frame
* 4) If `press` greater than `this._releaseSequence`, start sequence
*
* Button + 10K ohm resistor
* * 1 === open
* * 0 === closed
*
* @param {object} err Error object present if problem reading pin
* @param {integer} val Current value of the pin
*
*/
_watchRelease (err, val) {
const now = +new Date()
let press = 0
if (err) {
return log.error(err)
}
log.info(`Release switch val: ${val}`)
if (val === 0) {
//closed
if (this._releaseClosedState(now)) {
this._state.release.time = now
this._state.release.active = true //maybe unncecessary
}
} else if (val === 1) {
//opened
if (this._state.release.active) {
press = now - this._state.release.time
if (press > this._releaseMin && press < this._releaseSequence) {
this.frame()
} else if (press >= this._releaseSequence) {
this.sequence()
}
log.info(`Release closed for ${press}ms`)
this._state.release.time = 0
this._state.release.active = false
}
}
log.info('completed if statement')
} }
_releaseClosedState (now) { intval._releaseMin = 50
if (!this._state.release.active && this._state.release.time === 0) { intval._releaseSequence = 1000
return true intval._microDelay = 10 // delay after stop signal before stopping motors
}
if (this._state.release.active && (now - this._state.release.time) > (this._releaseSequence * 10)) {
return true
}
return false
}
/**
* Set the default direction of the camera.
* * forward = true
* * backward = false
*
* @param {boolean} [dir=true] Direction of the camera
*
*/
setDir (val = true) {
if (typeof val !== 'boolean') {
return log.warn('Direction must be represented as either true or false')
}
this._state.dir = val
}
/**
* Begin a single frame with set variables or defaults
*
* @param {?boolean} [dir="null"] (optional) Direction of the frame
* @param {?integer} [time="null"] (optional) Exposure time, 0 = minimum
*
*/
frame (dir = null, time = null) {
if (dir === true || (dir === null && this._state.dir === true) ) {
dir = true
} else {
dir = false
}
if (time === null && this._state.time !== 0) { intval._declarePins()
time = this._state.time process.on('SIGINT', intval._undeclarePins)
} else { process.on('uncaughtException', intval._undeclarePins)
time = 0 }
} /**
* (internal function) Declares all Gpio pins that will be used
this._state.frame.start = +new Date() *
this._state.frame.active = true */
this._pin.micro.watch(this._watchMicro) intval._declarePins = function () {
let pin
log.info('frame', {dir : dir, time : time}) for (let p in PINS) {
pin = PINS[p]
if (dir) { if (pin.edge) intval._pin[p] = Gpio(pin.pin, pin.dir, pin.edge)
this._startFwd() if (!pin.edge) intval._pin[p] = Gpio(pin.pin, pin.dir)
} else { log.info('_declarePins', { pin : pin.pin, dir : pin.dir, edge : pin.edge })
this._startBwd()
}
} }
/** intval._pin.release.watch(intval._watchRelease)
* Start a sequence of frames, using defaults or explicit instructions }
* /**
*/ * (internal function) Undeclares all Gpio in event of uncaught error
sequence () { * that interupts the node process
log.info('sequence', `Started sequence`) *
*/
intval._undeclarePins = function (e) {
log.error(e)
if (!intval._pin) {
log.warn('_undeclarePins', { reason : 'No pins'})
return process.exit()
} }
status () { log.warn('_undeclarePins', { pin : PINS.fwd.pin, val : 0, reason : 'exiting'})
return this._state intval._pin.fwd.writeSync(0)
log.warn('_undeclarePins', { pin : PINS.bwd.pin, val : 0, reason : 'exiting'})
intval._pin.bwd.writeSync(0)
intval._pin.fwd.unexport()
intval._pin.bwd.unexport()
intval._pin.micro.unexport()
intval._pin.release.unexport()
process.exit()
}
/**
* Start motor in forward direction by setting correct pins in h-bridge
*
*/
intval._startFwd = function () {
intval._pin.fwd.writeSync(1)
intval._pin.bwd.writeSync(0)
//start high-cpu watch
}
/**
* Start motor in backward direction by setting correct pins in h-bridge
*
*/
intval._startBwd = function () {
intval._pin.fwd.writeSync(0)
intval._pin.bwd.writeSync(1)
}
/**
* Stop motor by setting both motor pins to 0 (LOW)
*
*/
intval._stop = function () {
intval._pin.fwd.writeSync(0)
intval._pin.bwd.writeSync(0)
let len = (+new Date()) - intval._state.frame.start
log.info(`Frame stopped ${len}ms`)
intval._pin.micro.unwatch()
intval._state.frame.active = false
intval._state.frame.start = 0
}
/**
* Callback for watching relese switch state changes.
* Using GPIO 06 on Raspberry Pi Zero W.
*
* 1) If closed AND frame active, start timer, set state primed to `true`.
* 1) If opened AND frame active, stop frame
*
* Microswitch + 10K ohm resistor
* * 1 === open
* * 0 === closed
*
*
* @param {object} err Error object present if problem reading pin
* @param {integer} val Current value of the pin
*
*/
intval._watchMicro = function (err, val) {
const NOW = +new Date()
if (err) {
log.error('_watchMicro', err)
}
//determine when to stop
if (val === 0 && intval._state.frame.active) {
if (!intval._state.micro.primed) {
intval._state.micro.primed = true
intval._state.micro.time = NOW
log.info('Mircoswitch primed to stop motor')
}
} else if (val === 1 && intval._state.frame.active) {
if (intval._state.micro.primed) {
intval._state.micro.primed = false
intval._state.micro.time = 0
setTimeout( () => {
log.info(`Stopped frame after ${NOW - intval._state.micro.time}ms`)
}, intval._microDelay)
}
} }
} }
/**
* Callback for watching relese switch state changes.
* Using GPIO 05 on Raspberry Pi Zero W.
*
* 1) If closed, start timer.
* 2) If opened, check timer AND
* 3) If `press` (`now - intval._state.release.time`) greater than minimum and less than `intval._releaseSequence`, start frame
* 4) If `press` greater than `intval._releaseSequence`, start sequence
*
* Button + 10K ohm resistor
* * 1 === open
* * 0 === closed
*
* @param {object} err Error object present if problem reading pin
* @param {integer} val Current value of the pin
*
*/
intval._watchRelease = function (err, val) {
const now = +new Date()
let press = 0
if (err) {
return log.error(err)
}
log.info(`Release switch val: ${val}`)
if (val === 0) {
//closed
if (intval._releaseClosedState(now)) {
intval._state.release.time = now
intval._state.release.active = true //maybe unncecessary
}
} else if (val === 1) {
//opened
if (intval._state.release.active) {
press = now - intval._state.release.time
if (press > intval._releaseMin && press < intval._releaseSequence) {
intval.frame()
} else if (press >= intval._releaseSequence) {
intval.sequence()
}
log.info(`Release closed for ${press}ms`)
intval._state.release.time = 0
intval._state.release.active = false
}
}
log.info('completed if statement')
}
module.exports = new Intval() intval._releaseClosedState = function (now) {
if (!intval._state.release.active && intval._state.release.time === 0) {
return true
}
if (intval._state.release.active && (now - intval._state.release.time) > (intval._releaseSequence * 10)) {
return true
}
return false
}
/**
* Set the default direction of the camera.
* * forward = true
* * backward = false
*
* @param {boolean} [dir=true] Direction of the camera
*
*/
intval.setDir = function (val = true) {
if (typeof val !== 'boolean') {
return log.warn('Direction must be represented as either true or false')
}
intval._state.dir = val
}
/**
* Begin a single frame with set variables or defaults
*
* @param {?boolean} [dir="null"] (optional) Direction of the frame
* @param {?integer} [time="null"] (optional) Exposure time, 0 = minimum
*
*/
intval.frame = function (dir = null, time = null) {
if (dir === true || (dir === null && intval._state.dir === true) ) {
dir = true
} else {
dir = false
}
if (time === null && intval._state.time !== 0) {
time = intval._state.time
} else {
time = 0
}
intval._state.frame.start = +new Date()
intval._state.frame.active = true
intval._pin.micro.watch(intval._watchMicro)
log.info('frame', {dir : dir, time : time})
if (dir) {
intval._startFwd()
} else {
intval._startBwd()
}
}
/**
* Start a sequence of frames, using defaults or explicit instructions
*
*/
intval.sequence = function () {
log.info('sequence', `Started sequence`)
}
intval.status = function () {
return intval._state
}
module.exports = intval

1110
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
'use strict' 'use strict'
const intval = require('../lib/intval') const intval = require('../lib/intval')
intval.init()