pin("change", <cb>) unexpected behavior
benderforbeer opened this issue · 4 comments
I apologize for the vague description upfront, but I'm not sure how to qualify the issue with specificity.
The problem I am having is that running this code, the console will only display three total samples before I have to redeploy the software on the device.
var tessel = require('tessel');
var output = tessel.port.B.pin[7]; // select pin 7 on port B as output
var input = tessel.port.B.pin[2]; // select pin 2 on port B as input
{
// Device specific pin specifications.
let high = 3.3;
let low = 0;
let step = 0.5
let samplecount = 0;
let voltage = high
onPinChanged();
function onPinChanged(pinvalue) {
input.analogRead(function(error, value) {
console.log(samplecount, pinvalue, value);
});
++samplecount;
}
input.on("change", onPinChanged);
setInterval(function () {
output.analogWrite(voltage);
voltage = voltage <= low + step ? high : voltage - step;
}, 500);
}
console.log("(Press CTRL + C to stop)")
Whereas, moving the sampling logic (analogRead
) into the setInterval
callback results in the expected behavior. This leads me to believe a) Im doing something wrong, which would be fantastic because that's an easy problem to solve or b) something with the interrupt pin("change", <cb>)
event is wonky?
var tessel = require('tessel');
var output = tessel.port.B.pin[7]; // select pin 7 on port B as output
var input = tessel.port.B.pin[2]; // select pin 2 on port B as input
{
// Device specific pin specifications.
let high = 3.3;
let low = 0;
let step = 0.5
let samplecount = 0;
let voltage = high
setInterval(function () {
output.analogWrite(voltage);
input.analogRead(function(error, value) {
console.log(samplecount, value > high/2 ? 1 : 0, value);
++samplecount;
});
voltage = voltage <= low + step ? high : voltage - step;
}, 500);
}
Just a heads up, the analogWrite
arguments of 0-3.3 were a bug that was fixed in ab94b62 that will be in the next release.
As for your program, the change
event represents async interrupt detection on both the rising and falling edge. It's likely that your program is writing values that don't represent enough difference between one and the next to be considered a "change". @kevinmehall or @ekolker can probably elaborate on this a bit more.
That aside, what I think you're trying to achieve can be done without interrupts or intervals:
"use strict";
var tessel = require("tessel");
var output = tessel.port.B.pin[7]; // select pin 7 on port B as output
var input = tessel.port.B.pin[2]; // select pin 2 on port B as input
{
let high = 3.3;
let low = 0;
let step = 0.1;
let samplecount = 0;
let voltage = high;
function adcBoomerang(pin, handler) {
pin.analogRead((error, value) => {
handler(value);
setTimeout(_ => adcBoomerang(pin, handler), 50);
});
output.analogWrite(voltage = voltage <= low + step ? high : voltage - step);
}
adcBoomerang(input, value => {
console.log(samplecount++, value);
});
}
console.log("(Press CTRL + C to stop)")
This has been running on my Tessel for around 7 minutes (I just looked in the terminal and the closest sample number my eyes could discern was 85-something-something, so I calculated minutes from that)
@rwaldron Thanks for the quick and detailed response!
Now that you mention/describe the change
behavior, in that it is the differential voltage between the rising and falling edges, it makes perfect since... for digital signals. It would be really interesting if the pin.on("change', ...) signature could accept a predicate so a developer could define what a 'change' means in different contexts.
Thanks so much for the example of the boomerang, this is almost exactly what I'm looking for and will get me where I need to go with my little project.
P.S. Maybe this isn't the most appropriate place to ask, but in the firmware for the ADC, there's a comment about how the ADC is sampling at ~100K Hz (https://github.com/tessel/t2-firmware/blob/master/common/analog.c#L7-L8).
How do I achieve this sampling frequency since the minimum time for setTimeout
is 1ms (1K Hz), or a higher sampling frequency in general? I'm trying not to have aliasing occur when sampling my signal, the higher the frequency the better for what I'm doing (-3db @ 440K Hz - aliasing is already occurring).