Open adonespitogo opened 6 years ago
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time.
I haven't seen something like this in the past. This doesn't however mean that it's not happening.
I'd just like to know if you have any idea on top of your head what might be the cause of this issue.
Do the pulses from the coin acceptor bounce? If so, this may explain what's happening.
There is a delay between point in time when an interrupt occurs and point in time when the callback passed to the Epoll
constructor is called. Between those two points in time the pin state may change. If the pin state changes between these points in time then the value read from the GPIO will not be the expected value. This can happen with momentary push buttons that bounce. Perhaps there is a similar effect with the coin acceptor.
I tried using debounceTimeout option from onoff npm package. I tested with values 1,10, 15. But as the number gets larger, the more interrupts are being skipped.
I solved my problem by using python instead and polling the value by reading the gpio#/value with interval 10ms, since python never skips a tick unlike nodejs' setTimeout/setInterval.
I have no knowledge with c language and can't dig on this issue. I can close this issue if you think this is unlikely to be epolls shortcoming.
On Sun, Apr 15, 2018, 1:13 AM Brian Cooke, notifications@github.com wrote:
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time.
I haven't seen something like this in the past. This doesn't however mean that it's not happening.
I'd just like to know if you have any idea on top of your head what might be the cause of this issue.
Do the pulses from the coin acceptor bounce? If so, this may explain what's happening.
There is a delay between point in time when an interrupt occurs and point in time when the callback passed to the Epoll constructor is called. Between those two points in time the pin state may change. If the pin state changes between these points in time then the value read from the GPIO will not be the expected value. This can happen with momentary push buttons that bounce. Perhaps there is a similar effect with the coin acceptor.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/fivdi/epoll/issues/26#issuecomment-381344437, or mute the thread https://github.com/notifications/unsubscribe-auth/ADqWxEe4skVNNumssPzCAwJP5H6qiFCDks5toi4xgaJpZM4TVFRq .
Let's leave the issue open. I'll take a closer look at some point to see if something goes wrong when the process is inactive for a long period of time.
Thank you for reporting this issue.
Thanks as well for this project. Still a great library :)
On Sun, Apr 15, 2018, 2:04 AM Brian Cooke, notifications@github.com wrote:
Let's leave the issue open. I'll take a closer look at some point to see if something goes wrong when the process is inactive for a long period of time.
Thank you for reporting this issue.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/fivdi/epoll/issues/26#issuecomment-381348366, or mute the thread https://github.com/notifications/unsubscribe-auth/ADqWxP4YELYUmyPrPgmHw6A8G7e-u1mzks5tojpHgaJpZM4TVFRq .
@adonespitogo above you mention the following:
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time
Approximately how long is it necessary to wait before the issue can be seen?
Actually, I just realize that this has become very random. I didnt have to wait so long, it can happen within a minute. Sometimes, even on first insertion of coin. Sometimes, on second, on third insertion. Sometimes it doesn't occur within 15 mins of trying to insert coin at around 30s - 1min interval.
On Sun, Apr 15, 2018, 4:03 AM Brian Cooke, notifications@github.com wrote:
@adonespitogo https://github.com/adonespitogo above you mention the following:
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time
Approximately how long is it necessary to wait before the issue can be seen?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fivdi/epoll/issues/26#issuecomment-381356597, or mute the thread https://github.com/notifications/unsubscribe-auth/ADqWxDx_DxEhSzImqcSr1XAZu_rRZm_Sks5tolX_gaJpZM4TVFRq .
I think theres a problem either in the emiting of the interrupt, in which case the epoll is not at fault. Or theres a problem with epoll with regards to the delay of the callback as you mentioned.
Regarding the debounce, I think the problem doesn't lie there because I tried using the debounceTimeout option of onoff library with no success.
My suspicion is that since nodejs is single threaded, the callback may have been delayed.
On Sun, Apr 15, 2018, 4:10 AM adones pitogo, pitogo.adones@gmail.com wrote:
Actually, I just realize that this has become very random. I didnt have to wait so long, it can happen within a minute. Sometimes, even on first insertion of coin. Sometimes, on second, on third insertion. Sometimes it doesn't occur within 15 mins of trying to insert coin at around 30s - 1min interval.
On Sun, Apr 15, 2018, 4:03 AM Brian Cooke, notifications@github.com wrote:
@adonespitogo https://github.com/adonespitogo above you mention the following:
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time
Approximately how long is it necessary to wait before the issue can be seen?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fivdi/epoll/issues/26#issuecomment-381356597, or mute the thread https://github.com/notifications/unsubscribe-auth/ADqWxDx_DxEhSzImqcSr1XAZu_rRZm_Sks5tolX_gaJpZM4TVFRq .
Thanks for the information.
I'll implement a stress test and run it for a several hours to see what happens. The pulses from the coin acceptor could be generated by a second Raspberry Pi or an AVR microcontroller.
This is my code by the way, I believe this might be of use as reference for your stress test:
'use strict'
const Q = require('q')
const payment = require('./payment.js');
const config = require('./config/config.json')
const Gpio = require('onoff').Gpio
module.exports.init = function () {
let coinslot = new Gpio(451, 'in', 'both')
let time_now = 0
let last_detect_time = 0
let has_detected = false
let diff = 0
let current_total = 0
let interval = 100
let prev_val = 1
function checkDoneInsert() {
if (has_detected) {
time_now += interval
diff = time_now - last_detect_time
if (diff > 1000) {
console.log('payment: ', current_total)
payment.received(current_total);
current_total = 0
diff = 0
time_now = 0
last_detect_time = 0
has_detected = false
}
}
}
function onChange(val) {
if (val === 1 && prev_val === 0) {
has_detected = true
last_detect_time = time_now
current_total += 1
}
prev_val = val
}
coinslot.watch(function (err, val) {
if (err)
console.log(err)
else
onChange(val)
})
setInterval(function () {
checkDoneInsert()
}, interval)
return Q()
}
After some experimentation I think the most likely cause for failing to detect some of the pulses from the coin acceptor is blocking synchronous code.
coin-acceptor.c is a program that can be used to simulate the coin acceptor on an atmega328p. Every two seconds the program will generate five pulses to simulate a five peso coin. The program stops after simulating 10.000 coins.
coin-counter-success.js successfully detects the pulses for 10.000 five peso coins.
coin-counter-fail.js fails to detect all the pulses for 10.000 five peso coins. Each pulse is low for 20 milliseconds and high for 100 milliseconds. The program fails to detect approximately 7% of the pulses. The failures occur because the program blocks the main JavaScript thread by executing synchronous code for 30 milliseconds once per second. The 30 milliseconds of blocking is longer that 20 milliseconds for which the pulse is low and the JavaScript code doesn't get around to processing some of the falling edges before the rising edges occur.
The last 16 lines of output for one run of coin-counter-success.js:
fallingPulses: 49975, risingPulses: 49975, errors: 0
fallingPulses: 49975, risingPulses: 49975, errors: 0
fallingPulses: 49980, risingPulses: 49980, errors: 0
fallingPulses: 49980, risingPulses: 49980, errors: 0
fallingPulses: 49981, risingPulses: 49981, errors: 0
fallingPulses: 49985, risingPulses: 49985, errors: 0
fallingPulses: 49985, risingPulses: 49985, errors: 0
fallingPulses: 49990, risingPulses: 49990, errors: 0
fallingPulses: 49990, risingPulses: 49990, errors: 0
fallingPulses: 49992, risingPulses: 49991, errors: 0
fallingPulses: 49995, risingPulses: 49995, errors: 0
fallingPulses: 49995, risingPulses: 49995, errors: 0
fallingPulses: 50000, risingPulses: 50000, errors: 0
fallingPulses: 50000, risingPulses: 50000, errors: 0
fallingPulses: 50000, risingPulses: 50000, errors: 0
fallingPulses: 50000, risingPulses: 50000, errors: 0
The last 16 lines of output for one run of coin-counter-fail.js:
fallingPulses: 46503, risingPulses: 49985, errors: 0
fallingPulses: 46505, risingPulses: 49987, errors: 0
fallingPulses: 46505, risingPulses: 49987, errors: 0
fallingPulses: 46509, risingPulses: 49992, errors: 0
fallingPulses: 46509, risingPulses: 49992, errors: 0
fallingPulses: 46511, risingPulses: 49995, errors: 0
fallingPulses: 46513, risingPulses: 49997, errors: 0
fallingPulses: 46513, risingPulses: 49997, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
fallingPulses: 46518, risingPulses: 50002, errors: 0
epoll has its own thread for detecting events. The code in this thread could be modified to queue events for later processing. Events that occur when blocking JavaScript synchronous code is executing for prolonged periods of time would then be queued and could be processed later without getting 'lost'.
Wow thanks for taking the time to test this. I'm really looking forward for the fix for this. Right now I'm using polling to detect the coins and it's taking a bit of processing resources by constantly reading the gpio value every 10ms.
Hi, I'm trying to interface a multi coin acceptor with Espressobin. This coin acceptor emits pulses for every coin inserted. For example 1 peso coin (I'm in philippines) pulses 0 for 20ms and then pulses 1 for 100ms (using 'both' edge). It turns the GPIO input to 0 for 20ms and turns to 1 for 100ms. It does this one time for 1 peso coin and 5 times for 5 peso coin.
So if you print the value of 'both' edge every time an interrupt occurs, this is the output:
1 peso coin:
5 peso coin:
The problem is that sometimes, some of the interrupts are not detected by the epoll library when I'm no longer interacting with the coin acceptor after sometime. What happens is, for example inserting a 5 peso coin to the multi coin acceptor results to:
I think the interrupt detection job is somewhat put to background or something that's why it can't properly detect the pulses when there is no activity for some time. In the next consecutive insertion of coins, it properly detects the coins again.
I can confirm that the problem is not the circuit or the coin acceptor because this doesn't happen when I use the same schematics on raspberry pi's GPIO and a python script.
I'd just like to know if you have any idea on top of your head what might be the cause of this issue.