PiGraham
Posts: 4862
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 9:51 am

techpaul wrote:I would agree that in general multiple systems and multiple UPS for real failsafe.

In this case as this is one HVAC system, which will have inbuilt modes that put the unit safe when power fails (no doubt always off), powering one or more Pis from the same mains feed as the HVAC is adequate as neither can do anything to the HVAC during power fail. Running the Pi(s) from completely
separate mains feeds would be pointless and introduce more points of failure.

Adding a UPS to report main failure and time would be useful but it depends if you are trying to make a complete failsafe(r) system or just certain aspects.
A UPS for the Pi is only useful for reporting power failure, which may be important for properties left unattended during cold winters. Off may be a critical failure state that needs attention ASAP.

The application is a thermostat so I assume the system can be remotely switched between modes to turn heating or cooling on or off to keep the property temperature within limits.

Here's an idea for what could be a simpler "fail-safe":
Connect a standard thermostats in series or parallel with the Pi controlled relays. If a thermostat is set to the max and min limits the Pi is restricted to control within that range. The HVAC may have such a device already.

Wire it so that a dumb thermostat <TH_MIN heat control is in parallel with the Pi controlled relay so that when the house starts to freeze and a dead Pi fails to turn on the heating the dumb thermostat does the job.

Connect a >TH_MAX N/C thermostat O/P in series with the Pi heating relay so that the Pi cannot maintain heating-on above the dumb thermostat limit.
You could use something like these:
http://www.screwfix.com/p/siemens-raa20 ... stat/81184
You may need a pair to limit heating and a pair to limit cooling

Heating:
Force on T < TH_MIN (parallel N/O contact)
Force off T > TH_MAX (series N/C contact)
Cooling:
Force on T > TC_MAX (parallel N/O contact)
Force off T < TC_MIN (series N/C contact)

So, if the Pi goes crazy it can't heat the house beyond TH_MAX or cool it below TC_MIN.
If the Pi fails to act the dumb thermostats will heat the house to keep above TH_MIN and not go above TH_MAX.

In between these limits you have programmable control by the Pi.

Any single thermostat can fail without crisis. If the TH_MIN fails to short, turning on the heating when it shouldn't, the Pi can report the temperature is above set-point and the TH_MAX thermostat will cut heating before damage occurs. Similarly for cooling.

Is it worth £40 for some basic thermostats? Will the HVAC provide such a function anyway?

It's interesting to think about.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 12:45 pm

Good ideas and inputs Graham, thanks.

I did not really want to use this post for a general discussion on thermostat designs, I wanted to do that separately in a dedicated one. I will probably share my experiences in pieces later on, when I have my design fully working for a longer period. Stay tuned, but don't hold your breath.

However, since you brought it up, I need to go in a bit more detail to explain my particular situation, which is what I wanted to avoid for this post, but here we go.

The picture shows my web-based thermostat system in operation.
I pick-up the required connections (W, Y, R, C,..) from the "real" thermostat, it's connected in parallel.
However, this particular type gets its power from the R terminal and either the W or Y wire, and to do so, requires the manual switching from cooling to heating. I connected a spare wire in the cable to the C (common) of the HVAC system so through C and R, I have 24VAC available to power the Pi. The two are joined by the hip for power.

Here's the rub with the thermostat. When the Pi is not activating the HVAC relais, the thermostat is in operation and shows the temperature as you can see on the picture.
When the Pi switches the HVAC relais however, the thermostat becomes powerless for that period, as a function of it's design.

I need to figure out how to design a circuit to solve that, such that both thermostats are truly in parallel, and doing partially what you suggested. Partially, because it can only take one temperature setting (either for heating or for cooling). Luckily the house is in a very warm climate, winters are not the problem. Besides, that's when we are there. If all else fails, there is always a nice neighbor available. So these are some of the trade-offs I have made.

As you can imagine, my Pi program automatically switches from heating to cooling.

I'm bound to get that question about that funny wire... Through trial and error, and loosing some hair, I have found that the DS18B20 temperature sensor has to be a certain "length of wire" away from any heat source which is why I put it directly into the airflow. (The major inlet vent is almost directly overhead.)
I really can't explain it, but it seems that there is a heat transfer through the connection wires to the sensor. Believe me, I tried many options. It will not work well inside the box or even close to it, period. Does not look pretty, but it works really well is accurate and is very responsive.

So, I hope this explains a few things to the folks following this post.

If you all don't mind, I prefer to get back to the topic of this post. How to create a better and relatively simple failsafe(r) operation from the Pi through the use of a GPIO channel. I'm still waiting for some parts such that I can build and test the latest version of the circuit. It covers a few aspects of the errors that could possibly happen, and I'd like to expand on that and add support for a failing relays operation. Maybe more. In the meantime, if somebody else comes up with another idea, I'm willing to give that a try too.

I would really like to secure that hug from Joan!
Attachments
Thermostat.jpg
Thermostat.jpg (63.36 KiB) Viewed 6429 times

PiGraham
Posts: 4862
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 1:16 pm

OK, just a couple of comments on "Failsafe use of GPIO pin".
More or less in-line with your idea:

1. Monitor the state of whatever the output is supposed to switch via a GPIO input and test in your application to check that the device is on when it's supposed to be and off otherwise.

2. You can use a re-triggerable monostable that requires a change of state of an input to re-trigger it. Edge triggering is important. You can keep the output of the monostable on by pulsing the GPIO output. If the pulsing stops the monostable times out and the output goes off.

3. Drive the pulsing in your application's main control loop so that if the monitoring/control function fails the output will turn off. Don't use hardware PWM of driver-based pulsing since that will most likely keep running if your critical code fails.Protect the critical code.

Make sure that if the GPIO fails stuck high or low the monostable is not re-triggered and turns off.

Take care over building the signal watchdog. It's an extra single point of failure so it has to be ultra-reliable.

The 555 (I haven't used one of these for decades. Feeling old :cry: )
may not be well suited because of how it triggers: -

wikipedia wrote:The pulse begins when the 555 timer receives a signal at the trigger input that falls below a third of the voltage supply.
...
While using the timer IC in monostable mode, the main disadvantage is that the time span between any two triggering pulses must be greater than the RC time constant.
It is level triggered and won't re-trigger while active.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 4:15 pm

PiGraham wrote:.....
3. Drive the pulsing in your application's main control loop so that if the monitoring/control function fails the output will turn off. Don't use hardware PWM of driver-based pulsing since that will most likely keep running if your critical code fails.Protect the critical code.

Make sure that if the GPIO fails stuck high or low the monostable is not re-triggered and turns off.

Take care over building the signal watchdog. It's an extra single point of failure so it has to be ultra-reliable.

The 555 (I haven't used one of these for decades. Feeling old :cry: )
may not be well suited because of how it triggers: -

wikipedia wrote:The pulse begins when the 555 timer receives a signal at the trigger input that falls below a third of the voltage supply.
...
While using the timer IC in monostable mode, the main disadvantage is that the time span between any two triggering pulses must be greater than the RC time constant.
It is level triggered and won't re-trigger while active.
Actually be dubious about wikipedia look at the datasheet and the modified circuit, the level at which it triggers is 1/3 Vcc and CANNOT be retriggered within its timeout period (and a bit). Look at modification input goes low to trigger, and the charge cap is shorted when the input goes HIGH.

So GPIO stuck low will trigger once and the trigger circuit wont accept a trigger again, stuck high and never gets a trigger (times out). from datasheet (National Semi LM555) front page

"The circuit may be triggered and reset on falling waveforms"

Yes the 555 is peculair but the trigger has weird characteristics and likes the trigger to be pulses shorter than output pulse width.

555 not looked at for a few years last in a weird rechargeable shaver .
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

PiGraham
Posts: 4862
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 5:23 pm

[quote="techpaul"]Actually be dubious about wikipedia look at the datasheet and the modified circuit, the level at which it triggers is 1/3 Vcc and CANNOT be retriggered within its timeout period (and a bit). Look at modification input goes low to trigger, and the charge cap is shorted when the input goes HIGH.

So GPIO stuck low will trigger once and the trigger circuit wont accept a trigger again, stuck high and never gets a trigger (times out). from datasheet (National Semi LM555) front page

[b]"The circuit may be triggered and reset on falling waveforms"[/b]

Yes the 555 is peculair but the trigger has weird characteristics and likes the trigger to be pulses shorter than output pulse width.

555 not looked at for a few years last in a weird rechargeable shaver .[/quote]

Ha ha! Yes, always read the data sheet! It's just that wikipedia tend to get top ranking. I think it is accurate here though. I think you will get a glitchy output in this application because the 555 does not re-trigger while the output is on, so the output will turn off every watchdog period and turn back on at the next S/W cycle generated trigger.

If your GPIO fails low the 555 output gets stuck high (capacitor permanently reset = timing disabled).
If the GPIO fails high the 555 output gets stuck low. (never triggers)

[quote="TI LM555 datasheet"]During the timing cycle when the output is high, the further application of a trigger pulse will not effect the circuit so long as the trigger input is returned high at least 10 μ s before the end of the timing interval. However the circuit can be reset during this time by the application of a negative pulse to the reset terminal (pin 4). The output will then remain in the low state until a trigger pulse is again applied

Note: In monostable operation the trigger should be driven high before the end of the timing cycle.
[/quote]

This use really needs a monostable that can be re-triggered while active, so that it never times out, and accepts edge not level triggers. The the output will stay high as long as the triggers keep coming and if the trigger gets stuck high or low the device times out and resets its output. Output high = healthy, low = sick.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 6:56 pm

PiGraham wrote:
techpaul wrote:Actually be dubious about wikipedia look at the datasheet and the modified circuit, the level at which it triggers is 1/3 Vcc and CANNOT be retriggered within its timeout period (and a bit). Look at modification input goes low to trigger, and the charge cap is shorted when the input goes HIGH.

So GPIO stuck low will trigger once and the trigger circuit wont accept a trigger again, stuck high and never gets a trigger (times out). from datasheet (National Semi LM555) front page

"The circuit may be triggered and reset on falling waveforms"

Yes the 555 is peculair but the trigger has weird characteristics and likes the trigger to be pulses shorter than output pulse width.

555 not looked at for a few years last in a weird rechargeable shaver .
Ha ha! Yes, always read the data sheet! It's just that wikipedia tend to get top ranking. I think it is accurate here though. I think you will get a glitchy output in this application because the 555 does not re-trigger while the output is on, so the output will turn off every watchdog period and turn back on at the next S/W cycle generated trigger.

If your GPIO fails low the 555 output gets stuck high (capacitor permanently reset = timing disabled).
If the GPIO fails high the 555 output gets stuck low. (never triggers)
Which is what is NOT[/b[ required[ I see your point nowquote]
TI LM555 datasheet wrote:During the timing cycle when the output is high, the further application of a trigger pulse will not effect the circuit so long as the trigger input is returned high at least 10 μ s before the end of the timing interval. However the circuit can be reset during this time by the application of a negative pulse to the reset terminal (pin 4). The output will then remain in the low state until a trigger pulse is again applied

Note: In monostable operation the trigger should be driven high before the end of the timing cycle.


This use really needs a monostable that can be re-triggered while active, so that it never times out, and accepts edge not level triggers. The the output will stay high as long as the triggers keep coming and if the trigger gets stuck high or low the device times out and resets its output. Output high = healthy, low = sick.[/quote]Adding the transistor as shown earlier in the thread and earlier the URL http://www.doctronics.co.uk/555.htm#retriggering example shows what happens but means the pulse width needs to be not too short to allow cap discharge. Despite what I said above forgot it is a PNP transistor so when a trigger low pulse comes along the 555 is triggered (or re-triggered) and also disharges the timing cap to zero which restarts the timeout period maintaining the output high.

The addition of the transistor creates a re-triggerable monostable avoiding the edge nature of the 555 being latched. Actually in a similar manner to a 123 device, apart from not always needing a repeated edge yes a 123 would be better.
Last edited by techpaul on Wed Jun 19, 2013 7:50 pm, edited 1 time in total.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Wed Jun 19, 2013 7:09 pm

Graham, thanks for the inputs - again!

I already have a circuit that should fit the bill of what you are recommending, and techpaul and I have been discussing it. Simulating the circuit works, but, as is my habit, I need to build and test it first. Parts are on order (somebody is having a field day with us Pi experimenters...) I'll be back soon, so watch this space...

PiGraham
Posts: 4862
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Failsafe(r) use of GPIO pin driving critical application

Thu Jun 20, 2013 6:39 am

I owe you an apology. I now see that you have used additional components to modify the operation of the 555 to do edge re-triggering. :oops:

Carry on!

User avatar
aTao
Posts: 1095
Joined: Wed Dec 12, 2012 10:41 am
Location: Howlin Eigg

Re: Failsafe(r) use of GPIO pin driving critical application

Thu Jun 20, 2013 10:02 am

PiGraham wrote: Here's an idea for what could be a simpler "fail-safe":
Connect a standard thermostats in series or parallel with the Pi controlled relays.
Thought thats what I said.....
>)))'><'(((<

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Thu Jun 20, 2013 10:20 am

Hmm, yes that's possible.
But, if I understand what you're suggesting, I think I will loose the ability to set temperatures at will over the internet, because the other thermostat will have precedence over the Pi one way or the other (temps too high, OR temps too low). I already have a thermostat in parallel, but can't use that yet. See my comments about that in an earlier post.

I'm actually working on another idea at the moment, that is building on the 555 timer solution. Stay tuned...

PiGraham
Posts: 4862
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Failsafe(r) use of GPIO pin driving critical application

Thu Jun 20, 2013 2:07 pm

paulv wrote:Hmm, yes that's possible.
But, if I understand what you're suggesting, I think I will loose the ability to set temperatures at will over the internet, because the other thermostat will have precedence over the Pi one way or the other (temps too high, OR temps too low). I already have a thermostat in parallel, but can't use that yet. See my comments about that in an earlier post.

I'm actually working on another idea at the moment, that is building on the 555 timer solution. Stay tuned...
You would be able to set the temperatures over the internet, but only within a safe range defined by the thermostats.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Thu Jun 20, 2013 3:55 pm

OK, finally got a couple of 555's, so I could build the circuit and start a real test.

Below is the diagram that I ended up with.
555-monostable.png
555-monostable.png (14.91 KiB) Viewed 6303 times
(the 555 can drive the LED directly, I just rigged this up to mimic a part of the relays circuit.)

Note the seemingly superfluous 2K2 pull-up for the trigger input of the 555. I initially made the mistake to rely only on the pull-up from the GPIO-pin, but if you run the test program, and stop it, you'll loose the pull-up (through the GPIO-cleanup). To protect the Pi input, I used a 1K resistor in series that creates a divider network with the GPIO pull-up, but the result was that the trigger input got low, driving the 555 output HIGH. Oops, need to watch out for that because that would switch on the HVAC. For now it works as a proof of concept. Keep that in mind if you want to play with it yourself.

You'll note from the R/C selection that I left my original idea of using a very long pulse duration to mimic my main timing loop. That does not work. The reason is that the last trigger pulse gets extended by a complete period, and that would mean that after I switch off the HVAC, it would continue to run for the duration of the R/C period. (that's why I like to build and verify things)

I initially selected the 555 because the pulses it can make are very long. The 74LS123 cannot handle that well, so I initially discarded that option.
It's back on the drawing board now, because it already has the re-trigger, and it has complementary outputs. Plus it comes with two for one, which is what I need eventually anyway.
Unfortunately, although I already ordered the parts, the shipment had the wrong chips in them, so more patience is needed.

For those interested in the 555 design, which may be very useful for other applications, below are the scope screens.
top of C1.jpg
top of C1.jpg (62.16 KiB) Viewed 6310 times
This screen shows the incoming trigger pulses on the lower channel (B) and the charging/discharging of C1. The R/C combination and the pulse period have been matched to leave enough head-room for Debian housekeeping.
555 output.gif
555 output.gif (62.37 KiB) Viewed 6310 times
The 555 output is pretty clear. The triggers start/restart the mono and after the last trigger, it runs until the R/C period has been satisfied.

To prepare the program for my software hart-beat, and to test the circuits, I designed a small Python program, that uses threads, as explained way up in this post. It's more complete, and generated the signals you see on the scope screens.

Code: Select all

#!/usr/bin/env python2.7

from time import sleep
from threading import Thread
import RPi.GPIO as GPIO

HVAC = False # Initial state of HVAC
HVAC_mono = 22 # GPIO channel 22 = pin 15
GPIO.setmode(GPIO.BCM)
GPIO.setup(HVAC_mono, GPIO.OUT, pull_up_down=GPIO.PUD_UP)  # initialize trigger channel with pull-up

class ThreadClass(Thread):
    def run(self):
        while HVAC: # if the HVAC needs to be on, generate the pulses
            GPIO.output(HVAC_mono, GPIO.LOW) # create negative edge to trigger the monostable
            sleep (0.01) # 10ms pulse duration
            GPIO.output(HVAC_mono, GPIO.HIGH) 
            sleep(.1) # 100ms period

def hart_beat(): # create a seperate thread to mimic a s/w hart-beat
    t = ThreadClass()
    t.setDaemon(True) # so a ctrl-C can terminate it
    t.start()

# main program
try:
   while True:
        hart_beat() # pulse the monostable
        # simulate the HVAC controlling software
        if HVAC == False: HVAC = True
        else: HVAC = False
        sleep(2) # 2 sec on, 2 sec off to fit the scope screen

except KeyboardInterrupt:
    GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup()     # clean up GPIO on normal exit
So, there is more homework to do, but again, there is hope.
I just need to be patient until the 74LS123 parts come, try that out and finally select the best one of the two. Stay tuned...

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Fri Jun 21, 2013 2:08 pm

Well hello again.
The 74LS123 arrived, and I rigged it up following to the schematic I got from forum member techpaul a while earlier:
123-monostable.png
123-monostable.png (12.74 KiB) Viewed 6286 times
I used the same Python program as I did for the 555, and it produced exactly the same results.
So, needless to say, as far as I'm concerned, the 123 is the clear winner!
Less parts, fewer tricks, reduced complexity, therefore better reliability.

Now that I have solved the driving portion of the circuit, I need to work on the circuit that senses the correct operation of the whole relays chain. (from the software all the way to the relays switch), and then the corrective action if something is wrong.
I have the schematic worked out, but need to verify a couple of things.

More later!

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Sat Jun 22, 2013 8:12 am

For the next step, I wanted to design a circuit that checks the whole relays chain. (from software hart-beat all the way to the relay switch)
Here is what I came up with to simulate the concept:
AC-alive_check.png
AC-alive_check.png (63.92 KiB) Viewed 6263 times
I used a jumper to act as the relay switch
The simulation proved the concept, with one caveat. LTspice kept insisting on grounding the 24VAC circuit, so I faked that with R5 and C3, to minimize any adverse effects on the Pi ground.

Here is what it does. If the switch is open, there is an AC voltage present on both sides of the contacts. This will trigger the reverse polarity LED's in the LTV814 opto-coupler, and the transistor will conduct in the rhythm of the AC, stopping the charging of the capacitor.
If the switch is closed to turn on the HVAC, there is no voltage over the relay switch (it's a short for the opto-coupler) there are no pulses to trigger the transistor and the capacitor will be charged to the 3V3 rail. The GPIO input pin will see a HIGH.
Here's the simulation:
AC-alive_check_sim.png
AC-alive_check_sim.png (49.02 KiB) Viewed 6263 times
The green trace is the 60Hz at the input pin of the opto-coupler. The blue trace is at the input of the GPIO channel.

Below is the circuit I actually built and tested. (I used a 24VAC transformer to prove the concept)
And the Python code I used to test the circuit with before connecting it to the 24VAC transformer.

Code: Select all

#!/usr/bin/env python2.7

import RPi.GPIO as GPIO
from time import sleep

PIN = 22 # GPIO 22 = pin 15

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.OUT)
HVAC = GPIO.PWM(PIN, 60) # 60 Hz

HVAC.start(50) # 50% duty cycle
raw_input('Press return to stop:')   # use raw_input for Python 2
HVAC.stop()

GPIO.cleanup()
I think I can eliminate R4 and doubled the size of R1, but it felt good so for now I just left it in. Same with R3. As a habit, I put a 1K resistor in series with all GPIO channels while I'm bread-boarding, for safety. I will probably reduce the size to 100Ohm, but still leave them in for protection. They are also nice to have to bridge distances to components on the real board.
AC-alive_check_ckt.png
AC-alive_check_ckt.png (9.29 KiB) Viewed 6263 times
In the software, I now need to verify that when I switch the HVAC off, I also get a HIGH on the GPIO input pin to verify the whole chain is working. This will check the heart-beat software, the GPIO channel, the functioning of the 74LS123, and the functioning of the relays coil and switch. If the HVAC is supposed to be off, and I get a LOW, I need to do something.

Obviously, we're not going to stop here now that we are this far.
My next step is to design and verify the circuit that switches the HVAC off when there is a malfunction in this chain, so we have obtained a fully closed-loop safety device for our system.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Sat Jun 22, 2013 9:45 am

So there you have it. This is the complete design for a closed-loop safety system up for review and comments:
Failsafe ckt.png
Failsafe ckt.png (39.53 KiB) Viewed 6254 times
Correction: R9 is connected to 3V3, not VCC
The Safety relays is in-line with the HVAC relays, and when it is powerless or not driven, it's open.
The software will have to activate this relays during the program init, and then it stays powered unless there is a Chain Alive issue, when it needs to be deactivated.
The HVAC relays will switch under power, so it has a snubber circuit to protect the contacts and prevent them from sticking. The Safety Relais will normally never be switched while powered, only when there is an emergency. Up to you to add a snubber if you want.

I used this Python code to stimulate the circuit before I tested it with the 24VAC:

Code: Select all

#!/usr/bin/env python2.7

import RPi.GPIO as GPIO
from time import sleep

PIN = 22 # GPIO 22 = pin 15

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.OUT)
HVAC = GPIO.PWM(PIN, 60) # 60 Hz

HVAC.start(50) # 50% dutycycle
#sleep(0.1)
raw_input('Press return to stop:')   # use raw_input for Python 2
HVAC.stop()

GPIO.cleanup()
Here is the LTsim circuit I used to verify the concept:
AC-alive_check.png
AC-alive_check.png (63.92 KiB) Viewed 6241 times
Note that LTspice insisted on a ground on the 24VAC side, so I faked that with C3 and R5.

And here is the simulation result:
AC-alive_check_sim.png
AC-alive_check_sim.png (49.02 KiB) Viewed 6241 times
The green trace is the voltage at the input pin of the opto-coupler, and the blue trace is at the PGIO channel pin. The components have been selected to stay below 0.5 V, or go to the 3V3 rail. Plenty of margin for the GPIO channel.

With an addition of a 74LS123, an opto-coupler and an extra transistor plus some hardware glue, you have an adequate protection system for only a few dollars or Euro's, not counting the extra safety relays. This relays should pretty much match the relays you're already using to power your whatever, especially if you use a relays that switches higher currents and/or main voltages. You may have to adjust the circuit to support the driving portion of the relays that you're using, but the principle stays the same. You will need to adjust R8 and R11 for voltages other than 24VAC, I selected 10mA to drive the input LED's.

CAUTION: If you do need to do something with the mains, let me point out that you need to take all precautions possible to make sure that the mains voltage is never even getting near to you or you Pi! In principle, the opto-coupler itself is safe (isolation voltage 5.000V rms), but it should not even be near you or your low voltage circuitry, and I would consider to use two 1/2 Watt resistors in series for R8 and R11 to create a safer path to the LTV814, or better yet, use a device that has more room between the input pins (the 814 has the standard 2.54mm or .1 inch for the DIL version I'm using).

If you don't switch something in an AC circuit, the Check Alive circuit can be a lot simpler, and you probably don't need the opto-coupler. Again the principle stays the same, but you can reduce some more parts.

I have considered using Triacs (with out without an isolating MOC) to switch the relays, but with the low frequency of switching the HVAC, there is not much stress on the contacts. Besides, Triacs fail mostly in the "closed" situation, not so good for our application. If you do want to use a Triac for the HVAC control, I would certainly use a relays for the fail-safe, because they normally fail in the open position. (because we only switch that relays powerless, the contacts are not likely to fuse together creating a closed failure) I may switch to FET's instead of the 2N3904's, but functionally they don't add a whole lot, so I have not decided yet.

One more caution though. I'm not an accomplished designer and I hope smarter people with more experience will look at this circuit and make suggestions for improvements. Also, I cannot build and test the above circuit with the actual HVAC until early September. I need to be present, but since I could build and test all parts individually, I'm pretty convinced it will work as advertised. And then one more heads-up in case you want to build your own thermostat. This is not the complete circuit, that may be a topic for another forum post later, much later.

Stay tuned for updates, inputs and improvements for this particular post though.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Fri Oct 04, 2013 7:28 pm

It's been a while since I wrote the last posting, but in the mean-time, I was able to finish the complete system, which is now up and running. In the process of integrating all the various components, and making it work in the complete system, I've had to make (or wanted) some adjustments, so here are the relevant pieces of the final result:

Here is the thermostat next to the "old" one, that still can be activated if needed.
IMG_0107.jpg
IMG_0107.jpg (35.99 KiB) Viewed 5764 times
The required components did not fit on one board, so I've actually made three.
(the Power Supply is covered in another forum post http://www.raspberrypi.org/phpBB3/viewt ... 37&t=50470 )

Here is the Logic Board, that sits on top of the GPIO connector of the Pi. It also plugs into the P6 (the Halt) connector on the Pi board, and with another connector into the Relay Board.
Here is the schematic of the Logic Board:
Logic Board.png
Logic Board.png (47.8 KiB) Viewed 5764 times
This is the Relay Board:
Relay Board.png
Relay Board.png (47.87 KiB) Viewed 5764 times
Here are some relevant pieces of the code:
GPIO Port definitions:

Code: Select all

# GPIO Channels
HVAC_Is_Alive_P = 27    # input
PWR_Sense_P = 17        # input
PWR_Timer_P = 25        # output
PWR_Gate_P = 7          # output
FAN_Is_Alive_P = 11     # input
FAN_P = 8               # output
Fail_Safe_P = 22        # output
Reset_P = 9             # input
System_Status_P = 18    # output
HVAC_P = 23             # output
Heat_Cool_P = 24        # output
# W-1 interface = 4     # input
GPIO Function definitions:

Code: Select all

    # ----- setting up the interface with the hardware
    if DEBUG: GPIO.setwarnings(True)
    else: GPIO.setwarnings(False)

    # Use the Raspberry the BCM pins
    GPIO.setmode(GPIO.BCM)

    # Power Supply setup, the input action is defined below
    GPIO.setup(PWR_Sense_P, GPIO.IN)
    #
    # The following 2 ports must be set within the Shutdown_Timer period of 45 seconds
    # otherwise the HW Watch_Dog on the UPS board will put the PI to sleep.
    GPIO.setup(PWR_Timer_P, GPIO.OUT, initial=GPIO.HIGH)
    GPIO.setup(PWR_Gate_P, GPIO.OUT, initial=GPIO.HIGH)

    # fail safe relais setup for the HVAC system
    GPIO.setup(Fail_Safe_P, GPIO.OUT, initial=GPIO.LOW, pull_up_down=GPIO.PUD_DOWN) # Relais K2

    # HVAC relais setup
    GPIO.setup(HVAC_Is_Alive_P, GPIO.IN) # safety check for the HVAC relais
    GPIO.setup(HVAC_P, GPIO.OUT, pull_up_down=GPIO.PUD_UP, initial=GPIO.LOW) # Green LED, Relais K1

    # Fan relais setup
    GPIO.setup(FAN_Is_Alive_P, GPIO.IN) # safety check for the fan relais
    GPIO.setup(FAN_P, GPIO.OUT, pull_up_down=GPIO.PUD_UP, initial=GPIO.LOW) # Yellow LED, Relais K4

    # system reset button setup, the action is defined below
    GPIO.setup(Reset_P, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    # system status LED setup
    GPIO.setup(System_Status_P, GPIO.OUT, pull_up_down=GPIO.PUD_UP)   # White LED
    sys_stat = GPIO.PWM(System_Status_P, 0.5) # PMW frequency of .5 Hz
    sys_stat.start(0) # start the PWM, but with a duty cycle of 0, so the LED is on during booting

    # setup of the Heat_Cool relais and the LED's
    GPIO.setup(Heat_Cool_P, GPIO.OUT, initial=GPIO.LOW, pull_up_down=GPIO.PUD_UP) # Red LED - Heat, Blue LED - Cool, Relais K3

    # Connector pin 7 is reserved for the W1 interface to the DS18X20 sensors

    # --- this needs to be at the end of the port definitions, otherwise the detections don't work!
    # setup the event to detect a falling edge on the main power sense input
    GPIO.add_event_detect(PWR_Sense_P, GPIO.FALLING)
    # setup the event detection thread for the reset button
    GPIO.add_event_detect(Reset_P, GPIO.FALLING, callback=reset_action, bouncetime=1000)

And the code to drive the HVAC system (the code for the Fan is virtually the same)

Code: Select all

class HVAC_ThreadClass(Thread):
    def run(self):
        while HVAC_SYSTEM : # if the HVAC needs to be activated, generate the pulses
            # create a negative edge to trigger the monostable
            GPIO.output(HVAC_P, GPIO.LOW)
            sleep (0.01) # 10ms pulse duration
            GPIO.output(HVAC_P, GPIO.HIGH)
            sleep(.1) # 100ms period



def HVAC_hart_beat(): # create a seperate thread to mimic a s/w hart-beat
    global hvac_thread
    hvac_thread = HVAC_ThreadClass()
    hvac_thread.setDaemon(True) # so a ctrl-C can terminate it
    if not hvac_thread.isAlive():
        hvac_thread.start() # start the thread

The function that controls the running of the PWM:
(note that I took several statements out because it clutters the meaning of the actual code)

Code: Select all

def HVAC(mode):
    '''
    Function to switch the cooling/heating system on or off.
    Called with HVAC[ON | OFF]

    The hardware does not care if we switch it on while it is already on.
    Our logging will be cleaner if we only register the mode changes.

    '''
    global hvac_flag, hvac_save_mode, hvac_rrd, system_mode, HVAC_SYSTEM

    write_log("trace", "entering HVAC : "+str(mode))

    if mode :
        HVAC_SYSTEM = ON
        # start the PWM process thread. It will react to the status of
        # the global variable HVAC_SYSTEM. If HVAC_SYSTEM = OFF it will terminate
        HVAC_hart_beat()
        sleep(1) # give it some time to start

        if GPIO.input(HVAC_Is_Alive_P) == 0 : # if the relais is closed it sb 1; if open a 0
            write_log("error", "HVAC relais not working")
            # if this is the case, the temperature will go up or down, and we'll
            # catch that in get_temps
            mail_alarm("HVAC relais fails to close")
            Fail_Safe(OFF) # disable the HVAC relais from the system
        if hvac_save_mode :
            write_log("mode", "HVAC on  : {action}".format(
                action="heating" if system_mode else "cooling"))
            hvac_save_mode = False # only report mode changes
    else:
        HVAC_SYSTEM = OFF
        sleep(2) # give the thread some time to terminate
        if hvac_thread is not None and hvac_thread.is_alive():
            if TRACE: print(hvac_thread.getName() + " is still alive and should be off!")
            return # try it again

        if GPIO.input(HVAC_Is_Alive_P) == 1 : # if the relais is open it sb a 0; if still closed a 1
            if TRACE:  print "HVAC relais fails to open"
            write_log("error", "HVAC relais fails to open")
            mail_alarm("HVAC relais fails to open")
            Fail_Safe(OFF) # disable the HVAC relais from the system
        if DEBUG: print "HVAC off"
        if not hvac_save_mode :
            write_log("mode", "HVAC off : {action}".format(
                action="heating" if system_mode else "cooling"))
            hvac_save_mode = True

If the relays seems to be stuck, the Fail_Safe relays is made powerless and the circuit can no longer keep the HVAC system running.
Last edited by paulv on Sat Oct 05, 2013 2:55 am, edited 2 times in total.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Failsafe(r) use of GPIO pin driving critical application

Fri Oct 04, 2013 7:30 pm

Here is a picture of the Logic Board:
IMG_0096.jpg
IMG_0096.jpg (31.77 KiB) Viewed 5764 times
And here is the Relays Board
IMG_0097.jpg
IMG_0097.jpg (35.82 KiB) Viewed 5764 times
And in the enclosure with most cables attached:
IMG_0100.jpg
IMG_0100.jpg (45.29 KiB) Viewed 5763 times
Thanks for contributing and following this thread. It's been a great learning experience and a lot of fun.

Return to “Automation, sensing and robotics”