-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgpiohelper.js
127 lines (99 loc) · 3.04 KB
/
gpiohelper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var fs = require('fs');
function GPIOHelper() {
this.exportPath = "/sys/class/gpio/gpiochip0/subsystem/export";
this.pinDirectionPath = "/sys/class/gpio/gpio$/direction";
this.pinValuePath = "/sys/class/gpio/gpio$/value";
this.pins = [0, 1, 6, 7, 8, 12, 13, 14, 23, 26, 21, 20, 19, 18];
this.pinListeners = {};
this.pinValueCache = {};
// Make sure pins have been exported for read/write
for(var x = 0; x < this.pins.length; x++) {
var pin = this.pins[x];
// If the 'value' path already exists, then we don't need to export.
if(fs.existsSync(this.pinValuePath.replace('$', pin)) === false) {
try {
fs.writeFileSync(this.exportPath, String(this.pins[x]));
} catch(e) {
console.log("Error exporting pin "+this.pins[x]+": "+e.message);
}
}
}
}
GPIOHelper.prototype.setPinDirection = function(pin, dir, callback) {
if(dir !== 'out' && dir !== 'in') {
throw new Error("Invalid pin direction, use 'in' or 'out'.");
}
fs.writeFile(this.pinDirectionPath.replace('$', pin), dir, callback);
};
GPIOHelper.prototype.setPin = function(pin, value, callback) {
var self = this;
this.setPinDirection(pin, 'out', function(err) {
if(err) {
callback(err);
} else {
fs.writeFile(self.pinValuePath.replace('$', pin), value ? '1' : '0', callback);
}
});
};
GPIOHelper.prototype.getPin = function(pin, callback) {
var self = this;
this.setPinDirection(pin, 'in', function(err) {
if(err) {
callback(err);
} else {
fs.readFile(self.pinValuePath.replace('$', pin), function(err, buf) {
if(err) {
callback(err);
} else {
callback(null, parseInt(buf.toString()));
}
});
}
});
};
GPIOHelper.prototype.setPinDirectionSync = function(pin, dir) {
if(dir !== 'out' && dir !== 'in') {
throw new Error("Invalid pin direction, use 'in' or 'out'.");
}
fs.writeFileSync(this.pinDirectionPath.replace('$', pin), dir);
};
GPIOHelper.prototype.setPinSync = function(pin, value) {
this.setPinDirectionSync(pin, 'out');
fs.writeFileSync(this.pinValuePath.replace('$', pin), value ? '1' : '0');
};
GPIOHelper.prototype.getPinSync = function(pin) {
this.setPinDirectionSync(pin, 'in');
var val = fs.readFileSync(this.pinValuePath.replace('$', pin));
return parseInt(val.toString());
};
GPIOHelper.prototype.onPinChange = function(pin, callback) {
if(!this.pinListeners[pin]) {
this.pinListeners[pin] = [];
}
this.pinListeners[pin].push(callback);
this._beginPolling();
};
GPIOHelper.prototype._beginPolling = function() {
if(this._hasBegunPolling) return;
this._hasBegunPolling = true;
var self = this;
this._pollingInterval = setInterval(function() {
self._poll();
}, 0);
}
GPIOHelper.prototype._poll = function() {
for(var pin in this.pinListeners) {
// Read and compare value
var value = this.getPinSync(pin);
if(this.pinValueCache[pin] !== value) {
// Value has changed!
this.pinValueCache[pin] = value;
// Trigger all callbacks
var callbacks = this.pinListeners[pin];
for(var k in callbacks) {
callbacks[k](value);
}
}
}
}
module.exports = GPIOHelper;