Does any GPIO node support edge events, rising or falling state changes?

Does any GPIO node support edge events, rising or falling state changes? Looking 'pi gpio node' it is just binary digital logic (0|1) state. I have use case where I need to sense rising or falling state. This is easy to do say from python for example.

Do you mean you are looking for the equivalent of a combined gpio In and a Switch in one node?

That is what the digital input of the gpio node does. It waits for an edge and uses that to send the new state.

No, that is not what I am asking... With various GPIO libraries you can detect the actual edge shift, such as when a button is being pressed, not already pressed. Or when button is being released, not already released. This feature set does not appear to be part of any NR node library that I have found as yet. This is not digital on/off input state, but the actual state transition being sensed. Typically you use GPIO add/remove event detect handlers to invoke a callback for the rising or falling state of input in progress, not input completed. A digital state is the result only at the end of the transition, but not the actual circuit behavior alone. You can do all kinds of interesting things with this transition of states. Like how a touch phone screen does interesting things beyond simple digital on/off state inputs.

I think you are too tied up in the question that you are missing what you are being told.

That is exactly what the nodes @dceejay do.

The "transit time" from being pressed to actually being pressed - which you seem to be stuck - is small.

Think about it.
The button is.... at rest. Released or pressed.
The GPIO pin is .... at what ever level. High or Low. (1 or 0)

The button is pressed and for a small moment in time there is an edge as it changes.

What ever you call it is by the by. The nodes mentioned should do what you want.

I fear/feel you are lost with the terms being used and that won't help the situation.

There is nothing wrong with trying the nodes just to try them.

Rising and falling state timing is not so small that code can not respond to it. GPIO libraries such as RPi.GPIO for python support logic to watch and act on the actual rise and fall of the circuit before/after 1 or 0 is the digital state. So there is more to the circuit than just a 1 or 0 state. But apparently not supported well or at all via NR...via node module/libraries.

I have already written a python script that does catch the rise and fall of the circuit state, and reports the result via MQTT to NR. Not a 100% NR solution, but works. This allows for such monitoring as a Fan Tachometer value for example, where you read the fall of the circuit state, as a pulse and then can compute the number pulses per time frame (fraction of second based on the fan motor duty cycle), to establish RPM of the fan for example.

There are several forum posts asking how to read a fan tachometer within NR, but such would required NR GPIO node to catch the rise and fall of the GPIO pin state. This is what I can't as yet find in any NR module I have found as yet. Hence my question.

It maybe, likely, that NR can't work consistently at the timing resolution that is needed to capture say such tachometer pulsing. The more flows active, the less timing resolution possible. Even with python there is degree of variance, that effects the values resulting.

One example is to use an Arduino to capture the fan pulsing and forward the estimated RPM values to NR via MQTT. Given Arduino running C as lean as possible, that makes sense, and likely more accurate in total than my python script, but I don't need explicit accuracy, just validation that the fan is running close to the expected RPM target value.

The goal is still to find a 100% NR oriented solution of course, where I can get a reasonable RPM estimate, so still looking and thinking of ways it might work. :slight_smile:

Here is first attempt to monitor fan performance (tachometer pin on 3 pin fan) via NR only. Unfortunately, the interval timings are highly variable, thus the estimated RPM values are inconsistent. For a fan that consistently runs between 990 and 1020 RPM, often 1000 to 1010 per my python script, NR flow comparatively starts well, but then is all over the place.

Python3 Script Results...


Mean 1004.654688, Variance 28.883861, Deviation 5.374371

NR flow results...


The above was on a Pi3 Model B+ that is fairly busy, have 20 odd flows, some of them quite demanding at completely random intervals or patterns. Using the rising or falling events (via python RPi.GPIO) to trigger the interval sampling provides a tighter interval consistency, thus a more consistent RPM estimation.

Using ESP32 or ESP8266 to sample and forward to NR is another possibility of course. Forgot to mention this when notating Arduino as an option.

I could always cheat... using mean, variance, and standard deviation values to strip odd values from a larger sample population, then recalculate the mean as the reported tachometer value. Dirty, sneaky... but maybe one way to do it.

I think you are using the wrong tool for the job.

NR has time limit constrains on it to how fast it can scan GPIO pins and spit out things.
It isn't written to specifically scan one GPIO pin because you want it to do that.

If you want it to that resolution, it would be better you write the code yourself.
And what you have posted above, you already have.

I get it that things can get/be frustrating.

But it is only you who can decide when you are going to stop re-inventing the wheel - as most programs are already written, it is just a case of finding them - and cut the losses and write your own stuff.

I would like to be able to do that, but can't.

Good? Bad? Who knows? It is what it is.

How were you thinking such a node might interact with node red?

To be clear... the way the current pi gpio nodes work is that they call out to python...

in there for an input pin we setup the edge interrupt as

        if bounce > 0:
            GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=int(bounce))
        else :
            GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback)

so we look for both edges, and then the callback is

        def handle_callback(chan):
            if bounce > 0:

so I think apart from the if statement checking the debounce time that we respond as quickly as we can - then as we know, node is single threaded so all the other flows may indeed get in the way of doing accurate time measurements... (and not to mention any gc activity that may occur.)

Of course if someone wanted to enhance the gpio nodes to include either a count per second or timegap between edges type modes then they could happily be discussed and a pull request considered,

Right, but the original question was... if there was a NR module/node library GPIO library that do expose the low level event driven feature set for GPIO. The answer is no. There is not, that I have found. That is fine. As I noted, this not a surprise given the nature and limits NR has, either its self, or by the modules used per implemented design. What is cool of course is that what the current nodes do under the hood of course as dceejay illustrated, thanks for that.

At no point did I find this frustrating. Not sure where that impression came from? :slight_smile:

Of course if someone wanted to enhance the gpio nodes to include either a count per second or timegap between edges type modes then they could happily be discussed and a pull request considered,

Is this likely? No sure, seems more of a niche need? I mean the forum is not flooded with requests to do such? What we have now works fine most of the time, right?

The python script I have is functional, and this is not the first time such a method has been needed or used by myself or others. I have done this method to reduce load on PiZero devices where running extensive flows slams the poor zeros. It just would be preferred to avoid it and keep within NR so to speak.

Would be interesting when at some point in the future, NR could be, how should I say it, thread friendly as well, but that an entirely different can of worms, right?

I think most users would offload something lke this to something like a Wemos or an Arduino so that real time calculations can be guaranteed.

1 Like

No reason why a Pi shouldn't be able to handle 1kHz...

You are right. I was misinterpreting the requirement, I thought @Nodi.Rubrum was trying to measure the time between edges, and perhaps he is doing that, but if he just needs the speed say once a second then the problem is much easier to solve, and I would have thought that even node-red would handle it ok.
@Nodi.Rubrum how have you attempted to do this in node-red?

Yes he has - see results table above...
When I said Pi could do it - I carefully didn't say Node-RED could :-). (yet)...
Doing it externally in C or python means you can dedicate a thread or core to it so the rest of Node-RED won't be affected. This could be done using usual mqtt as a bridge between them (as already implemented - but could be more "built in" by extending the existing gpio node to add some more sub commands to the existing nrgpio python script to help do this... if someone wanted to have a go.

I only mentioned this because sometimes I get frustrated when I am on a quest to get something done only to discover it can't be done.

@Trying_to_learn, OH! OK.

@dceejay, I am trying a couple of things beyond the above, to see if I can do it completely within NR that is closer to the python script method, just for the fun of the attempt. The issue is, of course the NR misses pulses, time interval is inconsistent at times... but if I take a bigger sample size, and drop the more (obvious) RPM estimates that are off the mark, I think I can get something that seems reasonable. I think I will keep my python script as a sanity check.

What algorithm are you using to calculate the speed?

How often do you need an output giving the speed?

Speed or RPM estimate is done via counting pulses per the time frame. When I do this via python using an event handler, the time frame can be variable (but typically about 0.02 seconds). The number of pulses is based on typical make and model of the fan given its respective duty cycle.

The code I migrated from python, using in the test flow:

    if (msg.payload == ZERO) {
        theInterval = new Date().getTime()/1000 - (flow.get('Time') || ZERO);

        if (theInterval > 0.01) {

            theFrequency = ONE / theInterval;
            theRevolution = (theFrequency / TWO) * SIXTY
            flow.set('Time', new Date().getTime()/1000);

In python randomly you do get a few pulses that come to fast too want to process, since the 0.01 limit. This happens if the fan happens to slow or speed up for example. I am not driving the fan speed by PWM for the given testing, and even though it is a 12 DC fan, I am driving it at only 5v, so I get approximately 990 to 1030 RPM, but if I was running at 12 DC, would 2700 to 3000 at a minimum, some fan models at 12 DC more than 6000.

I have not added the 'time out' logic as yet, such that if the fan RPM is 0 or some low threshold, I generate an alert, my python script does this via a monitoring thread task function. So for example if no pulse is received in 5 seconds... time out, and error message sent. At some point I will do a simple interrupt or such in the NR logic to mirror the same feature.