Skip to content

Commit 1305c7b

Browse files
committed
Makes fully class-based and emits change events
1 parent 396e306 commit 1305c7b

File tree

2 files changed

+116
-96
lines changed

2 files changed

+116
-96
lines changed

examples/cap1188-events.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const connect = require("../").connect;
2+
3+
// Connect to the CAP1188 breakout.
4+
// Returns a promise that resolves to the
5+
// CAP1188 instance when it's ready.
6+
const connectionPromise = connect();
7+
8+
// When it's ready, add a listener that emits
9+
// when a touch is registered
10+
connectionPromise.then(cap1188 => {
11+
cap1188.on("change", function(evt) {
12+
console.log(evt);
13+
});
14+
});

lib/CAP1188.js

Lines changed: 102 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
A port of the same library for Espruino:
88
http://www.espruino.com/CAP1188
99
*/
10+
const EventEmitter = require("events").EventEmitter;
11+
1012
var C = {
1113
ADDRESS_DEFAULT: 0x29
1214
};
@@ -26,128 +28,132 @@ var B = {
2628
MAIN_CONTROL_INT: 0x0
2729
};
2830

29-
function CAP1188(_i2c, _opts) {
30-
_opts = _opts == null ? {} : _opts;
31-
this.i2c = _i2c;
31+
class CAP1188 extends EventEmitter {
32+
constructor(_i2c, _opts) {
33+
super();
34+
35+
_opts = _opts == null ? {} : _opts;
36+
this.i2c = _i2c;
37+
38+
// Support old API where second param was _addr
39+
if (typeof _opts === "number") {
40+
this.addr = _opts;
41+
} else {
42+
this.addr = _opts.address || C.ADDRESS_DEFAULT;
43+
this.resetPin = _opts.resetPin || null;
44+
}
3245

33-
// Support old API where second param was _addr
34-
if (typeof _opts === 'number') {
35-
this.addr = _opts;
36-
} else {
37-
this.addr = _opts.address || C.ADDRESS_DEFAULT;
38-
this.resetPin = _opts.resetPin || null;
46+
this.pollingIntervalMs = _opts.pollingIntervalMs || 500;
47+
this.pollingId = null;
48+
this.lastTouches = [false, false, false, false, false, false, false, false];
49+
50+
this.initialize();
3951
}
4052

41-
this.initialize();
42-
}
53+
/* Initialize the chip */
54+
initialize() {
55+
this.linkLedsToSensors();
56+
this.multipleTouches(true);
57+
// "Speed up a bit"
58+
this.i2c.writeSync(this.addr, R.STANDBY_CONFIG, Buffer.from([0x30]));
4359

44-
/* Initialize the chip */
45-
CAP1188.prototype.initialize = function() {
46-
this.linkLedsToSensors();
47-
this.multipleTouches(true);
48-
// "Speed up a bit"
49-
// this.i2c.writeTo(this.addr, [R.STANDBY_CONFIG, 0x30]);
50-
this.i2c.writeSync(this.addr, R.STANDBY_CONFIG, Buffer.from([0x30]));
51-
};
60+
this.scheduleTouchPoll = this.scheduleTouchPoll.bind(this);
5261

53-
/* Reset the chip if a reset pin has been specified */
54-
CAP1188.prototype.reset = function(callback) {
55-
throw new Error('Reset not currently supported');
62+
// Begin polling touches when a listener is
63+
// registered
64+
this.once("newListener", this.scheduleTouchPoll);
65+
}
5666

57-
var delay = 100,
58-
pin = this.resetPin,
59-
self = this;
67+
/* Begins polling for touches and
68+
emits events when they change */
69+
scheduleTouchPoll() {
70+
this.readTouchesAndEmit();
71+
setTimeout(this.scheduleTouchPoll, this.pollingIntervalMs);
72+
}
6073

61-
if (pin == null) {
62-
throw new Error('CAP1188 reset called but no resetPin given');
74+
readTouchesAndEmit() {
75+
var lastTouches = this.lastTouches;
76+
var currentTouches = this.readTouches();
77+
var changes = [];
78+
79+
for (var i = 0; i < 8; i++) {
80+
if (currentTouches[i] !== lastTouches[i]) {
81+
changes.push({ id: i, touched: currentTouches[i] });
82+
}
83+
}
84+
85+
if (changes.length > 0) {
86+
this.emit("change", { changes: changes, touches: currentTouches });
87+
this.lastTouches = currentTouches;
88+
}
6389
}
6490

65-
pin.write(0);
66-
setTimeout(function() {
67-
pin.write(1);
68-
setTimeout(function() {
69-
pin.write(0);
70-
setTimeout(function() {
71-
self.initialize();
72-
if (callback) {
73-
callback();
74-
}
75-
}, delay);
76-
}, delay);
77-
}, delay);
78-
};
91+
/* How many simultaneous touches to allow */
92+
multipleTouches(enable) {
93+
// 1 will block multiple touches
94+
this.writeBit(R.MULTI_TOUCH_CONFIG, 7, enable ? 0 : 1);
95+
}
7996

80-
/* How many simultaneous touches to allow */
81-
CAP1188.prototype.multipleTouches = function(enable) {
82-
// 1 will block multiple touches
83-
this.writeBit(R.MULTI_TOUCH_CONFIG, 7, enable ? 0 : 1);
84-
};
97+
/* Link the LED to corresponding sensor */
98+
linkLedsToSensors() {
99+
for (var i = 0; i < 8; i++) {
100+
this.linkLedToSensor(i, 1);
101+
}
102+
}
85103

86-
/* Link the LED to corresponding sensor */
87-
CAP1188.prototype.linkLedsToSensors = function() {
88-
for (var i = 0; i < 8; i++) {
89-
this.linkLedToSensor(i, 1);
104+
/* Link LED pin to sensor */
105+
linkLedToSensor(num, enable) {
106+
this.writeBit(R.SENSOR_INPUT_LINKING, num, enable);
90107
}
91-
};
92108

93-
/* Link LED pin to sensor */
94-
CAP1188.prototype.linkLedToSensor = function(num, enable) {
95-
this.writeBit(R.SENSOR_INPUT_LINKING, num, enable);
96-
};
109+
/* Read state of all sensors */
110+
readTouches() {
111+
var touches = [],
112+
raw;
97113

98-
/* Read state of all sensors */
99-
CAP1188.prototype.readTouches = function() {
100-
var touches = [],
101-
raw;
114+
// this.i2c.writeTo(this.addr, R.SENSOR_INPUT_STATUS);
115+
this.i2c.writeSync(this.addr, Buffer.from([R.SENSOR_INPUT_STATUS]));
102116

103-
// this.i2c.writeTo(this.addr, R.SENSOR_INPUT_STATUS);
104-
this.i2c.writeSync(this.addr, Buffer.from([R.SENSOR_INPUT_STATUS]));
117+
// raw = this.i2c.readFrom(this.addr, 1)[0];
118+
raw = this.i2c.readSync(this.addr, 1)[0];
105119

106-
// raw = this.i2c.readFrom(this.addr, 1)[0];
107-
raw = this.i2c.readSync(this.addr, 1)[0];
120+
if (raw) {
121+
// Clear interrupt to be able to read again
122+
this.writeBit(R.MAIN_CONTROL, B.MAIN_CONTROL_INT, 0);
123+
}
108124

109-
if (raw) {
110-
// Clear interrupt to be able to read again
111-
this.writeBit(R.MAIN_CONTROL, B.MAIN_CONTROL_INT, 0);
112-
}
125+
for (var i = 0; i < 8; i++) {
126+
touches[i] = this.getBit(raw, i);
127+
}
113128

114-
for (var i = 0; i < 8; i++) {
115-
touches[i] = this.getBit(raw, i);
129+
return touches;
116130
}
117131

118-
return touches;
119-
};
120-
121-
/* */
122-
CAP1188.prototype.getBit = function(byt, position) {
123-
return 1 == ((byt >> position) & 1);
124-
};
132+
/* */
133+
getBit(byt, position) {
134+
return 1 == ((byt >> position) & 1);
135+
}
125136

126-
/* Set a single bit in a register */
127-
CAP1188.prototype.writeBit = function(reg, bit, val) {
128-
// this.i2c.writeTo(this.addr, reg);
129-
this.i2c.writeSync(this.addr, Buffer.from([reg]));
137+
/* Set a single bit in a register */
138+
writeBit(reg, bit, val) {
139+
this.i2c.writeSync(this.addr, Buffer.from([reg]));
130140

131-
// var b = this.i2c.readFrom(this.addr, 1)[0];
132-
var b = this.i2c.readSync(this.addr, 1)[0];
141+
var b = this.i2c.readSync(this.addr, 1)[0];
133142

134-
b = val !== 0 ? b | (1 << bit) : b & ~(1 << bit);
143+
b = val !== 0 ? b | (1 << bit) : b & ~(1 << bit);
135144

136-
// this.i2c.writeTo(this.addr, [reg, b]);
137-
this.i2c.writeSync(this.addr, reg, Buffer.from([b]));
138-
};
145+
this.i2c.writeSync(this.addr, reg, Buffer.from([b]));
146+
}
139147

140-
/* Set more bits in a register */
141-
CAP1188.prototype.writeBits = function(reg, shift, val) {
142-
// this.i2c.writeTo(this.addr, reg);
143-
this.i2c.writeSync(this.addr, Buffer.from([reg]));
144-
// var b = this.i2c.readFrom(this.addr, 1)[0];
145-
var b = this.i2c.readSync(this.addr, 1)[0];
148+
/* Set more bits in a register */
149+
writeBits(reg, shift, val) {
150+
this.i2c.writeSync(this.addr, Buffer.from([reg]));
151+
var b = this.i2c.readSync(this.addr, 1)[0];
146152

147-
b = b | (val << shift);
148-
// this.i2c.writeTo(this.addr, [reg, b]);
149-
this.i2c.writeSync(this.addr, reg, Buffer.from([b]));
150-
};
153+
b = b | (val << shift);
154+
this.i2c.writeSync(this.addr, reg, Buffer.from([b]));
155+
}
156+
}
151157

152158
exports.connect = function(_i2c, _addr) {
153159
return new CAP1188(_i2c, _addr);

0 commit comments

Comments
 (0)