working rpi gpio interrupt with packet socket
parent
ed76c3e83a
commit
6680fd3ad9
|
@ -0,0 +1,33 @@
|
||||||
|
module.exports = {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"modules": true,
|
||||||
|
"spread" : true,
|
||||||
|
"restParams" : true
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"node": true,
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2017,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"no-console": 0,
|
||||||
|
"semi": ["error", "never"],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"single"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import Interrupt from '../src/interrupt-packet'
|
||||||
|
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||||
|
|
||||||
|
let interrupts = new Interrupt([9,10,24],{id:'interrupt', mock:true, itrn:{path:'/opt/sockets/mcp.sock'}})
|
||||||
|
|
||||||
|
interrupts.interruptProcess = function (pin) {
|
||||||
|
let packet = {cmd:'pin.interrupt.find', pin:pin}
|
||||||
|
this.send(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
(async () => {
|
||||||
|
|
||||||
|
await interrupts.init()
|
||||||
|
interrupts.fire(9)
|
||||||
|
interrupts.fire(10)
|
||||||
|
interrupts.fire(24)
|
||||||
|
await delay(3000)
|
||||||
|
process.kill(process.pid, 'SIGTERM')
|
||||||
|
|
||||||
|
})().catch(err => {
|
||||||
|
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||||
|
// process.kill(process.pid, 'SIGTERM')
|
||||||
|
})
|
22
package.json
22
package.json
|
@ -1,13 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "@uci/interrupt",
|
"name": "@uci/interrupt",
|
||||||
"main": "src/interrupt.js",
|
"main": "src/interrupt-packet.mjs",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "a class for adding interrupt processesing for gpio pins on Raspberry Pi and Similar SBCs",
|
"description": "a class for adding interrupt processesing for gpio pins on Raspberry Pi and Similar SBCs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"testi": "node test/interrupt.test.js",
|
"mock": "sudo SOCKETS_DIR=/opt/sockets node_modules/.bin/nodemon --require @std/esm examples/mock",
|
||||||
"testw": "./node_modules/.bin/mocha --reporter list --recursive ",
|
"mockl": "sudo DEBUG=true SOCKETS_DIR=/opt/sockets node_modules/.bin/nodemon --require @std/esm examples/mock"
|
||||||
"test": "istanbul cover ./node_modules/.bin/_mocha test/ --report lcovonly -- -R spec --recursive && codecov || true",
|
|
||||||
"watch": "./node_modules/.bin/npm-watch"
|
|
||||||
},
|
},
|
||||||
"author": "David Kebler",
|
"author": "David Kebler",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -29,12 +27,14 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pigpio": "^0.x"
|
"pigpio": "^0.x"
|
||||||
},
|
},
|
||||||
|
"@std/esm": "cjs",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^3.5.0",
|
"@std/esm": "^0.22.0",
|
||||||
"chai-as-promised": "^6.0.0",
|
"chai": "^4.1.2",
|
||||||
"codecov": "^1.0.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
|
"codecov": "^3.0.0",
|
||||||
"istanbul": "^0.4.5",
|
"istanbul": "^0.4.5",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^5.0.1",
|
||||||
"npm-watch": "^0.1.7"
|
"nodemon": "^1.14.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
import bus, { Gpio as gpio } from 'pigpio'
|
||||||
|
// import btc from 'better-try-catch'
|
||||||
|
// import Base from '@uci/base'
|
||||||
|
import Base from '@uci/base'
|
||||||
|
|
||||||
|
import logger from '@uci/logger'
|
||||||
|
let log = {}
|
||||||
|
const LOG_OPTS = (id) => {
|
||||||
|
return {
|
||||||
|
repo:'uci-mcp',
|
||||||
|
npm:'@uci/mcp',
|
||||||
|
file:'src/mcp230xx-packet.mjs',
|
||||||
|
class:'MCP230XX',
|
||||||
|
id:id,
|
||||||
|
instance_created:new Date().getTime()
|
||||||
|
}}
|
||||||
|
|
||||||
|
export default class Interrupt extends Base {
|
||||||
|
constructor(pins,opts={}) {
|
||||||
|
|
||||||
|
opts.sockets = opts.sockets ? (opts.sockets + ',') : ''
|
||||||
|
if (opts.path || opts.itrn) {
|
||||||
|
opts.itrn = opts.itrn || {}
|
||||||
|
opts.itrn.path = opts.path || opts.itrn.path || (process.env.SOCKETS_DIR || __dirname) + '/interrupt.sock'
|
||||||
|
opts.sockets = opts.sockets + 'itrn#c>n,'
|
||||||
|
}
|
||||||
|
if (opts.itrt || opts.host) {
|
||||||
|
opts.itrt = opts.itrt || {}
|
||||||
|
opts.itrt.host = opts.host || opts.itrt.host
|
||||||
|
opts.itrt.port = opts.itrt.port || opts.port || 1777
|
||||||
|
opts.sockets = opts.sockets + 'itrt#c>t'
|
||||||
|
}
|
||||||
|
if (opts.sockets==='') throw ('must have at least one socket client')
|
||||||
|
console.dir(opts)
|
||||||
|
super(opts)
|
||||||
|
log = logger.child(LOG_OPTS(this.id))
|
||||||
|
log.info({pins:pins, opts:opts},'create interrupts with these opts')
|
||||||
|
this.mock = opts.mock
|
||||||
|
this.mode = gpio.INPUT
|
||||||
|
this.pull = opts.pull || gpio.PUD_DOWN
|
||||||
|
this.edge = opts.edge || gpio.RISING_EDGE
|
||||||
|
this.interrupts = {}
|
||||||
|
for(let pin of pins) {
|
||||||
|
if (typeof pin==='number') {pin={num:pin}}
|
||||||
|
this.interrupts[pin.num] = {
|
||||||
|
pin: new gpio(
|
||||||
|
pin.num,
|
||||||
|
{
|
||||||
|
mode: pin.mode || this.mode,
|
||||||
|
pullUpDown: pin.pull || this.pull
|
||||||
|
// do not! set edge here as it will start the emitter -- see pigio js
|
||||||
|
}),
|
||||||
|
edge: pin.edge || this.edge,
|
||||||
|
socket: pin.socket,
|
||||||
|
cmd: pin.cmd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end constructor
|
||||||
|
|
||||||
|
|
||||||
|
async init(){
|
||||||
|
await super.init()
|
||||||
|
|
||||||
|
// for cntrl-c exit of interrupt
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
this.exit().then((resp) => console.log('\n', resp)) // unexport on cntrl-c
|
||||||
|
.catch(err => console.log('error:', err))
|
||||||
|
})
|
||||||
|
for(const pin_num in this.interrupts) {
|
||||||
|
let pin = this.interrupts[pin_num].pin
|
||||||
|
let edge = this.interrupts[pin_num].edge
|
||||||
|
console.log(`starting interrupt on pin ${pin_num}`)
|
||||||
|
pin.on('interrupt', this.interruptProcess.bind(this,pin_num))
|
||||||
|
// rock n roll!!, start the pigpio interrupt
|
||||||
|
console.log('edge=',edge)
|
||||||
|
if(!this.mock) pin.enableInterrupt(edge)
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end constructor
|
||||||
|
|
||||||
|
// manual firing for testing
|
||||||
|
fire(pin_num) {
|
||||||
|
console.log('manually firing interrupt for pin', pin_num)
|
||||||
|
this.interrupts[pin_num].pin.emit('interrupt',null)
|
||||||
|
}
|
||||||
|
|
||||||
|
exit() {
|
||||||
|
bus.terminate()
|
||||||
|
return Promise.reject('keyboard termination...terminating interrupts')
|
||||||
|
}
|
||||||
|
|
||||||
|
interruptProcess (pin) {
|
||||||
|
console.log('=======================')
|
||||||
|
console.log(`pin ${pin} on rpi bus has thrown an interrupt`)
|
||||||
|
console.log('this is the default processor')
|
||||||
|
console.log('replace "interruptProcess" for your instance or extended class')
|
||||||
|
console.log('=======================')
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end Class
|
||||||
|
|
||||||
|
// default handler just logs the pin number fired
|
||||||
|
// overwrite with actual socket send with appropriate packet
|
Loading…
Reference in New Issue