Making the Raspberry Pi use RF signals for logic

Making the Raspberry Pi Use RF Signals for Logic

This post will explain how to get the Raspberry Pi to read and interpret RF signal-codes to be used for logic. Ultimately I’ll show you how to “capture” signals as strings and compare them with expected strings to trigger either a Bash or Python script.

Requirements & assumptions

First of all, you need a fully functional Raspberry Pi with Raspbian installed. In order to get started with Making the Raspberry Pi Use RF Signals for Logic, I’m assuming that you also followed and completed 433MHz RF Communication to a Raspberry Pi. After the setup, we will need the command line to do some testing and write some Python and Bash coding to receive signals and apply logic to them. It’s easier than you might think! If you don’t have a screen, keyboard and mouse you will need to be on a network and use PuTTY and/or WinSCP for the setup, coding and testing.

For easier testing purposes I recommend having additional set of working speakers/earphones connected to the audio jack of your Raspberry Pi, especially if you’re not going to use the HDMI cable for sound.

For this tutorial you will also need:

  • eSpeak fully installed & audible.

Let’s start

In order to get the Raspberry Pi to use RF signals for logic, we must first get it up and running with receiving RF signals. After following my 433MHz RF Communication to a Raspberry Pi post, you should have an Arduino connected, up and running with a transmitter and a Raspberry Pi to a receiver of a 433MHz RF Transmitter Receiver modules pair. This was the code snippet we used then to send signal-codes to the Raspberry Pi:

#include 

RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  // Transmitter is connected to Arduino Pin #10  
  mySwitch.enableTransmit(10);

  // Optional set pulse length.
  // mySwitch.setPulseLength(320);

  // Optional set protocol (default is 1, will work for most outlets)
  // mySwitch.setProtocol(2);

  // Optional set number of transmission repetitions.
  // mySwitch.setRepeatTransmit(15);

}

void loop() {
  /* Using decimal code */
  mySwitch.send(1234, 24);
  Serial.print("Attempting to send 1234");
  delay(4000);
  mySwitch.send(4321, 24);
  Serial.print("Attempting to send 4321");
  delay(4000);

  /* Using binary code */
  //mySwitch.send("000000000001010100010001");
  //delay(1000);  
  //mySwitch.send("000000000001010100010100");
  //delay(1000);*/
}

With this piece of coding the Arduino will send the decimal code ‘1234’, wait for four seconds and then send ‘4321’. It will run over and over until the Arduino’s power is disconnected. There are many ways to incorporate microcontrollers with code and other modules to give specific signal-codes, but for now we will only use these two signals (‘1234 & ‘4321’).

Make sure the Raspberry Pi receives them correctly.

It was mentioned that after installing wiringPi and 433Utils we will be using 433Utils’ RFSniffer.cpp to receive signals.

RFSniffer.cpp only reads and displays the signals it received on the terminal. To continue we will need to modify this file and bring in a Python script file to do the logic part where the modified RFSniffer.cpp will trigger the Python file.

The initial Python script

With this file we will simply make the correct signal-code received, trigger the python file to log the signal-code received.

Create and/or go to your working directory and create the Python file. I will be using /home/pi/bin as my working directory and sniffer.py as my initial Python file,

sudo nano /home/pi/bin/sniffer.py

copy the following script-code to it:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, getopt
import uuid

log_file_directory = "/home/pi/logs" # don't use a '/' at the end!
log_file_name = "sniffed.txt"

def main(argv):
  opts, args = getopt.getopt(argv,"s:")

  for opt, arg in opts:
    if opt == '-s': #meaning there's valid args/codes in it
      full_log_file_name = log_file_directory + "/" + log_file_name
        with open(full_log_file_name, 'a') as outfile:
          sniffed_code = arg + "\n"
          outfile.write(sniffed_code)

if __name__ == "__main__":
  main(sys.argv[1:])

and make it fully accessible for all:

sudo chmod 777 /home/pi/bin/sniffer.py

When triggered, the Python script will log the signal to /home/pi/logs/sniffed.txt. You can change these destinations if you like. It will sequentially log them one by one in the same file.

Create & compile a new RFSniffer.cpp file

To edit and recompile RFSniffer.cpp, you need to be in the 433Utils/RPi_utils directory:

cd 433Utils/RPi_utils

First, create a backup of your original file,

sudo cp RFSniffer.cpp RFSniffer_original.cpp

then open and edit the file,

sudo nano RFSniffer.cpp

and remove all the old code and copy and paste the following code to it:

/*
  RFSniffer

  Usage: ./RFSniffer []
  [] = optional

  Hacked from http://code.google.com/p/rc-switch/
  by @justy to provide a handy RF code sniffer

  Adjusted from http://stackoverflow.com/questions/26948861/raspberry-rfsniffer-read-output-with-python
  by Renier Delport to provide Python integration

*/

#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <unistd.h>

RCSwitch mySwitch;

int main(int argc, char *argv[]) {

  // This pin is not the first pin on the RPi GPIO header!
  // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
  // for more information.
  int PIN = 2;

  if(wiringPiSetup() == -1) {
    printf("wiringPiSetup failed, exiting...");
    return 0;
  }

  int pulseLength = 0;
  if (argv[1] != NULL) pulseLength = atoi(argv[1]);

  mySwitch = RCSwitch();
  if (pulseLength != 0) mySwitch.setPulseLength(pulseLength);
  mySwitch.enableReceive(PIN);  // Receiver on interrupt 0 => that is pin GPIO pin #2 (pin 13)

  while(1) {
    int count = 0;
    std::string signals;
    signals = "";

    while (count < 10000) {
      if (mySwitch.available()) {
        int value = mySwitch.getReceivedValue();

        if (value == 0) {
          printf("Unknown encoding\n");
        }
        else {
          std::string signal;
          std::stringstream signalStream;
          signalStream << value; signal = signalStream.str();
          if (signals.length() > 0) {
            signals.append(",");
          }
          else {
            // first receive, so reset timeframe here
            count = 0;
          }
          signals.append(signal);
          printf("Received %s\n", signal.c_str() );
        }
        mySwitch.resetAvailable();
      }
      usleep(50);
      count += 1;
    }
    if (signals.length() > 0) {
      std::string command;
      command.append("python /home/pi/bin/sniffer.py -s ");
      command.append(signals);
      printf("Call %s\n", command.c_str());
      system(command.c_str());
    }
  }
  exit(0);
}

This code snippet will chain together signal-codes received in a short frame of time as they are received. These signal-codes are passed in as comma-separated values to your python script (argument -s code1,code2,code3).

Remember to save your changes (Ctrl X & y).

To recompile the changed code, while still in the 433Utils/RPi_utils directory use:

make RFSniffer.cpp

or:

make all

After successfully compiling your file, go back to the /home/pi directory (cd). To start RFSniffer you can use the following command:

sudo /home/pi/433Utils/RPi_utils/RFSniffer

The terminal will now be waiting for RF signals and if it receives them, will display it on the terminal screen and also send them intermittently to the Python sniffer script. You might be seeing other code in between there as well, but it should mainly be ‘1234’ followed by ‘4321’. If you received these code signals on your terminal, also check your /home/pi/logs/sniffed.txt.

Take a breather

That’s the basis of sending and receiving RF signal-codes on a Raspberry Pi. When RFSniffer is running, you will now be able to use the signals in the sniffer.py file for further logic. You can keep your Ardiuno running, but exit out of RFSniffer by pressing Ctrl + Z.

The adapted Python script

A part of the adopted Python file is an additional Python file that will store our recognised codes and command lines. In the same directory as your initial sniffer.py (/home/pi/bin) create an additional file called sniffer_commands.py:

sudo nano /home/pi/bin/sniffer_commands.py

Copy the following script-code to it,

#!/usr/bin/python
# -*- coding: utf-8 -*-

code_commands = {
"1234": "sudo /home/pi/bin/test1.sh",
"4321": "sudo /home/pi/bin/test2.sh",
"911": "path to Bash or Python script here, etc.",
"102": "path to last Bash or Python script here" # note that last line does not end with a comma ","
}

exit and save (Ctrl X & y) and make it fully accessible for all:

sudo chmod 777 /home/pi/bin/sniffer_commands.py

This is the file you will edit in the future to update your signal-codes and paths. You can add as many signal codes with their respective paths as you like as long as you keep the layout the same. You can do so then by using:

sudo nano /home/pi/bin/sniffer_commands.py

Now we’re going to adapt the initial Python file, /home/pi/bin/sniffer.py to issue these commands once your specified code-signal has been received.

To open and edit your /home/pi/bin/sniffer.py file again use:

sudo nano /home/pi/bin/sniffer.py

Remove all the previous code and paste the following updated script-code to it:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sniffer_commands import code_commands # imports a path of a Bash or Python script to execute when a specific code is received //
import sys, getopt
import uuid
import os

log_file_directory = "/home/pi/logs" # don't use a '/' at the end!
log_file_name = "sniffed.txt"

def main(argv):
  opts, args = getopt.getopt(argv,"s:")
  for opt, arg in opts:
    if opt == '-s': #meaning there's valid args/codes in it
      full_log_file_name = log_file_directory + "/" + log_file_name
        with open(full_log_file_name, 'a') as outfile:
          sniffed_code = arg + "\n"
          outfile.write(sniffed_code)
        code_list = arg.split(",")
        cleaned_code_list = list((set(code_list))) #removing duplicates
        for sniffed_code in cleaned_code_list:
          #single_sniffed_code = sniffed_code + "\n"
          #with open(full_log_file_name, 'a') as outfile:
          #  outfile.write(single_sniffed_code)
          for compare_sniffed_code, elem in code_commands.items():
            if compare_sniffed_code == sniffed_code :
              code_command = code_commands[compare_sniffed_code]
              os.system(code_command)

if __name__ == "__main__":
    main(sys.argv[1:])

The additional code will take the chained signal-codes and break them into single signal-codes. It will then compare them one by one with the contents of the /sniffer_commands.py file to see if there is a recognised signal-code linked to a path. If the signal-code is recognised, it will trigger that file.

Now let’s test it!

To test whether a command line is triggered, we’ll write two little Bash scripts each containing a specific eSpeak command to test.

Now let’s create two tester Bash scripts named test1.sh and test2.sh in the same directory as specified in the sniffer_commands.py file:

sudo nano /home/pi/bin/test1.sh

Paste the following code to it,

#!/bin/bash

# This is a simple tester script to see if it is triggered.
# When triggered, you should hear "The testx.sh script file has been triggered."
# Make sure to test it separately first!

full_bash_name=`basename "$0"`

espeak "The $full_bash_name script file has been triggered."

exit and save (Ctrl X & y).

Make a copy,

sudo cp /home/pi/bin/test1.sh /home/pi/bin/test2.sh

and make both files accessible for all:

sudo chmod 777 /home/pi/bin/test1.sh
sudo chmod 777 /home/pi/bin/test2.sh

Fire up RFSniffer again and let it happen:

sudo /home/pi/433Utils/RPi_utils/RFSniffer

You should now hear eSpeak’s robot voice every time a Bash script is triggered!

Related product links

Please support Behind The Scenes by using these links to purchase these related products online from our partner websites. Links will open in a new window...

About the author
Renier busies himself with improving his English writing, creative web design and his websites, photoshopping, micro-electronics, multiple genres of music, superhero movies and badass series.
Behind the Scenes is a free, informative website. If you find value in any of our content, please consider making a donation to our cause.
Donate via PayPal

Save, share & Disqus

Use the buttons below, on the left or the bottom of this page to share this post. Your comment is important, but don't be a knob. Keep it constructive and polite.

Comment via Disqus

Disqus is a worldwide comment hosting service for web sites and online communities. This secure platform ensures a pleasant commenting environment which is manageable from one account. Use the Login button to sign up.

More Raspberry Pi related posts

Get WP Toolset – for custom WordPress development without programming
Get WP Toolset – for custom WordPress development without programming
19 August 2019
Ad: Extend the functionality of WordPress with regards to its ability to store data and publish it on your website. More…
433MHz RF communication to a Raspberry Pi
433MHz RF communication to a Raspberry Pi
27 March 2016 | Updated 1 July 2017
This post will explain how to get up and running with the 433MHz RF Transmitter Receiver modules to send radio frequency (RF) signal-codes from a transmitter device to a Raspberry Pi. More…
Mounting a shared NAS folder onto a Paspberry Pi
5 steps in mounting a shared NAS folder to a Raspberry Pi
17 September 2015 | Updated 6 April 2018
Network Attached Storage (NAS) devices are popular to add large amounts of data storage space to a network. A networked Raspberry Pi can also make use of this storage to, for example, make use of its space or to have access to its files. 5 steps in mounting a shared NAS folder to a Raspberry Pi will go through the process using NFS. More…
Categories
Raspberry Pi