Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupt misfire #191

Closed
ZBAGI opened this issue Dec 16, 2021 · 3 comments
Closed

Interrupt misfire #191

ZBAGI opened this issue Dec 16, 2021 · 3 comments

Comments

@ZBAGI
Copy link

ZBAGI commented Dec 16, 2021

I trying to read rfid reader via wiegand interface but I seems to have an issue with interrupts.
From time to time I were getting reads that are invalid, after short investigation I noticed that it happens only once, after application started. Here is code example:

const Gpio = require('onoff').Gpio

var timeout, data = [];
function handleBit(pin, val) {
	pin.watch((_, value) => {
		clearTimeout(timeout)
		data.push(val)
		timeout = setTimeout(() => {
			console.log(data.join(""));
			data = []
		}, 30)
	})
}

var d0 = new Gpio(23, 'in', 'rising', {debounceTimeout: 0});
var d1 = new Gpio(24, 'in', 'rising', {debounceTimeout: 0});
handleBit(d0, 0);
handleBit(d1, 1);

Here is test output:

pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
^C
pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
^C
pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
^C
pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
^C
pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
^C
pi@zbagi:~ $ node ./controller/test.js
11001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001
1011000001111011110101010011011001

1011000001111011110101010011011001 is correct data that I would expect to be send every time yet, after each restart for some reason I missing couple interrupts. Since my app is killed while idle and started when needed it is a big issue for me. It does not matter how long I wait from app startup to readout, those couple bits are always missing on the first readout.

Envoierment:

onoff: 6.0.3
node: 17.1.0

raspberry pi: 3 model B
OS:

NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
@ZBAGI
Copy link
Author

ZBAGI commented Dec 16, 2021

Possibly related to fivdi/epoll#26 ?

@edit: I tried to keep application working and looks like after long idle time I still missing 1/2 interrupts on first data broadcast. Just like described in epoll issue linked above

@fivdi
Copy link
Owner

fivdi commented Dec 17, 2021

Possibly related to fivdi/epoll#26 ?

This could very well be the case.

I have never used the Wiegand protocol, but googling says the Wiegand pulse width time is between 20 uS and 100 uS, and the pulse interval time between 200 uS and 20 mS.

If the pulse interval time for your reader is close to 200 uS, I can imagine interrupts being missed, especially at the start of the first read. For example, the JavaScript interpreter may have a lot of work to do for the initial few bits compared to later bits.

@ZBAGI
Copy link
Author

ZBAGI commented Dec 22, 2021

Refreshing timer without allocating a new object thus minimalizing time spent in the watch function seems to help:

const Gpio = require('onoff').Gpio

var data = [];
var timeout = setTimeout(() => {
	if(data.length == 0)
		return;
		
	console.log(data.join(""));
	data = []
}, 30);

function handleBit(pin, val) {
	pin.watch((_, value) => {
		data.push(val)
		timeout.refresh();
	});
}

var d0 = new Gpio(23, 'in', 'rising', {debounceTimeout: 0});
var d1 = new Gpio(24, 'in', 'rising', {debounceTimeout: 0});
handleBit(d0, 0);
handleBit(d1, 1);

Initially I tried to set one interval and save date of last bit broadcasted, but timeout = Date.now() seems to be not fast enough and still caused interrupts to be missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants