Contents

Introduction

This example will show how to create a simple, yet sensitive motion detector using a photoresistor and an Arduino controlled by the MATLAB Support Package for Arduino Hardware. A photoresistor is a variable resistor that responds to the intensity of incident light, so the motion detector will be sensitive to motion that causes lighting changes for the photoresistor.

A program written in MATLAB will use commands from the support package to read in analog voltages from an Arduino pin. As voltage readings are collected in MATLAB, they are associated with a timestamp to maintain a comprehensive record. The combined voltage and time data is then plotted and analyzed in real-time to determine if motion is detected. The code presented here utilizes a combination of algorithms to detect motion, but there are numerous other machine learning and data analysis algorithms that could be applied.

While the motion detector is running, the MATLAB program stores each voltage reading along with a corresponding timestamp. This allows the user to process a complete set of data in MATLAB after the recording is finished. This article shares the results of several post-recording motion detection and analysis algorithms that are provided in the analysis code.

Required Hardware

Task 1 - Connect the Arduino to MATLAB

To connect the Arduino to MATLAB, you need to install the MATLAB Support Package for Arduino Hardware. This support package is available for MATLAB releases R2014b and higher and can be accessed using the Support Package Installer. This installer can be opened from the MATLAB Toolstrip under Add-Ons -> Get Hardware Support Packages or by running supportPackageInstaller in the Command Window. Once you have the support package installed, follow the steps below to connect to your Arduino.

  1. Plug the Arduino into your computer using the USB cable.
  2. In MATLAB, initialize an Arduino object.
% Inputs: Port ID (from your computer), Arduino board type
myArduino = arduino('COM6','Uno');

Task 2 - Test your MATLAB-Arduino Connection

Most Arduino or Arduino clone boards have a built-in LED on pin 13. If your board includes an LED, you can test your Arduino connection by turning that LED on and off. If your board does not have a built-in LED, you can easily connect one in series with a resistor between a digital pin (13 for example) and the GND pin (see circuit diagram below). The resistor value required will change depending on what color the LED is, but for the basic red and yellow LEDs a 330 Ohm resistor should be appropriate. Once you have an LED connected, execute the code below to blink the LED five times.

myArduino.configureDigitalPin(13,'Output'); % set pin 13 to Output
for blink = 1:5
    myArduino.writeDigitalPin(13,1); % turn LED on
    pause(1); % pause for 1 second
    myArduino.writeDigitalPin(13,0); % turn LED off
    pause(1); % pause for 1 second
end

Task 3 - Make the Circuit

Note that like normal resistors, the photoresistor has no orientation – we don’t have to worry about which way current flows through it. We’ll be creating a simple voltage divider with our photoresistor.

  1. Using the breadboard, connect the photoresistor and a 10 kOhm resistor in series.
  2. Connect the free side of the 10 kOhm resistor to a GND (ground) pin on the Arduino.
  3. Connect free side of the photoresistor to the 5V (5 Volts) pin on the Arduino.
  4. To allow us to monitor the voltage between the photoresistor and the 10 kOhm resistor, connect this point in the circuit to an analog input on the Arduino using a wire. This will act as a potentiometer.

Task 4 – Test your Circuit and Photoresistor

The next step is to test the circuit you’ve made to ensure that the photoresistor is responding correctly to changing light conditions. The script below shows how to configure the Arduino and retrieve voltage readings from the photoresistor on an analog pin. Try covering the photoresistor or turning on/off the lights while the script is running to see how the photoresistor responds. Note if you run this MATLAB file with your own hardware setup, you will get your own unique data and it will be different from the next 2 plots shown in the published html version of this example. The published version is based on data we collected and used for the data analysis in the sections below.

% Configure Arduino
PHOTORESISTOR_PIN_NUMBER = 0;
myArduino.configureAnalogPin(PHOTORESISTOR_PIN_NUMBER,'Input');

% Initialize Variables
readings = 750; % this should take 20-30 seconds
times = zeros(readings,1);
analogVoltageIn = zeros(readings,1);

% Initialize a Figure and Axes
figure;
hold on;
ylim([0,5]);
title('Analog Voltage vs. Time');
ylabel('Analog Voltage (Volts)');
xlabel('Time (seconds)');
scatterPlot = scatter(NaN(readings,1),NaN(readings,1),200,'.k');

% Record and Display the Analog Voltage Readings in Real-Time
tic;
for r = 1:readings
    times(r) = toc;
    analogVoltageIn(r) = myArduino.readVoltage(PHOTORESISTOR_PIN_NUMBER);
    scatterPlot.XData(r) = times(r);
    scatterPlot.YData(r) = analogVoltageIn(r);
end

Photoresistor Theory

A photoresistor is a variable resistor that responds to the intensity of incident light. The brighter the light is, the less resistance the photoresistor provides. A simple voltage divider circuit where the photoresistor is in series with a constant-valued resistor will effectively convert changes in resistance to measureable changes in voltage. MATLAB is used to read in these voltages from an analog pin on the Arduino. As voltages are recorded by MATLAB, a program can correlate each voltage to a corresponding light level. Even simple photoresistors can be very sensitive, providing the full range of voltages (0-5V) for the Arduino’s analog pin to read in. MATLAB will read in these voltages rounded to the nearest 0.0049 volts because the analog signal is converted into a 10-bit digital signal.

$$\frac{5Volts}{2^{10Bits}} = 0.0049Volts $$

Task 5 - Calibrate Your Motion Detection Algorithm

Because the photoresistor has a high sensitivity, the motion detecting algorithms will require calibration depending the surrounding lighting conditions and how the motion detector is being used. The program's lighting level descriptors will also need to be adjusted based upon how sensitive you want this functionality to be.

The provided motion detector MATLAB code (Run_Motion_Detector.m) applies three types of calculations in real-time to determine if the current voltage reading signifies motion. Each calculation is a simple way to quantify a different type of variability within a small window of data. The calculations are each compared to a corresponding threshold variable to determine if the variability indicates motion. If any of the calculations exceeds its corresponding threshold variable, the current voltage reading is designated as showing motion. The threshold variables are directly related to the sensitivity of the motion detector and should be calibrated for each particular situation.

Here are descriptions for each method:

For a descriptive analysis of the lighting conditions, the getLightingCondition function qualitatively describes the light intensity at each voltage reading. This function should be calibrated and extended to appropriately describe the light levels at the location of your motion detector.

% Input: Arduino object, recording time (seconds)
Run_Motion_Detector(myArduino,30);

Task 6 - Post-Recording Data Analysis

Many motion detectors are only designed to detect motion in real-time because they are automating a particular task. This is a very common type of motion detector, seen in approach-activated doors at airports and grocery stores or motion-activated light switches in office buildings. Using MATLAB, the motion detector built in this example can not only detect motion in real-time, it can additionally record and compile the sensor readings over an entire recording session.

The Run_Motion_Detector function automatically saves the unprocessed analog voltages and timestamps to the base MATLAB workspace as the variables analogVoltage and sensorTime. Once saved in MATLAB, this data can be passed to the Analyze_Motion_Detector_Data function to implement and compare various motion detection algorithms. The figure below shows the results of the three motion detection algorithms as applied to the complete dataset. The red data markers are characterized as motion by all three methods. It is useful to see that some motion is only detected by the Slope Method (shown with green markers), while other motion is only detected by the Standard Deviation and/or Difference Methods (shown with cyan markers). By using a combination of these three methods to determine motion, the MATLAB motion detector can generate a comprehensive record of motion.

load('RealTime Method Comparison Data');
Analyze_Motion_Detector_Data(sensorTime,analogVoltage);
ylim([3,4.5]);

Task 7 - Motion Categorization

Using MATLAB for the data processing, it is easy to isolate motion events and characterize each one with several calculated parameters. Some simple parameters that can be calculated include:

The Categorize_Motion_Events function calculates these four parameters for each motion event and uses them to qualitatively describe the recorded motion. The descriptions are used to create useful labels on the voltage plot. The motion labels consist of three text characters and are positioned above the motion event they describe. The first character is a plus, minus, or equals sign indicating whether the intensity of the lighting increased (+), decreased (-), or stayed constant (=) around the motion event. The next character is a letter that refers to a specific type of motion. The motion types with corresponding letters are listed below. The third character (if specified) indicates how the average lighting during each motion event is related to the prior and following light intensities, using the same plus, minus, and equals sign identifiers as the first character.

If you are monitoring very specific types of motion, you can tighten the constraints to get more accurate categorization, or use machine learning techniques in MATLAB to program an automatically adjusting motion detector.

load('Sample Motion Categorization Data');
Categorize_Motion_Events(categorizationTime,categorizationVoltage);

Application: Hallway Activity Monitor

Because our motion detector is sensitive to changes in light, it will work best when the motion you want to capture corresponds with a sharp increase or sharp decrease in the lighting conditions. One scenario that works well to detect people is pointing the motion detector across a hallway at a well-lit wall or light source. When people walk down the hallway, there will be a sharp decrease in voltage as their shadow passes over the photoresistor.

The plot below is representative of data you might collect from a hallway motion detection monitor. The motion events are categorized using a version of the Categorize_Motion_Events function that was specifically modified to analyze hallway data. The motion events categorized as only changes in lighting (M or L) can be discarded as they most likely do not indicate people passing through the hallway. This leaves nine events that seem to indicate people. Further analysis could be done to calculate the speed of the person walking or how many people were in a group by looking at the length of the motion event.

load('Sample Hallway Motion Detector Data');
Categorize_Hallway_Events(hallwayTime,hallwayVoltage);