pin.on 'change' event not working properly
Closed this issue · 7 comments
I am playing with the pin.pull
right now and I am still experiencing some odd behavior. If I run a simple setInterval
loop like the following it works fine... meaning I have the pin.pull('pulldown')
set and when I push a button it sends 3.3V to that pin and will toggle back and forth between 0 and 1 as expected.
setInterval(function() {
pin.read(function(err, val) {
console.log('pull down val', val);
});
}, 500);
But, if I setup a change
event on the pin it will only read the event the first time the button is pressed (it actually reads it twice for some reason) but it never returns to 0 an therefore the change
event never fires again.
pin.on('change', function() {
pin.read(function(err, val) {
console.log('pull down val', val);
});
});
@rwaldron I have tried to debug this on my own without luck yet... do you have any idea what might be causing this behavior?
All I have found so far is that the first time I push the button the "byte" value is 194 (for pin 2) and from that point on the "byte" value is only 130 or 131 depending on if it is high or low. So whatever causes the "byte" value to reflect the change
event is only happing once?
var REPLY = {
ACK: 0x80,
NACK: 0x81,
HIGH: 0x82, //=130
LOW: 0x83, //=131
DATA: 0x84,
MIN_ASYNC: 0xA0,
ASYNC_PIN_CHANGE_N: 0xC0, //=194 for pin 2
ASYNC_UART_RX: 0xD0
};
Sorry, it seems I missed this when you first posted. Will try to repro now
Ok, I put together this circuit:
And ran this code:
[2, 5, 6, 7].forEach(index => {
tessel.ports.A.pin[index].on('change', function() {
console.log(index);
});
});
And I'm able to observe change events for the life of the program. What I find problematic is that I don't know the state of the pin when that change event is fired. I'm going to attempt to co-opt bit 3 as a "value field", ie.
With a console.log(replyBuf);
on line 173 of tessel-export.js.
Pin | Byte | Bits: As-is | Proposed Bits: High |
---|---|---|---|
2 | 0xc2 |
0b11000010 |
0b11001010 |
5 | 0xc5 |
0b11000101 |
0b11001101 |
6 | 0xc6 |
0b11000110 |
0b11001110 |
7 | 0xc7 |
0b11000111 |
0b11001111 |
I wasn't using the resistor (as shown in your example) because I was using the built-in pulldown/pullup resistors running the code below. I just re-tested it based on what you sent and it seems to work fine without the .read()
within the .on('change')
event.
This doesn't work past the first time the event is fired...
var tessel = require('tessel'); // import tessel
var pin = tessel.port['B'].pin[2];
pin.pull('pulldown');
pin.on('change', function() {
this.read(function(err, val) {
console.log('val', val);
});
});
This works every time the event is fired...
var tessel = require('tessel'); // import tessel
var pin = tessel.port['B'].pin[2];
pin.pull('pulldown');
pin.on('change', function() {
console.log('change event');
});
I guess, if you use .on('rise')
or .on('fall')
you will effectively know the value without even having it available.
Cool. I also think it's important that you should never have to also ask for the value when you get a change event... so I implemented my idea above and it works exactly as I'd hoped. Bit 3 of the interrupt response byte was not in use, bits 0, 1 & 2 were used to indicate that a "change" occurred on a "pin". You could know what pin, but not what its state was... so I put the state in bit 3 and it works perfectly. Patch and tests to follow.
This will definitely work, but I still don't understand why the .read()
within the .on('change')
event would cause the problem I was seeing? I'm just curious as to what was happening I guess.
I played with this some more and discovered that it works fine with .rawRead()
but .read()
definitely doesn't work when called within the callback of the .on('change')
event.
var tessel = require('tessel');
var tesselPort = 'B';
var changeCount = 0;
var pins = [2, 5, 6, 7];
// works with .rawRead() but not with .read()
pins.forEach(pinNum => {
tessel.port[tesselPort].pin[pinNum].pull('pulldown');
tessel.port[tesselPort].pin[pinNum].on('change', function() {
changeCount++;
console.log('pin:', pinNum, 'changeCount:', changeCount);
// this works
this.rawRead(function(err, val) {
console.log('val:', val);
});
// this doesn't work
/*
this.read(function(err, val) {
console.log('val:', val);
});
*/
});
});
setImmediate(function() {
console.log('ready');
});