This program shows how to use the VCNL4010 (proximity and ambient light sensor) on the QW dev kit for motion detection. When motion is detected, a message is shown in the console window and transmitted via Sigfox.

Dependencies:   QW_Sensors mbed

Fork of QW-Motiondetection by Quicksand

QW Motion Detection

This program shows how to use the VCNL4010 (proximity and ambient light sensor) on the QW dev kit for motion detection. When motion is detected, a message is shown in the console window and transmitted via Sigfox.

Code explanation

The program starts with the initialisation/declaration of the leds, pushbuttons and sensor. Also the necessary function prototypes and serial communications are declared. After the initialisation phase, the sensor ID is read and the IR-led current is set. After that, the program enters an infinite loop. Each loop the proximity value is read. When a certain threshold is passed, a led is turned on to indicate motion detection, a message is shown in the console window and a Sigfox message is transmitted. When the Sigfox message is transmitted, the loop continuous.

Sigfox message payload

First there is the "03", this is the Quicksand ID of the example program. This is used by Quicksand to keep track of our example programs. The second value that is transmitted is the proximity value the moment when motion was detected.

More information and other example code can be found on the component page by clicking the link below: https://developer.mbed.org/components/QW-SIGFOX-Development-Kit/

main.cpp

Committer:
quicksandjonas
Date:
21 months ago
Revision:
0:88ff4115c392

File content as of revision 0:88ff4115c392:

/* This program demonstrates how to use the VCNL4010 for motion detection.
 * Open a serial console to the board to see extra info.
 */

#include "mbed.h"
#include "VCNL4010.h"

#define SER_BUFFER_SIZE 32

/* The 4 onboard LEDs */
DigitalOut LED_0 (PB_6);
DigitalOut LED_1 (PA_7);
DigitalOut LED_2 (PA_6);
DigitalOut LED_3 (PA_5);

/* The 2 user buttons */
InterruptIn SW1(PA_8);
InterruptIn SW2(PB_10);

/* Proximity and ambient light sensor*/
VCNL40x0 VCNL4010(PB_9, PB_8, VCNL40x0_ADDRESS);      // SDA, SCL pin and I2C address

/* Function prototypes */
void sw1interrupt();
void sw2interrupt();
void sertmout();
bool modem_command_check_ok(char * command);
void modem_setup();

bool ser_timeout = false;

/* Serial port over USB */
Serial pc(USBTX, USBRX);

/* Serial connection to sigfox modem */
Serial modem(PA_9, PA_10);

int main()
{
    /* Storage for VCNL4010 readout */
    unsigned char ID=0, Current=0;
    unsigned int  ProxiValue=0;    

    /* Setup TD120x */
    wait(3);
    modem_setup();

    /* Turn off all LED */
    LED_0 = 1;
    LED_1 = 1;
    LED_2 = 1;
    LED_3 = 1;

    /* Setup button interrupts */    
    SW1.fall(&sw1interrupt);
    SW2.fall(&sw2interrupt);
    

    /* Read VCNL40x0 product ID revision register */
    VCNL4010.ReadID (&ID);
    pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID);

    VCNL4010.SetCurrent (20);                        // Set current to 200mA
    VCNL4010.ReadCurrent (&Current);                 // Read back IR LED current
    pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current);

    wait_ms(3000);                                   // Wait 3s (only for display)

    while(1) 
    {
        /* VCNL4010 reading */
        VCNL4010.ReadProxiOnDemand (&ProxiValue);    // read prox value on demand        
        
        /* If motion is detected, do a sigfox transmission */
        if (ProxiValue > 2500){                     // threshold can be changed to personal preference (determines the maximum distance from sensor for detection)
            LED_0 = 0;                              // turn on LED_0 to indicate motion detection and Sigfox transmission
            pc.printf("\rMotion detected!\n");
            char command[SER_BUFFER_SIZE];
            sprintf(command, "AT$SF=03%04x,2,0\n", (int) ProxiValue );
            pc.printf("Sending proximity value %5.0i over Sigfox using modem command: %s\n", ProxiValue , command);
            //pc.printf("using modem command: %s", command);
            modem_command_check_ok(command);
            LED_0 = 1;                              // turn off LED_0
        }
                
        wait_ms(100);
    }
}

void modem_setup()
{
    /* Reset to factory defaults */
    if(modem_command_check_ok("AT&F")) 
    {
        pc.printf("Factory reset succesfull\r\n");
    }
    else 
    {
        pc.printf("Factory reset TD120x failed\r\n");
    }
    /* Disable local echo */
    modem.printf("ATE0\n");
    if(modem_command_check_ok("ATE0")) 
    {
        pc.printf("Local echo disabled\r\n");
    }
    /* Write to mem */
    if(modem_command_check_ok("AT&W")) 
    {
        pc.printf("Settings saved!\r\n");
    }    
}

bool modem_command_check_ok(char * command)
{
    /* first clear serial data buffers */
    while(modem.readable()) modem.getc();
    /* Timeout for response of the modem */
    Timeout tmout;
    ser_timeout = false;
    /* Buffer for incoming data */
    char responsebuffer[6];
    /* Flag to set when we get 'OK' response */
    bool ok = false;
    bool error = false;
    /* Print command to TD120x */
    modem.printf(command);
    /* Newline to activate command */
    modem.printf("\n");
    /* Wait untill serial feedback, min 7 seconds before timeout */
    tmout.attach(&sertmout, 7.0);
    while(!modem.readable()&& ser_timeout == false);
    while(!ok && !ser_timeout && !error) 
    {
        if(modem.readable()) 
        {
            for(int i = 0; i < 5; i++)
            {
                responsebuffer[i] = responsebuffer[i+1];
            }
            responsebuffer[5] = modem.getc();
            if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' ) 
            {
                ok = true;
            }
            else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' ) 
            {
                error = true;
            }
        }
    }
    tmout.detach();
    return ok;
}

/* Button 1 ISR */
void sw1interrupt()
{
    pc.printf("\n\rButton 1 pressed\n\r");
}

/* Button 2 ISR */
void sw2interrupt()
{
    pc.printf("\n\rButton 2 pressed\n\r");
}

/* ISR for serial timeout */
void sertmout()
{
    ser_timeout = true;
}