Wireless Security System using APDS-9960 Gesture Sensor and 433MHz RF Transmitter-Receiver

Overview

Ever wanted a home security system wherein the alarm is far away from the main gate without having to use long wires? Perhaps somewhere inside your room where you can see the flashing light indicators and hear the buzzer even with headphones on. Using the APDS-9960 Gesture sensor along with the 433MHz RF Transmitter and Receiver Pair, this system can be achieved!

With a few tweaks on the code, this can even be turned into a monitoring system for people entering or leaving the house. There are many possibilities, limited to what you replace the actuator with.


Hardware Used

  • Arduino Uno R3 – 2

  • APDS-9960 Gesture Sensor – 1
  • 
    
  • 433MHz RF Transmitter-Receiver Pair – 1
  • 
    
  • LED – 4
  • 
    
  • Buzzer – 1
  • 
    
  • Breadboard – 2
  • 
    
  • Jumper Wires
  • 
    
    

    Software Used

    Libraries Used


    Application Description

    APDS-9960 Gesture Sensor

    The APDS-9960 Gesture Sensor module is not only capable of touchless gesture sensing, but is also capable of advanced proximity detection, ambient light sensing, and RGB color sensing. Four sensors in such a slim modular package! For this project however, we’ll only be focusing on the gesture sensing. You can check out how to use its proximity sensing feature to turn LEDs on by clicking here.

    How does it work?

    It utilizes four directional photodiodes to sense reflected IR energy to convert physical motion information (i.e. velocity, direction and distance) to a digital information. Learn more from its datasheet.

    433MHz RF Transmitter-Receiver Pair

    The 433MHz RF Transmitter and Receiver Pairis widely used because it has high volume of applications compared IR and is inexpensive. RF signals can travel from the transmitter to the receiver even when there is obstruction present, which is perfect for this project. Its range can reach up to 200 meters, which is more than enough for the project.

    How does it work?

    • Transmitter

    When the RF transmitter receives serial data, it transmits it to the receiver through an antenna. The saw resonator inside the transmitter will run and produce a constant RF output carrier wave of 433MHz when logic 1 is sent. The transmitter does not draw power when transmitting logic 0 since it fully suppresses the carrier frequency. This means that it is power efficient, as it significantly decreases power consumption. This technique is known as ASK or amplitude shift keying.

    • Receiver

    The receiver module consists of an RF tuned circuit and a couple of OP Amps to amplify the received carrier wave from the transmitter. The amplified signal is then fed to a PLL or Phase Lock Loop which allows the decoder to give better decoded output and noise immunity.

    Specifications of the Transmitter:

    Specifications of the Receiver:


    Hardware Setup

    Sensor and Transmitter

    APDS-9960 Gesture Sensor Connections

    • SDA connected to Arduino pin A4
    • SCL connected to Arduino pin A5
    • INT connected to Arduino pin D2
    • Vcc and Gnd connected to 5V and Ground respectively

    Fun Fact: SCL (Serial Clock) and SDA (Serial Data) pins are the dedicated pins for I2C communication. On the Arduino Uno they are found on Analog pins A4 and A5.

    433MHz RF Transmitter Connections

    • Data connected to Arduino pin D12
    • Vcc and Gnd connected to 5V and Ground respectively

    Receiver and Actuator

    433MHz RF Receiver Connections

    • Data connected to Arduino pin D11
    • Vcc and Gnd connected to 5V and Ground respectively

    LEDs and Buzzer Connections

    • LEDs connected to Arduino pins D10 down to D7 respectively
    • Buzzer connected to Arduino pin D6

    Code

    Transmitter code

    #include "Adafruit_APDS9960.h"
    #include <RH_ASK.h>
    #include <SPI.h>
    
    RH_ASK rf_driver;
    Adafruit_APDS9960 apds;
    
    void setup() {
      Serial.begin(300);
      rf_driver.init();
      if (!apds.begin()) {
        Serial.println("Failed to initialize Gesture Sensor! Please check your wiring.");
      }
      else
        Serial.println("Gesture Sensor initialized");
    
      if (!rf_driver.init()) {
        Serial.println("Failed to initialize 433MHz Transmitter! Please check your wiring.");
      }
      else
        Serial.println("433MHz Transmitter initialized");
    
      //gesture mode will be entered once proximity mode senses something close
      apds.enableProximity(true);
      apds.enableGesture(true);
    }
    
    void loop() {
      //read a gesture from the device
      uint8_t gesture = apds.readGesture();
    
      if (gesture == APDS9960_LEFT) {
        Serial.println("Gesture detected: LEFT SWIPE");
        const char *msg = "L";
        rf_driver.send((uint8_t *)msg, strlen(msg));
        rf_driver.waitPacketSent();
        delay(1000);
      }
      else if (gesture == APDS9960_RIGHT) {
        Serial.println("Gesture detected: RIGHT SWIPE");
        const char *msg = "R";
        rf_driver.send((uint8_t *)msg, strlen(msg));
        rf_driver.waitPacketSent();
        delay(1000);
      }
    }

    Receiver Code

    #include <RH_ASK.h>
    #include <SPI.h>
    
    RH_ASK rf_driver;
    
    void setup() {
      Serial.begin(300);
      rf_driver.init();
      pinMode(6, OUTPUT); //buzzer
      pinMode(7, OUTPUT); //LEDs
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(10, OUTPUT);
    
      if (!rf_driver.init()) {
        Serial.println("Failed to initialize 433MHz Receiver! Please check your wiring.");
      }
      else
        Serial.println("433MHz Receiver initialized");
    }
    
    void loop() {
      uint8_t buf[1];
      uint8_t buflen = sizeof(buf);
      // Check if received packet is correct size
      if (rf_driver.recv(buf, &buflen)) {
        if(!strcmp((char*)buf, "L")) { //gesture == APDS9960_LEFT
          Serial.println("Gesture detected: LEFT SWIPE");
          digitalWrite(6, HIGH); //buzzer
          digitalWrite(7, HIGH);
          delay(50);
          digitalWrite(7, LOW);
          digitalWrite(8, HIGH);
          delay(50);
          digitalWrite(8, LOW);
          digitalWrite(9, HIGH);
          delay(50);
          digitalWrite(9, LOW);
          digitalWrite(10, HIGH);
          delay(50);
          digitalWrite(10, LOW);
          digitalWrite(6, LOW); //buzzer
          delay(200);
          digitalWrite(6, HIGH); //buzzer
          delay(200);
          digitalWrite(6, LOW); //buzzer
          delay(200);
          digitalWrite(6, HIGH); //buzzer
          delay(200);
          digitalWrite(6, LOW); //buzzer
          delay(200);
          digitalWrite(6, HIGH); //buzzer
          delay(200);
          digitalWrite(6, LOW); //buzzer
        }
        else if(!strcmp((char*)buf, "R")) { //gesture == APDS9960_RIGHT
          Serial.println("Gesture detected: RIGHT SWIPE");
          digitalWrite(10, HIGH);
          delay(50);
          digitalWrite(10, LOW);
          digitalWrite(9, HIGH);
          delay(50);
          digitalWrite(9, LOW);
          digitalWrite(8, HIGH);
          delay(50);
          digitalWrite(8, LOW);
          digitalWrite(7, HIGH);
          delay(50);
          digitalWrite(7, LOW);
        }
          // Message received with valid checksum
          //Serial.print("Message Received: ");
          //Serial.println((char*)buf);         
      }
    }

    Code Breakdown

    Transmitter

    Pre-Initialization

    #include "Adafruit_APDS9960.h"
    #include <RH_ASK.h>
    #include <SPI.h>
    
    RH_ASK rf_driver;
    Adafruit_APDS9960 apds;

    First things first, we must include the libraries to be used in the project. The Adafruit_APDS9960 library will allow the Gesture Sensor to work. The RH_ASK library is from the RadioHead packet radio library for embedded processors that uses ASK or amplitude shift keying to send and receive data. This, along with the SPI (Serial Peripheral Interface) library which it is dependent on, will allow the RF Transmitter to work. The ASK object and APDS-9960 object is then created.

    void setup()

    Serial.begin(300);
    rf_driver.init();
    if (!apds.begin()) {
      Serial.println("Failed to initialize Gesture Sensor! Please check your wiring.");
    }
    else
      Serial.println("Gesture Sensor initialized");
    
    if (!rf_driver.init()) {
      Serial.println("Failed to initialize 433MHz Transmitter! Please check your wiring.");
    }
    else
      Serial.println("433MHz Transmitter initialized");

    Inside the setup() function, we set the serial baud rate to 300 bps since tiny RF modules best works on low baud rates. At high baud rates, the chance of data loss during propagating through air is much higher. Following that, the if-else statements will print a message in the Arduino serial to let the user know if the gesture sensor and the RF transmitter has been initialized successfully or not.

    apds.enableProximity(true);
    apds.enableGesture(true);

    The last two lines inside the setup() function will enable the proximity sensor and gesture sensor. Once proximity mode senses something close, the gesture mode will be entered.

    void loop()

    //read a gesture from the device
    uint8_t gesture = apds.readGesture();
    
    if (gesture == APDS9960_LEFT) {
      Serial.println("Gesture detected: LEFT SWIPE");
      const char *msg = "L";
      rf_driver.send((uint8_t *)msg, strlen(msg));
      rf_driver.waitPacketSent();
      delay(1000);
    }
    else if (gesture == APDS9960_RIGHT) {
      Serial.println("Gesture detected: RIGHT SWIPE");
      const char *msg = "R";
      rf_driver.send((uint8_t *)msg, strlen(msg));
      rf_driver.waitPacketSent();
      delay(1000);
    }

    Inside the loop() function, we try to constantly get a reading from the gesture sensor and store that value in an uint8_t datatype – an unsigned integer that is 8 bits in length, to minimize memory usage. A simple text string is then declared and stored in a character pointer named msg. For this, only one character is used to allow better overall performance, but it does not necessarily have to be one character only. Keep in mind the number of characters in the message, as the count will be needed in the receiver code later on.

    When the sensor reads a left swipe gesture, the message “L” will be transmitted using the send() function and if it reads a right swipe gesture, the message “R” will be transmitted instead. The send() function has two parameters – first is the array of data and second is number of bytes to be sent. This is then followed by the waitPacketSent() function which waits until the previous packet is finished being transmitted. After that, a delay of one second is set to give the receiver time to take in the data.

    Receiver

    Pre-Initialization

    #include <RH_ASK.h>
    #include <SPI.h>
    
    RH_ASK rf_driver;

    Similar to the transmitter side of the code, we must include the libraries to be used in the project. The RH_ASK library is from the RadioHead packet radio library for embedded processors that uses ASK or amplitude shift keying to send and receive data. This, along with the SPI (Serial Peripheral Interface) library which it is dependent on, will allow the RF Transmitter to work. The ASK object is then created.

    void setup()

    Serial.begin(300);
      rf_driver.init();
      pinMode(6, OUTPUT); //buzzer
      pinMode(7, OUTPUT); //LEDs
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(10, OUTPUT);
    
      if (!rf_driver.init()) {
        Serial.println("Failed to initialize 433MHz Receiver! Please check your wiring.");
      }
      else
        Serial.println("433MHz Receiver initialized");

    Inside the setup() function, we set the serial baud rate to 300 bps to match the baud rate of the transmitter. Then, we assign the LEDs and buzzer to their respective pins. Following that, the if-else statements will print a message in the Arduino serial to let the user know if the RF receiver has been initialized successfully or not.

    void loop()

    uint8_t buf[1];
    uint8_t buflen = sizeof(buf);

    Inside the loop() function, we create a buffer of size same as the transmitted message. In this case, it’s only one character.

    if (rf_driver.recv(buf, &amp;buflen)) {
      if(!strcmp((char*)buf, "L")) { //gesture == APDS9960_LEFT
        Serial.println("Gesture detected: LEFT SWIPE");
        digitalWrite(6, HIGH); //buzzer
        digitalWrite(7, HIGH);
        delay(50);
        digitalWrite(7, LOW);
        digitalWrite(8, HIGH);
        delay(50);
        digitalWrite(8, LOW);
        digitalWrite(9, HIGH);
        delay(50);
        digitalWrite(9, LOW);
        digitalWrite(10, HIGH);
        delay(50);
        digitalWrite(10, LOW);
        digitalWrite(6, LOW); //buzzer
        delay(200);
        digitalWrite(6, HIGH); //buzzer
        delay(200);
        digitalWrite(6, LOW); //buzzer
        delay(200);
        digitalWrite(6, HIGH); //buzzer
        delay(200);
        digitalWrite(6, LOW); //buzzer
        delay(200);
        digitalWrite(6, HIGH); //buzzer
        delay(200);
        digitalWrite(6, LOW); //buzzer
      }
      else if(!strcmp((char*)buf, "R")) { //gesture == APDS9960_RIGHT
        Serial.println("Gesture detected: RIGHT SWIPE");
        digitalWrite(10, HIGH);
        delay(50);
        digitalWrite(10, LOW);
        digitalWrite(9, HIGH);
        delay(50);
        digitalWrite(9, LOW);
        digitalWrite(8, HIGH);
        delay(50);
        digitalWrite(8, LOW);
        digitalWrite(7, HIGH);
        delay(50);
        digitalWrite(7, LOW);
      }
        // Message received with valid checksum
        //Serial.print("Message Received: ");
        //Serial.println((char*)buf);         
    }

    Next, we call a recv() function to turn the receiver on. If there is a valid message available, it copies the message to its first parameter buffer and returns true, otherwise it returns false. If the function returns true, the sketch enters into the nested if statement.

    In the nested if statement, strcmp() is used to compared the received string. It will output a 0 if the strings are equal, which is why the ! or NOT is necessary to turn it into a 1. If the message “L” is received, it signifies a left swipe and sweeps the LEDs from right to left, as well as turn the buzzer on and off with a short delay to simulate beeping. If the message “R” is received, it signifies a right swipe and sweeps the LEDs from left tor right. I did not include the buzzer beeping for the right swipe so it only alters the users when someone enters the house.


    Conclusion

    Wireless communication is always fun to experiment with. There are tons of possibilities that can be brought about using these modules, especially with regards to ease of access and convenience for the user. The 433MHz RF Transmitter-Receiver Pair is interesting because it uses ASK or amplitude shift keying to transmit and receive data and is commonly used in wireless security systems, car alarm systems, remote controls, and sensor reporting.


    References

    The post Wireless Security System using APDS-9960 Gesture Sensor and 433MHz RF Transmitter-Receiver appeared first on CreateLabz.

    433mhzAmplitude shift keyingApds-9960ArduinoAskGesture sensorKnowledgebaseReceiverRfSecurityTransmitterTx-rxWireless

    Leave a comment

    All comments are moderated before being published