Movement

To detect movement, you can use PIR Motion Sensor. As in the previous example, I used a sensor from Grove. A PIR Motion Sensor is very easy to use. When there is motion, the digital pin it is connected to is set to HIGH. No motion results in a LOW value. The Grove sensor has extra jumpers to define the sensitivity of the sensor. I have not changed them from the factory default.

To connect the sensor, connect its GND and VCC pins to ground and power on your breadboard using female-male jumper wires. Connect the signal pin to a digital pin on the Photon (I used pin D3).

In our code, we will stop using the delay() statement because we want to continuously monitor movement. If you use delay(10000) and then check for movement, you only check movement exactly once every 10 seconds. Instead, we want to continuously check for movement and, if there was movement in the last interval, report it with an event using Particle.publish(). Let's have a look at how we do that in the code:

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>


#define DHTPIN 1     // what pin we're connected to
#define DHTTYPE DHT22        // DHT 22 (AM2302)
#define LIGHTPIN A0         // pin to detect light
#define MOTIONPIN D3        // pin to detect motion
#define LEDPIN D7


// Variables for humidity and temperature
double h, t;

// Variable for light
int l;

// m for continuous detection and motion for 
// detection in last 10 seconds 
int m, motion = 0;

// init DHT library
DHT dht(DHTPIN, DHTTYPE);

// used for measuring every 10 seconds instead of delay
unsigned long previousMillis = 0;
const long interval = 10000;

void setup() {
    dht.begin();

    // Setup Particle variables
    Particle.variable("temperature", t);
    Particle.variable("humidity", h);
    Particle.variable("light", l);
    Particle.variable("lMotion", m);            // last motion
    Particle.variable("iMotion", motion);       // interval motion

    // Analog pin for light intensity
    pinMode(LIGHTPIN, INPUT);

    // Digital pin for motion
    pinMode(MOTIONPIN, INPUT);

    // Onboard LED to light when there is motion
    pinMode(LEDPIN, OUTPUT);
}

void loop() {
    // get the current millis
    unsigned long currentMillis = millis();

    // get readings after interval
    if(currentMillis - previousMillis >= interval) {
        // reset the timer
        previousMillis = currentMillis;

        // Reading temperature or humidity takes about 250 milliseconds!
        // Sensor readings may also be up to 2 seconds 'old' (its a 
        // very slow sensor)
        h = dht.getHumidity();
        // Read temperature as Celsius
        t = dht.getTempCelcius();
        // Read light intensity
        l = analogRead(LIGHTPIN);

        // Check if any reads failed and exit early (to try again).
        if (isnan(h) || isnan(t)) {
            return;
        }

        // Publish to Particle
        Particle.publish("temperature", String(t), 60, PRIVATE);
        Particle.publish("humidity", String(h), 60, PRIVATE);
        Particle.publish("light", String(l), 60, PRIVATE);
        Particle.publish("motion", String(motion), 60, PRIVATE);

        // to check for motion in next interval; reset motion
        motion = false;

    }

    // Detect motion continuously; when detected set motion to true
    // to indicate motion in the interval
    m = digitalRead(MOTIONPIN);
    if (m==HIGH) {
        digitalWrite(LEDPIN, HIGH);
        motion = true;
    } else {
        digitalWrite(LEDPIN, LOW);
    }

}

First of all, for motion, we define two variables m and motion. m is used to hold the result of the continuous check for motion and the motion variable is used to report motion in the last interval.

Next, we defined the following variable and constant:

unsigned long previousMillis = 0;
const long interval = 10000;

The variable previousMillis is used to hold the milliseconds of device uptime since our last measurement. The constant interval is used to define the interval to read from our sensors which is 10 seconds in this case. Note that the uptime returned by the millis() function is an unsigned long which means there will be an overflow after about 50 days.The code we use to check if our interval passed is overflow safe.

In the loop() we first retrieve the milliseconds of device uptime at that moment. Subsequently, we check the difference between previousMillis and currentMillis and if it is more or equal then 10000, we start all our measurements besides the motion check. The motion check is done continuously, outside the interval check. When motion is detected by reading HIGH from pin D3, the motion variable is set to true. That variable is sent to the Particle Cloud. After that, the motion variable is reset to false, to check for motion in the next interval.

Choosing between delay and working with millis() will depend on your scenario. Another scenario where working with millis() makes sense is detecting a button press. We will also use the millis() approach when we connect to IoT Hub using MQTT.

Now that we have all our sensors working, we can turn to sending our four measurements in one event using JSON.

results matching ""

    No results matching ""