Dr. Arne JachensDr. Arne Jachens

Relay controlled viy GPIO

Raspberry_Outputs

Connection of the relays to the RaspberryPi. Some output pin (GPIO22) is used to stear a relay. To keep the currenct over the RaspberryPi < 3 mA I use a resistor of 1.2 kOhm and a Transistor to switch the control current of the relay. The diode 1N4148 is used to get rid of inductive voltage spike when relay is shut off.

The simple solution above came with the disadvantage that, at some point of my development, I observed voltage drops due to operation of the relays, that affected my temperature measurements!

Therefore I use opto couplers to have a galvanic separation of my control board and the relays. By this design I moved the relays working at dangarous 230 V to an exterior PCB and may use indiendent supply voltage of 5V or 12V.

Raspberry_Relay.svg

Since the opto coupler PC817 draws a current of 20 mA, which is too much for the GPIO, I use the transistor BC337 as amplifier, R1 = 1.2 kOhm and R2 = 200 Ohm.

Python interface

import  RPi.GPIO as  GPIO


class HvcSetGPIO:
    
    def  __init__(self):
        """
        Connect your actuators to specific GPIO pins.
        """
        #Relays  links nach rechts: 27, 22, 23, 24, 25
        self.ActPins={}
        self.ActPins['solar'] = 25 #22
        self.ActPins['oven']  = 24 #23
        self.ActPins['pump']  = 23
        #self.ActPins['serv']  = 24
        #self.ActPins['door']  = 25

        
    def  setMode(self):
        """
        At startup, you need to set the mode once.
        """
        #Setup GPIO
        GPIO.setmode(GPIO.BCM)
        message = "HvcSetGPIO.setMode: \n"
        actuators={}
        for  pin in self.ActPins:
            GPIO.setup(self.ActPins[pin], GPIO.OUT)
            message = message + "GPIO "+pin+":\t"+str(self.ActPins[pin])+"\t=> OUT \n"
            actuators[pin] = 0

        return actuators,message

    
    def  set(self,actuators):
        """
        Set the GPIO according to the actuator settings,
        The actuators are expected to be in the range [0:1],
        where values > 0.5 are assumed to be ON.
        """
        for  pin in self.ActPins:
            if actuators[pin]>0.0:
                GPIO.output(self.ActPins[pin], GPIO.HIGH)
            else:
                GPIO.output(self.ActPins[pin], GPIO.LOW)
        return

"""
For testing, toggle some relays and hear the click.
Secondly, the status of all actuator pins is reported.
"""
if __name__ == "__main__":
    import  time
    myIO = HvcSetGPIO()
    actuators,message = myIO.setMode()
    print(message)
    actuators['oven']=1
    #myIO.set(actuators)
    time.sleep(1)
    actuators['oven']=0
    #myIO.set(actuators)
    #check status of GPIOS
    for  pin in myIO.ActPins:
        GPIO.output(myIO.ActPins[pin], GPIO.HIGH)
        foo = GPIO.input(myIO.ActPins[pin])
        print(pin,foo)
        
    time.sleep(2)
    for  pin in myIO.ActPins:
        GPIO.output(myIO.ActPins[pin], GPIO.LOW)
        foo = GPIO.input(myIO.ActPins[pin])
        print(pin,foo)

Test the GPIO Pin

To test the output relays you may toggle the appropriate pin via shel:
This works only if you have root privilegues
sudo -i
Activate port 22 and configure it as output pin
echo "22" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio22/direction

Now toggle the port
echo "1" > /sys/class/gpio/gpio22/value
echo "0" > /sys/class/gpio/gpio22/value
If you did connect a multimeter to the relay you will hear the beep.

Access the GPIO Pins

I created a new group
sudo -i
groupadd -f --system gpio

and added me to that group
nano /etc/group

gpio:x:99:pi
Than I created the access to the four pins used by me:
echo "22" > /sys/class/gpio/export
echo "23" > /sys/class/gpio/export
echo "24" > /sys/class/gpio/export
echo "25" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio22/direction
echo "out" > /sys/class/gpio/gpio23/direction
echo "out" > /sys/class/gpio/gpio24/direction
echo "out" > /sys/class/gpio/gpio25/direction

and changed owner and writing permissions:
chown -R root:gpio /sys/class/gpio/gpio22/*
chown -R root:gpio /sys/class/gpio/gpio23/*
chown -R root:gpio /sys/class/gpio/gpio24/*
chown -R root:gpio /sys/class/gpio/gpio25/*
chmod g+w /sys/class/gpio/gpio22/value
chmod g+w /sys/class/gpio/gpio23/value
chmod g+w /sys/class/gpio/gpio24/value
chmod g+w /sys/class/gpio/gpio25/value

This way I can switch the relays with my user privilegues - as long as I do not reboot the PI.

Finally I"ve put these tasks to the startup script /etc/init.d/S999raspberry

!/sbin/sh
#
### BEGIN INIT INFO
# Provides:          S999
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# Should-Start: 
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: HVC Jachens Haustechnik
# Description:
### END INIT INFO

# Template for custom rc script
PATH=/usr/sbin:/usr/bin:/sbin
export PATH

case $1 in
"start_msg")
        echo "Starting the RaspberryPi ports"
        ;;

"stop_msg")
        echo "Stopping the RaspberryPi ports"
        ;;

"start")
         # All required instruction to start the process. Can be a call to another script.
        #sudo echo "4" > /sys/class/gpio/export
        sudo echo "14" > /sys/class/gpio/export
        sudo echo "15" > /sys/class/gpio/export
        sudo echo "17" > /sys/class/gpio/export
        sudo echo "18" > /sys/class/gpio/export
        sudo echo "27" > /sys/class/gpio/export
        sudo echo "22" > /sys/class/gpio/export
        sudo echo "23" > /sys/class/gpio/export
        sudo echo "24" > /sys/class/gpio/export
        sudo echo "25" > /sys/class/gpio/export
        #sudo echo "out" > /sys/class/gpio/gpio4/direction
        sudo echo "in"  > /sys/class/gpio/gpio14/direction
        sudo echo "out" > /sys/class/gpio/gpio15/direction
        sudo echo "out" > /sys/class/gpio/gpio17/direction
        sudo echo "out" > /sys/class/gpio/gpio18/direction
        sudo echo "out" > /sys/class/gpio/gpio27/direction
        sudo echo "out" > /sys/class/gpio/gpio22/direction
        sudo echo "out" > /sys/class/gpio/gpio23/direction
        sudo echo "out" > /sys/class/gpio/gpio24/direction
        sudo echo "out" > /sys/class/gpio/gpio25/direction
        #sudo /bin/chown -R root:gpio /sys/class/gpio/gpio4/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio14/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio15/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio17/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio18/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio27/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio22/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio23/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio24/*
        sudo /bin/chown -R root:gpio /sys/class/gpio/gpio25/*
        #sudo /bin/chmod g+w /sys/class/gpio/gpio4/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio14/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio15/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio17/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio18/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio27/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio22/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio23/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio24/value
        sudo /bin/chmod g+w /sys/class/gpio/gpio25/value
        sudo chown root:gpio /dev/spidev0.*
        sudo chmod g+rw /dev/spidev0.*
        sudo chown root.gpio /dev/gpiomem
        sudo chmod g+rw /dev/gpiomem
        cd /var/www/ && sudo -u www-data php HV_loop.php&
        rval=1
        ;;


"stop")
        # All required instruction to stop the process. Can be a call to another script.
        pid=$(pgrep -f HV_loop)
        echo $pid
        kill $pid
        pid=$(pgrep -f thermos200)
        kill $pid

        rval=1
        ;;

*)
        echo "usage: $0 {start|stop|start_msg|stop_msg}"
        rval=1
        ;;

*)
        echo "usage: $0 {start|stop|start_msg|stop_msg}"
        rval=1
        ;;
esac
exit $rval
and activated this by
update-rc.d S999raspberry start NN 3

Such init.d script may be tested by
sudo /etc/init.d/S999raspberry start

The apache may be restarted by:
sudo /etc/init.d/apache2 restart

Then I added the GPIO access to my test program and checked it worked.

Configuration of GPIO Pins

For further information on how to configre the GPIO pins have a look to Raspberry Pi GPIO Belegung. There the GPIO access via bash, wiringPI or python is explained.