petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

GPIO.input voltage levels vs edge detection

Sun Aug 05, 2018 12:47 am

I have been working on a project where i would like to detect which valve of my home garden irrigation system is open and for how long. Eventually I will put a water meter on the line where I can remotely measure the number of gallons that flow to the valve manifold and if I know which valve is open, I can get an accurate idea of how many gallons pass though each valve. The valves are Rain Bird and their solenoid run on 24vac. I have been programming python on the Raspberry Pi for a couple of years now but circuit design is new to me.

I have designed a small circuit that will convert the 24vac to ~3.3 dc with acceptable ripple. By acceptable ripple I mean that it never goes low enough to trigger an edge detect on a Raspberry Pi 3b+ gpio pin. Here is the circuit:
The attachment CaptureCIS.PNG is no longer available
I can run SPICE on this in OrCAD Capture CIS Lite and I get the following output:
CaptureCIS.PNG
CaptureCIS.PNG (17.99 KiB) Viewed 5561 times
Now when I run this with my breadboard, I get a different waveform but I'll get to that later.
For my test, I have a Raspberry Pi 3b+. I have a Adafruit MCP3008 8-Channel 10-Bit ADC With SPI Interface for Raspberry Pi that I will use to read the voltage on GPIO pin 25 Pin 25 is initialized as a input GPIO with both rising and falling edge detects. I use GPIO 23 as an output to turn a relay on to supply 24vdc to my rectified circuit.

I run the following code:

Code: Select all

#!/usr/bin/env python2.7
## on esp
import RPi.GPIO as GPIO
import time
from datetime import datetime
from datetime import timedelta
from time import sleep     # this lets us have a time delay (see line 12)

state = 0
lastrise = None
lastdrop = None
starttime = 0

AO_pin = 0 #flame sensor AO connected to ADC chanannel 0
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler
SPICLK = 11
SPIMISO = 9
SPIMOSI = 10
SPICS = 8
RELAY = 23
OPTO1 = 25

linerf = []

def my_callback(channel):
    global linerf
    global starttime
    global lastrise
    global lastdrop
    global state
    global AO_pin
    global SPICLK
    global SPIMISO
    global SPIMOSI
    global SPICS

    # time.sleep(0.0001)
    nowtim = datetime.utcnow()
    gpiolevel = GPIO.input(OPTO1)
    # ad_value = readadc(AO_pin, SPICLK, SPIMOSI, SPIMISO, SPICS)
    # voltage = ad_value*(3.3 / 1024) # *5 no voltage divider here
    voltage = 1.11
    measuretime = datetime.utcnow() - nowtim
    timediff = None

    if gpiolevel:     # if port 25 == 1
        # if lastrise:
        #     timediff = nowtim - lastrise
        # lastrise = nowtim
        # if (timediff and
        #     timediff.days == 0 and
        #     timediff.seconds == 0 and
        #     timediff.microseconds < 1000):
        #     return
        linerf.append([ nowtim, voltage, state + .2, 1, measuretime ])
        # lastdrop = None
    else:                  # if port 25 != 1
        # if lastdrop:
        #     timediff = nowtim - lastdrop
        # lastdrop = nowtim
        # if (timediff and
        #     timediff.days == 0 and
        #     timediff.seconds == 0 and
        #     timediff.microseconds < 1000):
        #     return
        linerf.append([ nowtim, voltage, state + .2, 0, measuretime])
        # lastrise = None
    return

#port init
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    # set up the SPI interface pins
    GPIO.setup(SPIMOSI, GPIO.OUT)
    GPIO.setup(SPIMISO, GPIO.IN)
    GPIO.setup(SPICLK, GPIO.OUT)
    GPIO.setup(SPICS, GPIO.OUT)

    GPIO.setup(OPTO1, GPIO.IN)    # set GPIO25 as input (button)
    GPIO.setup(RELAY, GPIO.OUT)    # set GPIO24 as output
    GPIO.output(RELAY, False)

    # when a changing edge is detected on OPTO1 port, regardless of whatever
    # else is happening in the program, the function my_callback will be run
    GPIO.add_event_detect(OPTO1, GPIO.BOTH, callback=my_callback)

    pass

#read SPI data from MCP3008(or MCP3204) chip,8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if ((adcnum > 7) or (adcnum < 0)):
        return -1
    GPIO.output(cspin, True)

    GPIO.output(clockpin, False)  # start clock low
    GPIO.output(cspin, False)     # bring CS low

    commandout = adcnum
    commandout |= 0x18  # start bit + single-ended bit
    commandout <<= 3    # we only need to send 5 bits here
    for i in range(5):
        if (commandout & 0x80):
            GPIO.output(mosipin, True)
        else:
            GPIO.output(mosipin, False)
        commandout <<= 1
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)

    adcout = 0
    # read in one empty bit, one null bit and 10 ADC bits
    for i in range(12):
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)
        adcout <<= 1
        if (GPIO.input(misopin)):
            adcout |= 0x1

    GPIO.output(cspin, True)

    adcout >>= 1       # first bit is 'null' so drop it
    return adcout

def sortbytimekey(x):
    global starttime
    mstime = x[0] - starttime
    key = mstime.seconds + mstime.microseconds / 1000000.0
    return key

def main():
    init()
    global linerf
    global starttime
    time.sleep(2)
    voltimelist = []
    sleeptime = 0.00002  # .02 ms
    global state # 0 = not started, 1 = on, 2 = off, 3= zero reached
    avgvolt = 0
    avgvoltcnt = 0
    maxvolt = 0
    minvolt = 99999
    testtime = 2  #  seconds
    voltage = 0   # initial voltage value
    print ("will detect voltage. ")
    starttime = datetime.utcnow()
    measuretime =  datetime.utcnow() - starttime
    voltimelist.append([datetime.utcnow(), 0.0, state, GPIO.input(OPTO1), measuretime])
    GPIO.output(RELAY, True)
    state = 1
    print("ON, state = " + str(state))
    timercount = int(testtime / sleeptime) + 1
    while timercount >= 0 or state < 3:
        timercount -= 1
        if timercount == 0:
            GPIO.output(RELAY, False)
            state = 2
            print("OFF, state = " + str(state))
        time.sleep(sleeptime)
        readtime = datetime.utcnow()
        ad_value = 0 + readadc(AO_pin, SPICLK, SPIMOSI, SPIMISO, SPICS)
        voltage = ad_value*(3.3 / 1024) # *5 no voltage divider here
        thistime = datetime.utcnow()
        measuretime = thistime - readtime
        if state == 2 and voltage <= 0.3:
            print ("almost zero detected = " + str("%.4f"%voltage) + ", at time " + thistime.strftime("%H:%M:%S.%f"))
            state = 3
        voltimelist.append([thistime, voltage, state, GPIO.input(OPTO1), measuretime])
        if voltage > 0.5:
            avgvolt = ((avgvoltcnt * avgvolt) + voltage) / (avgvoltcnt + 1)
            avgvoltcnt += 1
            if voltage > maxvolt:
                maxvolt = voltage
            if voltage < minvolt:
                minvolt = voltage
        pass

    print ("Time's up. Finished! Average volts=" + str("%.4f"%avgvolt) +
          ", Max volts = " + str("%.4f"%maxvolt) +
          ", Min volts = " + str("%.4f"%minvolt) +
          " , Count = " + str(avgvoltcnt) + ", state = " + str(state))
    print "voltimelist len =", len(voltimelist)
    file = open("voltgraph.csv", "w")
    voltimelist = voltimelist + linerf
    starttime = voltimelist[0][0]
    voltimelist.sort(key = sortbytimekey)
    for voltim, volts, state, pin, measuretime in voltimelist:
        mstime = voltim - starttime
        file.write( "%d"%mstime.seconds + ".%06d"%mstime.microseconds +
                    ", " + str(state) +
                    ", " + str("%.4f"%volts) +
                    ", " + str(pin) +
                    ",%d"%measuretime.seconds + ".%06d"%measuretime.microseconds +
                    ", " + voltim.strftime("%H:%M:%S.%f") +
                    "\n"
                  )
    file.close()


if __name__ =='__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass

GPIO.cleanup()
What this code does is the following:
  • 1. Initialize the GPIO pins and set up GPIO.BOTH edge detection on pin 25 to call my callback routine.
  • 2. I close the relay, energizing my rectifier and supplying rippling ~ 3.0 v to the GPIO Pin 25. However, the ripple does not go low enough to trigger a falling edge
  • 3. When the callback occurs, I note the time and read the GPIO pin 25. I add these values to a python list where I am logging events.
  • 4. The relay is closed for about 2 seconds. The python code loops with a .02 ms wait between loops. At each iteration of the loop, the voltage is read, the GPIO pin is read and the time is noted. These items are added to a python list where I am logging events.
  • 5. When the 2 seconds are up the relay is opened but the looping continues until the voltage on pin 25 drops to less that 0.3 volts
  • 6. Once the 0.3 voltage is reached, the pyhon event list is written to a file where I can us MS Excel to graph it.
I observe the following:
  • 1. The first edge is detected at about 1.5 v. However, when I read the GPIO pin, it still reads ON.
  • 2. I continue getting edge detections about every 0.4 ms and I can see the voltage dropping but the GPIO pin still reads ON until the voltage reaches about 1.2v.
  • 3. At about 1.2v I start reading the GPIO pin off but am still getting edge detections until about 0.7 v.
This repeated firing of the callback is mentioned in earlier postings. The documentation mentions that the way to know if you have a rising or falling edge is to check the GPIO pin value. The problem is that during the first few firings of the callback, the GPIO pin value is not consistent with the edge detection. The voltage range for reading the pin does not match the voltage at which the edge event occurs. In fact, the callback happens early and this is why the suggestion of some posting to delay the read of the GPIO pin for a few milliseconds works. I'm uncomfortable with sleeping in a callback.

My next experiment will be to try a Schmitt Trigger on the output of my rectifier. My thought is that this will make the rise and fall steep enough to avoid this issue.

I'd like any suggestion anyone might have about how I can make the voltage fall steeper. I've tried different capacitors and resistors but can't seem to get the results I need.

- Thanks
PS. I have other diagrams and graphs but can't figure out how to attach them. If anyone is interested, I'll attach them to a different response.

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 12:06 am

Hallo,

First of all I had some similar problems like you have. I found out that the default RPi.gpio gives me some problems. Because of that I used a other one pigpio.

For my project I want to measure the time that a device is on. I found out that by using a optocouple works better that an power supply with a zener. I also added a RC filter to it. For now I doesn't have access to the schematic.

The nice thing about the optocouple is that the noise on the 24vac line is galvanic isolated from your pi. And they are practical on or off.

Btw. Sorry for the "incomplete" answer, I can provide later some more information. But I don't have the time now ;)

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 6:45 am

petermeigs wrote:
Sun Aug 05, 2018 12:47 am
The valves are Rain Bird and their solenoid run on 24vac.
I have designed a small circuit that will convert the 24vac to ~3.3 dc with acceptable ripple. By acceptable ripple I mean that it never goes low enough to trigger an edge detect on a Raspberry Pi 3b+ gpio pin.

Raspberry Pi 3b+. MCP3008 8-Channel 10-Bit ADC With SPI Interface for Raspberry Pi that I will use to read the voltage on GPIO pin 25 Pin 25 is initialized as a input GPIO with both rising and falling edge detects. I use GPIO 23 as an output to turn a relay on to supply 24vdc to my rectified circuit.

I run the following code ...
This repeated firing of the callback is mentioned in earlier postings.

My next experiment will be to try a Schmitt Trigger on the output of my rectifier. My thought is that this will make the rise and fall steep enough to avoid this issue.

I'd like any suggestion anyone might have about how I can make the voltage fall steeper. I've tried different capacitors and resistors but can't seem to get the results I need.

Hello. I am an electronic hobbyist. My current project is also in home automation. I have about 2 years hobbyist programming experience in Rpi3 python 3.5. I once tried basic Rpi GPIO and MCP23017 interrupt experiments successfully and more or less understand the interrupt operation.

I am using Rpi3+, with linux stretch 2018apr. I have some basic experience in using ADC MCP3208, and also Schmitt trigger logic gate HC14.

I know about rectifying, capacitor and resistor circuits, so I may try to help or make some suggestions.

I am impressed by the very detailed description of your problem. But it is a bit too long, so I only skimmed it quickly. I think the problem is likely in your design of the capacitor resistor circuit. I need to think about it for a while and see if I can make any suggestion.

I attach an old schematic of my 24VAC relay circuit. This is to test if I can upload a big image file successfully and you can read my image OK.

I will try to post again perhaps sometime today or tomorrow.
Attachments
DjEzUpO[1].jpg
DjEzUpO[1].jpg (95.72 KiB) Viewed 5529 times
I am an electronics and smart home hobbyist.

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 6:58 am

Hi,
Thanks for the comment about pigpio. I definitely think there is something wrong with the way GPIO works. The basic issue everyone I read seems to be dealing with is that when you use GPIO.both edge detection you are supposed to be able to determine if it is a rising edge or a falling edge. Unfortunately, the voltage at which a falling edge is detected is still high enough for the GPIO.input(pin) to return a 1. Interrupts fire until the voltage gets low enough and then they stop. For a while during these successive interrupts, GPIO.input(pin) returns 1 and then after a while it returns 0.

In my setup, I can measure the voltage and accurately relate the time I get the voltage to the time I get the interrupts. I can clearly see that I am getting a falling edge detected for about ~1ms before the GPIO.input(pin) returns the right value. This means to me that the edge detect voltages are not consistent with the voltages at which the GPIO.input(pin) returns its value.

If the edge detection event did not occur until the GPIO.input(pin) was accurate for the type of event, it would help make code written for this much more reliable. A disadvantage of this is that the notification would be about ~1ms later than when some edge activity started.

Another possible solution would be for the edge event code to return and indication of a falling or rising edge so that GPIO.input(pin) is not even needed.

I'll made some additional tests to see how events other than GPIO.BOTH work. Then, I'll take a look at pigpio and see how that behaves. Here is the graph I'm referring to.
The red line shows the voltage measurements I do every few 10's of a millisecond.
The blue line jumps up when an interrupt happens. Then I can interpolate the voltage at that point. I don't measure the voltage inside the interrupt because I'm concerned the read-adc code is not threadsafe.
The green line shows the result of the GPIO.input().
edgevoltagegraph.PNG
edgevoltagegraph.PNG (48.61 KiB) Viewed 5525 times

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:05 am

Hi, I just read another reply. I do need all the help I can get with the capacitor circuit. I have tried various capacitor values and resistor values and the ones I show seem to work the best so far. I think I should be able to get the shutdown falling edge to be steeper. If I could do that, then I think the other issues would go away.

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:08 am

One other comment I forgot to make: I have 16 valves I need to keep track of. This means the cost of anything I build is at least 16 times the cost of the components to build 1. So far, I have been able to keep the cost of the parts pretty low.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:11 am

tlfong01 wrote:
Mon Aug 06, 2018 6:45 am
I know about rectifying, capacitor and resistor circuits, so I may try to help or make some suggestions.

I need to refresh my memory on RC circuits before I can suggest anything. :lol:

My posts on home automation are very scattered. Below are some relevant ones you might interested to read. I am playing with a real clock timer DS3231. My plan is to use this clock to time my switching on off of heaters, fans, and pump. But I am not sure if I can do it.

(opto isolated relay switching) RE: RELAY MODULE KY-019 5V Post by tlfong01 » 2018-Jun-22 Fri 3:45 pm (Optocoupler to avoid back EMF / EMI)
viewtopic.php?f=37&t=77158&start=75#p1331550

(Schemitt Trigger) RE: RELAY MODULE KY-019 5V Post by tlfong01 » 2018-Jun-23 Sat 10:49 pm
viewtopic.php?f=37&t=77158&start=100#p1332019

(Real time clock) RE: RELAY MODULE KY-019 5V Post by tlfong01 » 2018-Jun-27 Wed 10:37 am
viewtopic.php?f=37&t=77158&start=100#p1333433

(Reducing EMI) RE: RELAY MODULE KY-019 5V Postby tlfong01 » 2018-Jul-13 Fri 7:53 pm
viewtopic.php?f=37&t=77158&start=150#p1340412
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:17 am

petermeigs wrote:
Sun Aug 05, 2018 12:47 am
I have other diagrams and graphs but can't figure out how to attach them. If anyone is interested, I'll attach them to a different response.

I am using the free imgur.com. You might like to try it.

I only tried imgur when I joined Rpi Forum two months ago. I still have difficulty uploading big images.

My imgur images
https://tlfong01.imgur.com/all
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:25 am

petermeigs wrote:
Mon Aug 06, 2018 7:08 am
One other comment I forgot to make: I have 16 valves I need to keep track of. This means the cost of anything I build is at least 16 times the cost of the components to build 1. So far, I have been able to keep the cost of the parts pretty low.
Ah, me too. I like to play with cheap things, as cheap as possible, but not cheaper. I am dreaming of controlling 64 relays, more than Rpi can give me. So I am using MCP23017 x 4 or more, to give me 64 GPIOs.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:32 am

petermeigs wrote:
Mon Aug 06, 2018 7:05 am
Hi, I just read another reply. I do need all the help I can get with the capacitor circuit. I have tried various capacitor values and resistor values and the ones I show seem to work the best so far. I think I should be able to get the shutdown falling edge to be steeper. If I could do that, then I think the other issues would go away.

I am a little bit confused. Did you take your voltage measurements using a scope? If yes, then you should know more electronic circuits than me :lol: . My electronic circuits knowledge are rusty. So I need to do some polishing. Below is the tutorial site I have been visiting more than 20 times in the past 2 months.

Electronics-Tutorials
https://www.electronics-tutorials.ws/
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 7:36 am

petermeigs wrote:
Sun Aug 05, 2018 12:47 am
I have been working on a project where i would like to detect which valve of my home garden irrigation system is open and for how long.

Short question - are the values open or close by themselves? If not, and Rpi do the switching, then of course Rpi can do the timing calculations.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 8:23 am

petermeigs wrote:
Mon Aug 06, 2018 7:05 am
I do need all the help I can get with the capacitor circuit. I have tried various capacitor values and resistor values and the ones I show seem to work the best so far.

I think I should be able to get the shutdown falling edge to be steeper. If I could do that, then I think the other issues would go away.

I am not too sure of your capacitor-resistor, or the Schmitt is the optimum way to go. What you are doing is a hardware method to condition the falling edge. You have this problem because Rpi.GPIO can only do falling or rising trigger, but not level trigger.

I vaguely remember that Arduino can do falling, rising, or level trigger. If you can do level trigger, then you don't need to take care of edge conditioning or switch bouncing.

I rember gpiozero has something like:

def _call_when_changed(self, channel, value):
super(RPIOPin, self)._call_when_changed()

not sure if it is level interrupt.

https://gpiozero.readthedocs.io/en/stab ... interrupt

I am playing with MCP23017, which do interrupt of output change from previous value, or from default value. I found them easy to do. But I am not suggesting you to use MCP23017, because it has a rather steep learning curve.

Anyway, I just want to tell you that I have forgotten the edge trigger thing and would not be able to read your program. My only help is perhaps on how to do the RC edge conditioning better.

BTW, I do remember one thing about edge triggering. When you detect an edge trigger, the call back routine should be short and quick to disable interrupt, to prevent further interrupts (due to bouncing etc). After disabling further interrupts, then you have plenty of time (not using the call back routine) to look at things and do what you want to do. But I am not that sure if I remember interrupt things correctly. :lol:
Attachments
RrUVQi7[1].jpg
RrUVQi7[1].jpg (101.14 KiB) Viewed 5466 times
Last edited by tlfong01 on Mon Aug 06, 2018 9:10 am, edited 3 times in total.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 8:34 am

petermeigs wrote:
Mon Aug 06, 2018 7:05 am
I do need all the help I can get with the capacitor circuit. I have tried various capacitor values and resistor values and the ones I show seem to work the best so far.

I think I should be able to get the shutdown falling edge to be steeper. If I could do that, then I think the other issues would go away.

My first thought is that if you use Schmitt trigger, then you don't need any RC, and of course not the zener, though I do find the use of a zener innovative :lol: . You might like to suggest a Schmitt trigger circuit and I can make some comments or give counter suggestions.

You might find my following 2 old posts useful for general reference.

(Schmitt Trigger HC14 1/2) RE: RELAY MODULE KY-019 5V Postby tlfong01 » 2018-Jun-23 Sat 3:10 pm
viewtopic.php?f=37&t=77158&start=75#p1331903

(Schmitt Trigger HC14 2/2) RE: RELAY MODULE KY-019 5V Postby tlfong01 » 2018-Jun-23 Sat 10:49 pm
viewtopic.php?f=37&t=77158&start=100#p1332019

Good luck and see you tomorrow.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 10:48 am

Brandon92 wrote:
Mon Aug 06, 2018 12:06 am
First of all I had some similar problems like you have. I found out that the default RPi.gpio gives me some problems. Because of that I used a other one pigpio.

using a optocouple works better that an power supply with a zener. I also added a RC filter to it. For now I doesn't have access to the schematic.

Yes, using an optocoupler is better than a zener. It works something like this.

If the AC24V converted DC voltage is high low enough, it drives sinks current through a biasing and current limiting resistor, from the LED on the left, which saturates the diode on the other side, which in turn saturates an NPN transistor, thus turning its CE output from non saturating high to saturating low.

A popular optocoupler is EL817C, and you can find reference circuits in 5V relay schematics.
Attachments
3o4iXX0[1].jpg
3o4iXX0[1].jpg (55.99 KiB) Viewed 5446 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 981
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 12:40 pm

tlfong01 wrote:
Mon Aug 06, 2018 10:48 am
If the AC24V converted DC voltage is high low enough, it drives sinks current through a biasing and current limiting resistor, from the LED on the left, which saturates the diode on the other side, which in turn saturates an NPN transistor, thus turning its CE output from non saturating high to saturating low.

A popular optocoupler is EL817C, and you can find reference circuits in 5V relay schematics.

And here is a quick and dirty draft. I have almost zero experience in designing AC circuits. So there is no guarantee that something won't explode!
Attachments
VCsxo8H[1].jpg
VCsxo8H[1].jpg (36.51 KiB) Viewed 5431 times
I am an electronics and smart home hobbyist.

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 2:15 pm

Hello,

First I thing its nice to give a little bit information about myself. As long as I remember I am working on electronics. And currently i'm a student, but I can call myself almost a engineer :) And I just started with the raspberry pi and python

So, lets me explain something what is "discovered" and later something about safety.

RPi.gpio vs pigpio
I used this schematic for this. Yes, R2 is quid big but for my purposes its just fine:
Optocouple input.png
Optocouple input.png (5.47 KiB) Viewed 5418 times
Long story short, I found out that this will not always trigger / handle the pin change correctly.' Or it will give me a error. When there are to much changes onto that pin the program can't handle that as wel.
This let me to a oter library; pigpio. And its working really well for me. Every pulse that I need is registered correctly. And this is part of the code that I used, and I know it's not the best one. But i'ts working for almost a week without a problem :):

Code: Select all

#fuction to check when the "trommelfilter" is active. And check how long it is on
def TF_active(gpio, level, tick):
	if level == 0:
		#load the global variables
		global timestamp
		global datestamp
		global timer_TF_active
		#Get the current date and time
		timestamp = strftime("%H:%M:%S")
		datestamp = strftime("%d-%m-%Y")
		#Get the time when the "trommelfilter" is active
		timer_TF_active = time()
		#For debug purposes
		print("Preset at:",timer_TF_active)
		logger.info("Active")
	else:
		#load the global variables
		global timer_TF_inactive
		global TF_was_active
		#Get the time when the "trommelfilter" is inactive
		timer_TF_inactive = time()
		#Mark a flag for the main program
		TF_was_active = 1
		#For debug purposes
		print("Release at:", timer_TF_inactive)
		logger.info("Deactivate")
		#change the pin interrupt to a falling edge \_
	return

#Start the detection wiht a falling edge		
cb1 = gpio.callback(TrommelFilter_io, pigpio.EITHER_EDGE, TF_active)
Safety
The reason why, I think, you should use a optocouple for detecting if a device or whatever is on. Is mainly for safety. When you have around / in your house a couple devices you want to monitor if it is on. You use they power supply to indicate it. So, far noting is wrong. But those devices are (possibly) physical connected to a other circuits braker with protection (I forget how it's called in other countries).
Let's me explain some scenarios with this information:

1, When you connect every ground to you pi. You also connect (possibly) different groups in your home to each other. As long as the isolation in the power supply is good. But if that's not the case, all the devices will be connected to your means power. And this is very dangerous! Because this can kill you. And it's possible that you protection doesn't kill the power. And it's then also possible that you connect different power groups together.

2, if some device produce (a lot of) noise. In his power rails. This will be transmitted into the rest of the devices that are connected to those same ground. And it can crash some devices if they don't have the right protection. And they are not design for those kind of interference.

3, with your current design, if there is a voltage spike. It can generate a voltage spike that can kill your pi.

This brings me to the conclusion that is better and saver

Zener diode
Remember that a zener diode have also a tolerance. So, the output voltage of that circuit could be higher than the 3.3V powersupply of you Pi. And this can give you some problems at the end. For example, damage the input. For example: a 3.3V zener can give a output of 3.465V

How to use a optocouple
First the schematic from tlfong01. But I thing it will not work possible as you will expect it. If the C is to small. You will get every zero crossing of the input sine. And that is not desirable in this case. An the extra transistor is also not needed. And you need also a extra powersupply for the schmit inverter, because you can't you the 5V from you pi.

I think the easiest why is one of those, (note, this is whitout protection!). When the AC is present on the input. The voltage of the GPIO.pin is 0V (active low).
Optocouple input v2.png
Optocouple input v2.png (12.85 KiB) Viewed 5418 times
BTW: This is also a interesting post about the GPIO inputs

If there is any question about this, I would like to hear it

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 5:29 pm

EDIT (sorry for the double post, but my images are disappear if I edit the post above)

To give a little more information about how to use the optocouplers. Some more interesting links:
Application note optocoupler
Datasheet MIC400
Application note MIC400
Datasheet HCPL3700
Application Notes - A Guide to Designing With Optocouplers

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 8:44 pm

wow! guys,
A lot of great information! I'll have to spend some time to digest it all. A little info about myself: I am a recently retired software engineer but I got into the raspberry pi on a suggestion from a co-worker. When I started my studies, I was interested in electrical engineering but got distracted by software. I've spent many years programming in c and java but in the last few years of working, in python and Ruby. Now with more time, I've gotten interested in home automation and IOT. Recently, my interest in circuit design got restarted but I'm at baby steps here.

I did some experiments with opto couplers (I got this one from aliexpress: 24V To 3.3V 8 Channel Optocoupler Isolation Module Level Voltage Converter PNP Output PLC Signal DST-1R8P-P by AL-ZARD) and had a good test with it. It did make my circuit seem complicated so I started trying to do a much simpler circuit. If anything I do is innovative, it's because I have so little experience and knowledge about this I'm not constrained by the knowing much.

Even with this optocoupler, I was getting multiple firings of the edge events. Since this is a DC-DC optocoupler, the AC LED optocoupler is an interesting alternative. I'll see if I can get some to test.

BTW, thanks for reminding me why was looking at optocouples to being with: I don't want to fry my RPI's

Also, I like the idea of level detection vs edge detection. Frankly, I don't care about the level, I just want to know when the valve is on. So if arduino can make this work, perhaps that's the way to go. I have even been thinking about ESP8266 as a possibility.

As an aside, I am using a Rachio 16 channel controller for my valve control. It's very nice and it turns out the water district for where I live provides a 100% rebate for using that. You can't argue with free. Anyway, my idea was to add a connection in parallel with the valve solenoids to detect when a particular zone goes on. I kind of got started with OpenSprinkler (see https://rayshobby.net/wordpress/opensprinkler/). Ray also did OpenGarage (https://rayshobby.net/wordpress/introducing-opengarage/)

Anyway, thanks again for all your comments. I'm off to catch up with all the new info.

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 9:20 pm

petermeigs wrote:
Mon Aug 06, 2018 8:44 pm
Even with this optocoupler, I was getting multiple firings of the edge events. Since this is a DC-DC optocoupler, the AC LED optocoupler is an interesting alternative. I'll see if I can get some to test.

BTW, thanks for reminding me why was looking at optocouples to being with: I don't want to fry my RPI's

Also, I like the idea of level detection vs edge detection. Frankly, I don't care about the level, I just want to know when the valve is on. So if arduino can make this work, perhaps that's the way to go. I have even been thinking about ESP8266 as a possibility.
Well, it's not because it a pi. It's more how you present the signals to the the input of you device. For example you simulation (its not 100% the same, buy you get the point);
3.3V zener input.png
3.3V zener input.png (45.57 KiB) Viewed 5361 times
Here you can see that the voltage is dropping. And this could trigger your pi input.

If you change the capacitor to a bigger value the problem is over:
3.3V zener input v2.png
3.3V zener input v2.png (42.64 KiB) Viewed 5361 times
But: this is not the solution btw. For that read my other post :)

PhilBr
Posts: 54
Joined: Tue Oct 31, 2017 5:28 pm

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 9:34 pm

Your plots of the voltages and book states are interesting. They show that the edge detection and pin reading occur at different thresholds.
Could you
A. Put a short sleep at the start of your callback routine. OR
B. Add a bouncetime parameter see
https://raspi.tv/2013/how-to-use-interr ... pio-part-2
Hth
Phil

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 10:22 pm

The MID400 looks like just the product but it needs 90vac RMS to turn on so I'm out of luck here with 24vac. The HCPL3700 looks like it is good from 5V to 240V and the level is controlled by a single resistor. That is in range so it merits more study. Thanks for this suggestion.

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 10:39 pm

No problem. But those devices are not the cheapest if you need a lot of them. And those were more as an example. And for my project I want to measure 230vac.
But you could also use a cheaper one, if the isolation barrier is strong enough.

Were did you read the 90vac?

I have also a little question for you, have you a question about what I wrote (my longest poste)?

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 10:41 pm

PhilBr wrote:
Mon Aug 06, 2018 9:34 pm
A. Put a short sleep at the start of your callback routine. OR
B. Add a bouncetime parameter
Hi, Thanks for the comments. They have all been extremely helpful and I am getting insgiht I would never have gotten on my own.

Anyway, back on topic:
I get a clean output in the steady state and at startup with 200nF The problem comes in when the power to the simulated solenoid is shut off. That's when I get all the edge detects. If I bump up the capacitance, (I've tried this) it actually makes things worse but I can't explain why yet. I realize that there are many comments talking about putting a time delay in the callback routine but sleeping in an interrupt routine seems like cheating somehow. I think it would help if someone had a good explanation as why this would not be harmful in some sense. I've had no luck with bounce time settings. The root of all this struggle for me is that when I get the callback, the GPIO.input is not right yet.

In the circuit I showed at the beginning, there was a switch that would open after 20ms. This was to show the interesting part, i.e, when the ac power was removed from the circuit.

Brandon92
Posts: 616
Joined: Wed Jul 25, 2018 9:29 pm
Location: Netherlands

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 10:51 pm

Wait a moment. I you say something very important right now. Do you have a flyback diode across the inductor of your solenoid? If this is not the case it can generate a large voltage swing.

If you want I can give more explanation about this. And what for kind of valves / solenoid are you using.

petermeigs
Posts: 79
Joined: Thu Mar 23, 2017 1:34 pm
Location: Los Altos, California

Re: GPIO.input voltage levels vs edge detection

Mon Aug 06, 2018 11:02 pm

Brandon92 wrote:
Mon Aug 06, 2018 10:39 pm
But those devices are not the cheapest if you need a lot of them.
But you could also use a cheaper one, if the isolation barrier is strong enough.
Were did you read the 90vac?
I have also a little question for you, have you a question about what I wrote (my longest post)?
I like the HCPL3700 because it comes in a DIP package and I can deal with soldering that. Also, it saves me from having to add bridge rectifiers so the circuit is tidier.
With regard to cheaper alternatives, is there an easy way to find these things? I've been overwhelmed with choices.
I read about the 90vac in the Datasheet you kindly linked me to.
Not questions yet on the long post but I'll be doing some code changes to try out the other gpio library.

I just saw your next post and thanks for the comment about the flyback diode for the solenoid. Here is a link to the solenoid for a Rainbird valve:
https://www.amazon.com/gp/product/B000P ... UTF8&psc=1

At first, I did not think I needed one because of my relay but since I will be in parallel with the Rachio controller circuit (and the relay is just for simulation), I think will definitely need some kind of protection against the relay coil.

Return to “Python”