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
this._releaseSequence = 1000
this._microDelay = 10 // delay after stop signal before stopping motors
this._declarePins() expected : 1000 //expected length of frame, in ms
process.on('SIGINT', this._undeclarePins) },
process.on('uncaughtException', this._undeclarePins) release : {
} time: 0,
/** active : false //is pressed
* (internal function) Declares all Gpio pins that will be used },
* micro : {
*/ time : 0,
_declarePins () { primed : false //is ready to stop frame
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 intval._releaseMin = 50
* that interupts the node process intval._releaseSequence = 1000
* intval._microDelay = 10 // delay after stop signal before stopping motors
*/
_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 intval._declarePins()
process.on('SIGINT', intval._undeclarePins)
log.info(`Frame stopped ${len}ms`) process.on('uncaughtException', intval._undeclarePins)
}
this._pin.micro.unwatch() /**
this._state.frame.active = false * (internal function) Declares all Gpio pins that will be used
this._state.frame.start = 0 *
*/
intval._declarePins = function () {
let pin
for (let p in PINS) {
pin = PINS[p]
if (pin.edge) intval._pin[p] = Gpio(pin.pin, pin.dir, pin.edge)
if (!pin.edge) intval._pin[p] = Gpio(pin.pin, pin.dir)
log.info('_declarePins', { pin : pin.pin, dir : pin.dir, edge : pin.edge })
} }
/** intval._pin.release.watch(intval._watchRelease)
* Callback for watching relese switch state changes. }
* Using GPIO 06 on Raspberry Pi Zero W. /**
* * (internal function) Undeclares all Gpio in event of uncaught error
* 1) If closed AND frame active, start timer, set state primed to `true`. * that interupts the node process
* 1) If opened AND frame active, stop frame *
* */
* Microswitch + 10K ohm resistor intval._undeclarePins = function (e) {
* * 1 === open log.error(e)
* * 0 === closed if (!intval._pin) {
* log.warn('_undeclarePins', { reason : 'No pins'})
* return process.exit()
* @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')
} }
log.warn('_undeclarePins', { pin : PINS.fwd.pin, val : 0, reason : 'exiting'})
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)
_releaseClosedState (now) { let len = (+new Date()) - intval._state.frame.start
if (!this._state.release.active && this._state.release.time === 0) {
return true
}
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) {
time = this._state.time
} else {
time = 0
}
this._state.frame.start = +new Date() log.info(`Frame stopped ${len}ms`)
this._state.frame.active = true
this._pin.micro.watch(this._watchMicro)
log.info('frame', {dir : dir, time : time}) intval._pin.micro.unwatch()
intval._state.frame.active = false
if (dir) { intval._state.frame.start = 0
this._startFwd() }
} else { /**
this._startBwd() * 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)
} }
}
/**
* Start a sequence of frames, using defaults or explicit instructions
*
*/
sequence () {
log.info('sequence', `Started sequence`)
}
status () {
return this._state
} }
} }
/**
* 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()