Remote Control Switches via 433 Mhz transmitter using gpiod with libgpiod v2 - instead of using gpiozero , RPi.GPIO , WiringPi

This page shows the way to control your lights and other devices in your house by using a simple 433 Mhz transmitter connected to the Raspberry Pi.

For more than 10 years I used the WiringPi software from www.wiringpi.com (which was standard software to use at that time and now is deprecated).

I created a script (Bash) which are independent of the Raspberry Pi model used and OS/Debian version!

##### Now updated for using Trixie / Debian version 13 with libgpiod v2 ! #####

I am using python with the libgpiod v2 library of gpiod (much faster than the command-line tools).

The scripts will still work after updates/upgrades of your Raspberry Pi hardware/software! So, this will work for RPi model 1 to 5.

It's using the gpiod software which is the best to be installed and the standard nowadays.

Note: Raspberry Pi 5 model will NO longer support NOR work with RPI.GPIO or WiringPi libraries/software.

 

Supported remote switches switches (which will work with this instruction):

- ELRO AB440 S
- Brennenstuhl RCS 1000 N Comfort
(Not tested: BAT RC-3500-A, Intertechno (Silvercrest) PA3-1000, Vivanco FSS 31000W)

NOTE: The ELRO switches are no longer available.. Order (Amazon/Ebay) and use the "Brennenstuhl RCS 1000 N Comfort" which are exactly the same as the ELRO's !

 

Hardware:

- Raspberry Pi

- RF-DRA887TX or DRA888TX or DRA889TX DORJI 433MHZ 10/17dBm ASK TRANSMITTER , DIP PACKAGE => http://www.dorji.com/products.php?CateId=36

PIN used on Raspberry Pi:
4 => 5V ----> +5V RF-Transmitter
6 => GND ----> 0V/GND RF-Transmitter
8 => GPIO for TX ----> Data out RF-Transmitter ==> This is Pin 14 !! See "TRANSMIT_PIN = 14" (in my case this is 14) in the elro.py script.

# make sure you install at least the libgpiod-dev for the gpiod.h file (also for C-library support)
apt-get install gpiod libgpiod-dev

mkdir -p /wiringpi/lights/

Scripts to create elro (To give all the credit in the past to WiringPi the directory is still named /wiringpi  and 'chmod 755' ):

-------------------------- name it: elro ------------------------------------------------------------

#!/bin/bash

#set -x

 


if [ -z "$3" -o -n "$4" ]

then

 echo "Usage: $0 <SwitchID> <SwitchNUM> <on|off>"

 echo "Example: $0 24 B on"

 exit

fi

 


DT=`date +%d-%m-%Y-%H-%M`

 


export PULSE=302

export ARG1=$1

export ARG2=$2

export ARG3=$3

 


if [ "${ARG1}" -lt "1" -o "${ARG1}" -gt "31" ]

then

 echo "Not a valid argument for SwitchID (valid values between: 1-31)!"

 echo "Usage: $0 <SwitchID> <SwitchNUM> <on|off>"

 exit

fi

D2B=({0..1}1{0..1}1{0..1}1{0..1}1{0..1}1)

PART1=`echo -n ${D2B[$ARG1]}|rev`

 


case $ARG2 in

 A|a )

 PART2=1110101010

 ;;

 B|b )

 PART2=1011101010

 ;;

 C|c )

 PART2=1010111010

 ;;

 D|d )

 PART2=1010101110

 ;;

 E|e )

 PART2=1010101011

 ;;

 * )

 echo "Not a valid argument for SwitchNUM (valid values: A|B|C|D|E)!"

 echo "Usage: $0 <SwitchID> <SwitchNUM> <on|off>"

 exit

 ;;

esac

 


case $ARG3 in

 ON|On|on )

 PART3=11101

 ;;

 OFF|Off|off )

 PART3=10111

 ;;

 * )

 echo "Not a valid argument for <on|off>!"

 echo "Usage: $0 <SwitchID> <SwitchNUM> <on|off>"

 exit

 ;;

esac

 


/wiringpi/lights/elro.py ${PULSE} ${PART1}${PART2}${PART3} 2>/tmp/elro_gpiod_elro_$$.err

if [ ! -s /tmp/elro_gpiod_elro_$$.err ]

then

 rm /tmp/elro_gpiod_elro_$$.err 2>/dev/null

else

 sleep 1

 /wiringpi/lights/elro.py ${PULSE} ${PART1}${PART2}${PART3} 2>/tmp/elro_gpiod_elro_$$.err

fi

 


exit

 


#OSBIT=`getconf LONG_BIT`

#if [ "${OSBIT}" = "64" ]

#then

# /wiringpi/lights/gpiod_elro_64_bit ${PULSE} ${PART1}${PART2}${PART3}

#else

# /wiringpi/lights/gpiod_elro_32_bit ${PULSE} ${PART1}${PART2}${PART3}

#fi

#

#exit

 


#Address(10 bits):

#31: 1111111111 

#15: 1111111110

#1 : 1110101010

#10: 1011101110

#16: 1010101011

#24: 1010101111

1111101010101110101010111

#bitpos: 10 => 16

#bitpos: 8 => 8

#bitpos: 6 => 4

#bitpos: 4 => 2

#bitpos: 2 => 1

#

#Letters(10 bits):

#A on: 1110101010

#B on: 1011101010

#C on: 1010111010

#D on: 1010101110

#E on: 1010101011

#bitpos: 20 => E

#bitpos: 18 => D

#bitpos: 16 => C

#bitpos: 14 => B

#bitpos: 12 => A

#

#Letters(5 bits):

#on:  11101

#off: 10111

#bitpos: 24 => off

#bitpos: 22 => on

#

-------------------------- end of: elro ------------------------------------------------------------
 

 

-------------------------- name it: elro.py ------------------------------------------------------------

#!/usr/bin/python3

 

import time

import sys

import gpiod

 

if len(sys.argv) < 3:

   print('no arguments passed')

   print('usage example: gpiod_elro.py 302 1010111111010101011..')

   sys.exit()

 

# Next is for Elro or Brennenstuhl RCS 1000 N Comfort

delay_s = float(sys.argv[1])

short_delay: float = delay_s / 1000000.0

long_delay: float = 3 * short_delay

extended_delay: float = 31 * short_delay

 

NUM_ATTEMPTS = 10

TRANSMIT_PIN = 14

GPIOCHIPSET = "/dev/gpiochip0"

 

def transmit_code(code):

    GPIOLINE=gpiod.request_lines(GPIOCHIPSET,consumer="elrosend",config={

      TRANSMIT_PIN: gpiod.LineSettings(

      direction=gpiod.line.Direction.OUTPUT,bias=gpiod.line.Bias.AS_IS,output_value=gpiod.line.Value.INACTIVE)

    })

    GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.INACTIVE)

    for t in range(NUM_ATTEMPTS):

        for i in code:

            if i == '1':

                GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.ACTIVE)

                time.sleep(short_delay)

                GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.INACTIVE)

                time.sleep(long_delay)

            elif i == '0':

                GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.ACTIVE)

                time.sleep(long_delay)

                GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.INACTIVE)

                time.sleep(short_delay)

            else:

                continue

        GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.INACTIVE)

        time.sleep(extended_delay)

    GPIOLINE.set_value(TRANSMIT_PIN, gpiod.line.Value.INACTIVE)

    GPIOLINE.release()

 

if __name__ == '__main__':

    for argument in list(sys.argv[2:]):

        exec('transmit_code(argument)')

 

exit()

 

#Now you can use the elro command to control a switch:

f.e.: ./elro 24 B on

./elro 18 C off

 

  Donate now via the Paypal button on the top in US Dollar and on the bottem in Euro