Paging A Mobile Phone With A Key Fob Part 2: Handle Event via a Raspberry Pi


In this blog post we will be connecting a 433MHz RF receiver to a Raspberry Pi (RPi) so that we can process the signal from the 433MHz RF transmitter.

A little bit about 433MHz RF

Radio communication over this UHF band have been around for a long time and is very common in the consumer electronic space. The 433MHz transmit and receiver modules are fairly easy to obtain and are very cheap. I won’t be going into details on how they works as there are plenty of great online resources on the topic. One tutorial I thought was really good at laying out the concepts was How 433MHz RF Tx-Rx Modules Work & Interface with Arduino.

Main components required

  • 433MHz transmitter (key fob)
  • 433MHz receiver (KR2402)
  • Raspberry Pi with Raspberry OS installed

I have chosen not to use a bare transmitter/receiver module as we don’t need to send custom data in our scenario. All we need is a device to indicate an event has occurred and also to indicate the event is no longer a concern. So a one or two buttoned device is all we need (a key fob is perfect and is ready to use off the shelf.

Getting the transmitter and receiver talking

I got my 2-channel RF relay receiver/key fob transmitter from AliExpress. Depending on where you are, you might be able to get them cheaper on eBay, Amazon, etc.

Relay receiver and key fob
Relay receiver board layout

First thing we want to do is ensure the receiver can receive the signals from the key fob.

If we look at the board layout above, we can see that the connector along the bottom takes anything between 5 – 30VDC. This is the input voltage that will drive the receiver (therefore we can connect a 9V battery to power it up, with the positive lead connected to V and the negative lead connected to G).

Once the receiver is powered up, we can clear the receiver of any previously stored transmitter sequence. We can do this by pressing the Learning Button 8 times. After that, the receiver should ignore any transmission from the key fob (no LED should be flashing when either button A or B is pressed).

Next we will train the receiver to accept the transmission from the key fob where each button will activate a relay on the receiver. We are going to train the receiver to treat the buttons as momentary presses (i.e. activated when the button is pressed, deactivated when the button is released). This is done by pressing the Learning Button once (more options can be found at https://qiachip.com/blogs/usermenu/dc6-30v-2channel-receiver-instruction-kr2402a). After that, we should see the LED on the receiver changes state when a button is pressed or released.

Relay receiver setup demo

Connecting relay receiver to the Raspberry Pi

Instead of powering the relay receiver with a 9V battery, we are going to power it using the 5V line on the Raspberry Pi. All we need to do is connect the 5V line on the Raspberry Pi to the input voltage terminal (V) on the relay receiver, then connect a ground pin on the Raspberry Pi to the ground terminal (G) on the relay receiver. Also, when wiring things up, make sure the Raspberry Pi is powered off so we don’t accidentally short something and damage the devices.

The remaining to do is connect each relay to a GPIO pin on the Raspberry Pi. We are also going to connect them up as normally opened (NO) mode. What this means is normally the relay will act as an opened circuit. Only when a button is pressed on the key fob, the receiver magnetised the relay, resulting in a closed circuit (GPIO pin active). When the button is released on the key fob, the receiver de-magnetised the relay, resulting in an opened circuit (GPIO pin inactive). In the diagram below, the top relay drives GPIO2 while the bottom relay drives GPIO3.

Raspberry Pi to relay receiver wiring diagram
Raspberry Pi to relay receiver actual wiring
Raspberry Pi and relay receiver in enclosure demo

At this point we can place the Raspberry Pi and relay receiver anywhere around the house as we no longer need to physically access them.

Processing the GPIO inputs on the Raspberry Pi

Now that the Raspberry Pi have been tucked away in a cabinet somewhere, we can actually setup a SSH session with the Raspberry Pi and write code on it. In the following example I am using VS Code to SSH into the Raspberry Pi.

In the demo above, what we did was SSH into the Raspberry Pi then select the project directory (or create a new one if you like). But more importantly, we want to create the following files:

  • App.py
  • ButtonMonitor.py
  • ButtonObserver.py
App.py

This is the main application entry point. All it does is create a ButtonObserver instance and two ButtonMonitor instance. The code for App.py is as follow:


'''
App.py
'''
import asyncio
import sys
import signal

from ButtonMonitor import ButtonMonitor
from ButtonObserver import ButtonObserver

async def main():

    execution_is_over = asyncio.Future()

    def abort_handler(*args):
        execution_is_over.set_result("Ctrl+C")
        print("")
        print("Cleaning up before exiting...")
        sys.exit(0)

    signal.signal(signal.SIGINT, abort_handler)

    try:
        observer = ButtonObserver()
        ButtonMonitor(2, "A", observer)  # Monitor button connected to input 2
        ButtonMonitor(3, "B", observer)  # Monitor button connected to input 3

        exit_reason = await execution_is_over
        print('Exit reason detected: %r' % exit_reason)

    finally:
        pass

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

ButtonMonitor.py

This file defines the ButtonMonitor class. This is a simple class to monitor a button via a GPIO input pin and notifies the observer when the button is pressed (GPIO Zero library is used to monitor the GPIO pins). The code for ButtonMonitor.py is as follow:


'''
ButtonMonitor.py
'''

from gpiozero import Button

class ButtonMonitor:
   def __init__(self, input_pin, name, observer):
      self.button = Button(input_pin)
      self.button_name = name
      self.observer = observer

      self.button.when_pressed = self.button_pressed

   def button_pressed(self):
      if self.observer is None:
         pass  # No observer so do nothing
      else:
         self.observer.handle_button_pressed(self.button_name)

ButtonObserver.py

This file defines the ButtonObserver class. This is a simple class which handles the button presses (which in this case just print out which button was pressed). The code for ButtonObserver.py is as follow:


'''
ButtonObserver.py
'''

class ButtonObserver:
   def handle_button_pressed(self, source):
      print("Button %r pressed" % source)

Handling button presses via Raspberry Pi Demo

In the following demo, I am using Termius on a mobile phone to SSH into the Raspberry Pi. We can see in the console log which button is being pressed.

What’s Next?

In the next part of the series, instead of logging to the console we will forward the button events to the cloud using Azure IoT Hub.

Categories: Internet of things, Python, Raspberry PiTags: , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: