This program shows how to use the VCNL4010 (proximity and ambient light sensor) on the QW dev kit for detecting an open closet door. When the closet is open, a message will be displayed in the console window and a Sigfox message will be send.
Fork of QW-Closet-detection by
QW Closet Detection
This program shows how to use the VCNL4010 (proximity and ambient light sensor) on the QW dev kit for detecting an open closet door. When the closet is open, a message will be displayed in the console window and a Sigfox message will be send.
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. After that, the program is waiting for a push on one of the buttons to calibrate the "device". Once calibrated, the program enters an infinite loop. Each loop the ambient light value is read. When a certain threshold is passed, a led is turned on to indicate an open closet, 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 "05", 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 ambient light value the moment when an open closet 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@1:95286e4370e7, 2016-12-15 (annotated)
- Committer:
- quicksandjonas
- Date:
- Thu Dec 15 10:10:30 2016 +0000
- Revision:
- 1:95286e4370e7
- Parent:
- 0:6c17d1a79f75
Code optimisation + comment
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
quicksandjonas | 1:95286e4370e7 | 1 | /* This program demonstrates how to use the VCNL4010 for detecting an open closet door. |
quicksandjonas | 1:95286e4370e7 | 2 | * Open a serial console to the board to see extra info. |
quicksandjonas | 1:95286e4370e7 | 3 | */ |
quicksandjonas | 1:95286e4370e7 | 4 | |
quicksand | 0:6c17d1a79f75 | 5 | #include "mbed.h" |
quicksand | 0:6c17d1a79f75 | 6 | #include "VCNL4010.h" |
quicksand | 0:6c17d1a79f75 | 7 | |
quicksandjonas | 1:95286e4370e7 | 8 | #define SER_BUFFER_SIZE 32 |
quicksandjonas | 1:95286e4370e7 | 9 | |
quicksandjonas | 1:95286e4370e7 | 10 | /* The 4 onboard LEDs */ |
quicksand | 0:6c17d1a79f75 | 11 | DigitalOut LED_0 (PB_6); |
quicksand | 0:6c17d1a79f75 | 12 | DigitalOut LED_1 (PA_7); |
quicksand | 0:6c17d1a79f75 | 13 | DigitalOut LED_2 (PA_6); |
quicksand | 0:6c17d1a79f75 | 14 | DigitalOut LED_3 (PA_5); |
quicksandjonas | 1:95286e4370e7 | 15 | |
quicksandjonas | 1:95286e4370e7 | 16 | /* The 2 user buttons */ |
quicksandjonas | 1:95286e4370e7 | 17 | InterruptIn SW1(PA_8); |
quicksandjonas | 1:95286e4370e7 | 18 | InterruptIn SW2(PB_10); |
quicksandjonas | 1:95286e4370e7 | 19 | |
quicksandjonas | 1:95286e4370e7 | 20 | /* Proximity and ambient light sensor*/ |
quicksandjonas | 1:95286e4370e7 | 21 | VCNL40x0 VCNL4010(PB_9, PB_8, VCNL40x0_ADDRESS); // SDA, SCL pin and I2C address |
quicksandjonas | 1:95286e4370e7 | 22 | |
quicksandjonas | 1:95286e4370e7 | 23 | /* Function prototypes */ |
quicksandjonas | 1:95286e4370e7 | 24 | void sw1interrupt(); |
quicksandjonas | 1:95286e4370e7 | 25 | void sw2interrupt(); |
quicksandjonas | 1:95286e4370e7 | 26 | void sertmout(); |
quicksandjonas | 1:95286e4370e7 | 27 | bool modem_command_check_ok(char * command); |
quicksandjonas | 1:95286e4370e7 | 28 | void modem_setup(); |
quicksandjonas | 1:95286e4370e7 | 29 | |
quicksandjonas | 1:95286e4370e7 | 30 | bool ser_timeout = false; |
quicksandjonas | 1:95286e4370e7 | 31 | |
quicksandjonas | 1:95286e4370e7 | 32 | /* Serial port over USB */ |
quicksand | 0:6c17d1a79f75 | 33 | Serial pc(USBTX, USBRX); |
quicksandjonas | 1:95286e4370e7 | 34 | |
quicksandjonas | 1:95286e4370e7 | 35 | /* Serial connection to sigfox modem */ |
quicksand | 0:6c17d1a79f75 | 36 | Serial modem(PA_9, PA_10); |
quicksand | 0:6c17d1a79f75 | 37 | |
quicksandjonas | 1:95286e4370e7 | 38 | |
quicksandjonas | 1:95286e4370e7 | 39 | bool indoor = false; |
quicksandjonas | 1:95286e4370e7 | 40 | int indoorLight; |
quicksand | 0:6c17d1a79f75 | 41 | |
quicksand | 0:6c17d1a79f75 | 42 | |
quicksand | 0:6c17d1a79f75 | 43 | int main() { |
quicksand | 0:6c17d1a79f75 | 44 | |
quicksandjonas | 1:95286e4370e7 | 45 | unsigned char ID=0; |
quicksandjonas | 1:95286e4370e7 | 46 | unsigned int AmbiValue=0; |
quicksandjonas | 1:95286e4370e7 | 47 | |
quicksandjonas | 1:95286e4370e7 | 48 | /* Setup TD120x */ |
quicksandjonas | 1:95286e4370e7 | 49 | wait(3); |
quicksandjonas | 1:95286e4370e7 | 50 | modem_setup(); |
quicksandjonas | 1:95286e4370e7 | 51 | |
quicksandjonas | 1:95286e4370e7 | 52 | /* Turn off all LED */ |
quicksand | 0:6c17d1a79f75 | 53 | LED_0 = 1; |
quicksand | 0:6c17d1a79f75 | 54 | LED_1 = 1; |
quicksand | 0:6c17d1a79f75 | 55 | LED_2 = 1; |
quicksand | 0:6c17d1a79f75 | 56 | LED_3 = 1; |
quicksandjonas | 1:95286e4370e7 | 57 | |
quicksandjonas | 1:95286e4370e7 | 58 | /* Setup button interrupts */ |
quicksandjonas | 1:95286e4370e7 | 59 | SW1.fall(&sw1interrupt); |
quicksandjonas | 1:95286e4370e7 | 60 | SW2.fall(&sw2interrupt); |
quicksand | 0:6c17d1a79f75 | 61 | |
quicksandjonas | 1:95286e4370e7 | 62 | /* Read VCNL40x0 product ID revision register */ |
quicksandjonas | 1:95286e4370e7 | 63 | VCNL4010.ReadID (&ID); |
quicksandjonas | 1:95286e4370e7 | 64 | pc.printf("\n\nProduct ID Revision Register: %d", ID); |
quicksandjonas | 1:95286e4370e7 | 65 | |
quicksandjonas | 1:95286e4370e7 | 66 | wait_ms(3000); //Wait 3s (only for display) |
quicksand | 0:6c17d1a79f75 | 67 | |
quicksandjonas | 1:95286e4370e7 | 68 | /* Calibrate the system by measuring the indoor light */ |
quicksandjonas | 1:95286e4370e7 | 69 | while(indoor != true){ |
quicksandjonas | 1:95286e4370e7 | 70 | LED_3 = 0; |
quicksandjonas | 1:95286e4370e7 | 71 | wait_ms(500); |
quicksandjonas | 1:95286e4370e7 | 72 | LED_3 = 1; |
quicksandjonas | 1:95286e4370e7 | 73 | wait_ms(500); |
quicksandjonas | 1:95286e4370e7 | 74 | } |
quicksandjonas | 1:95286e4370e7 | 75 | VCNL4010.ReadAmbiOnDemand (&AmbiValue); //Read ambi value on demand |
quicksandjonas | 1:95286e4370e7 | 76 | indoorLight = AmbiValue; |
quicksandjonas | 1:95286e4370e7 | 77 | pc.printf("\rIndoor light value is: %5.0i\n", indoorLight); |
quicksand | 0:6c17d1a79f75 | 78 | |
quicksand | 0:6c17d1a79f75 | 79 | while(1) { |
quicksandjonas | 1:95286e4370e7 | 80 | VCNL4010.ReadAmbiOnDemand (&AmbiValue); //Read ambi value on demand |
quicksandjonas | 1:95286e4370e7 | 81 | |
quicksandjonas | 1:95286e4370e7 | 82 | if(AmbiValue > (indoorLight+50)){ |
quicksandjonas | 1:95286e4370e7 | 83 | LED_0 = 0; //Turn on LED_0 to indicate open closet and Sigfox transmission |
quicksandjonas | 1:95286e4370e7 | 84 | pc.printf("\rCloset door has been opened!\n"); |
quicksandjonas | 1:95286e4370e7 | 85 | char command[SER_BUFFER_SIZE]; |
quicksandjonas | 1:95286e4370e7 | 86 | sprintf(command, "AT$SF=05%04x,2,0\n", (int) AmbiValue ); |
quicksandjonas | 1:95286e4370e7 | 87 | pc.printf("Sending ambient value %5.0i over Sigfox using modem command: %s\n", AmbiValue , command); |
quicksandjonas | 1:95286e4370e7 | 88 | modem_command_check_ok(command); |
quicksandjonas | 1:95286e4370e7 | 89 | LED_0 = 1; //Turn off LED_0 |
quicksandjonas | 1:95286e4370e7 | 90 | wait_ms(5000); //Wait 5 seconds before checking again |
quicksandjonas | 1:95286e4370e7 | 91 | } |
quicksandjonas | 1:95286e4370e7 | 92 | } |
quicksandjonas | 1:95286e4370e7 | 93 | } |
quicksandjonas | 1:95286e4370e7 | 94 | |
quicksandjonas | 1:95286e4370e7 | 95 | void modem_setup() |
quicksandjonas | 1:95286e4370e7 | 96 | { |
quicksandjonas | 1:95286e4370e7 | 97 | /* Reset to factory defaults */ |
quicksandjonas | 1:95286e4370e7 | 98 | if(modem_command_check_ok("AT&F")) |
quicksandjonas | 1:95286e4370e7 | 99 | { |
quicksandjonas | 1:95286e4370e7 | 100 | pc.printf("Factory reset succesfull\r\n"); |
quicksandjonas | 1:95286e4370e7 | 101 | } |
quicksandjonas | 1:95286e4370e7 | 102 | else |
quicksandjonas | 1:95286e4370e7 | 103 | { |
quicksandjonas | 1:95286e4370e7 | 104 | pc.printf("Factory reset TD120x failed\r\n"); |
quicksandjonas | 1:95286e4370e7 | 105 | } |
quicksandjonas | 1:95286e4370e7 | 106 | /* Disable local echo */ |
quicksandjonas | 1:95286e4370e7 | 107 | modem.printf("ATE0\n"); |
quicksandjonas | 1:95286e4370e7 | 108 | if(modem_command_check_ok("ATE0")) |
quicksandjonas | 1:95286e4370e7 | 109 | { |
quicksandjonas | 1:95286e4370e7 | 110 | pc.printf("Local echo disabled\r\n"); |
quicksand | 0:6c17d1a79f75 | 111 | } |
quicksandjonas | 1:95286e4370e7 | 112 | /* Write to mem */ |
quicksandjonas | 1:95286e4370e7 | 113 | if(modem_command_check_ok("AT&W")) |
quicksandjonas | 1:95286e4370e7 | 114 | { |
quicksandjonas | 1:95286e4370e7 | 115 | pc.printf("Settings saved!\r\n"); |
quicksandjonas | 1:95286e4370e7 | 116 | } |
quicksandjonas | 1:95286e4370e7 | 117 | } |
quicksandjonas | 1:95286e4370e7 | 118 | |
quicksandjonas | 1:95286e4370e7 | 119 | bool modem_command_check_ok(char * command) |
quicksandjonas | 1:95286e4370e7 | 120 | { |
quicksandjonas | 1:95286e4370e7 | 121 | /* First clear serial data buffers */ |
quicksandjonas | 1:95286e4370e7 | 122 | while(modem.readable()) modem.getc(); |
quicksandjonas | 1:95286e4370e7 | 123 | /* Timeout for response of the modem */ |
quicksandjonas | 1:95286e4370e7 | 124 | Timeout tmout; |
quicksandjonas | 1:95286e4370e7 | 125 | ser_timeout = false; |
quicksandjonas | 1:95286e4370e7 | 126 | /* Buffer for incoming data */ |
quicksandjonas | 1:95286e4370e7 | 127 | char responsebuffer[6]; |
quicksandjonas | 1:95286e4370e7 | 128 | /* Flag to set when we get 'OK' response */ |
quicksandjonas | 1:95286e4370e7 | 129 | bool ok = false; |
quicksandjonas | 1:95286e4370e7 | 130 | bool error = false; |
quicksandjonas | 1:95286e4370e7 | 131 | /* Print command to TD120x */ |
quicksandjonas | 1:95286e4370e7 | 132 | modem.printf(command); |
quicksandjonas | 1:95286e4370e7 | 133 | /* Newline to activate command */ |
quicksandjonas | 1:95286e4370e7 | 134 | modem.printf("\n"); |
quicksandjonas | 1:95286e4370e7 | 135 | /* Wait untill serial feedback, min 7 seconds before timeout */ |
quicksandjonas | 1:95286e4370e7 | 136 | tmout.attach(&sertmout, 7.0); |
quicksandjonas | 1:95286e4370e7 | 137 | while(!modem.readable()&& ser_timeout == false); |
quicksandjonas | 1:95286e4370e7 | 138 | while(!ok && !ser_timeout && !error) |
quicksandjonas | 1:95286e4370e7 | 139 | { |
quicksandjonas | 1:95286e4370e7 | 140 | if(modem.readable()) |
quicksandjonas | 1:95286e4370e7 | 141 | { |
quicksandjonas | 1:95286e4370e7 | 142 | for(int i = 0; i < 5; i++) |
quicksandjonas | 1:95286e4370e7 | 143 | { |
quicksandjonas | 1:95286e4370e7 | 144 | responsebuffer[i] = responsebuffer[i+1]; |
quicksandjonas | 1:95286e4370e7 | 145 | } |
quicksandjonas | 1:95286e4370e7 | 146 | responsebuffer[5] = modem.getc(); |
quicksandjonas | 1:95286e4370e7 | 147 | if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' ) |
quicksandjonas | 1:95286e4370e7 | 148 | { |
quicksandjonas | 1:95286e4370e7 | 149 | ok = true; |
quicksandjonas | 1:95286e4370e7 | 150 | } |
quicksandjonas | 1:95286e4370e7 | 151 | else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' ) |
quicksandjonas | 1:95286e4370e7 | 152 | { |
quicksandjonas | 1:95286e4370e7 | 153 | error = true; |
quicksandjonas | 1:95286e4370e7 | 154 | } |
quicksandjonas | 1:95286e4370e7 | 155 | } |
quicksandjonas | 1:95286e4370e7 | 156 | } |
quicksandjonas | 1:95286e4370e7 | 157 | tmout.detach(); |
quicksandjonas | 1:95286e4370e7 | 158 | return ok; |
quicksandjonas | 1:95286e4370e7 | 159 | } |
quicksandjonas | 1:95286e4370e7 | 160 | |
quicksandjonas | 1:95286e4370e7 | 161 | /* Button 1 ISR */ |
quicksandjonas | 1:95286e4370e7 | 162 | void sw1interrupt() |
quicksandjonas | 1:95286e4370e7 | 163 | { |
quicksandjonas | 1:95286e4370e7 | 164 | pc.printf("\n\rButton 1 pressed\n\r"); |
quicksandjonas | 1:95286e4370e7 | 165 | indoor = true; |
quicksandjonas | 1:95286e4370e7 | 166 | pc.printf("\n\rIndoor light measured\n\r"); |
quicksandjonas | 1:95286e4370e7 | 167 | } |
quicksandjonas | 1:95286e4370e7 | 168 | |
quicksandjonas | 1:95286e4370e7 | 169 | /* Button 2 ISR */ |
quicksandjonas | 1:95286e4370e7 | 170 | void sw2interrupt() |
quicksandjonas | 1:95286e4370e7 | 171 | { |
quicksandjonas | 1:95286e4370e7 | 172 | pc.printf("\n\rButton 2 pressed\n\r"); |
quicksandjonas | 1:95286e4370e7 | 173 | indoor = true; |
quicksandjonas | 1:95286e4370e7 | 174 | pc.printf("\n\rIndoor light measured\n\r"); |
quicksandjonas | 1:95286e4370e7 | 175 | |
quicksandjonas | 1:95286e4370e7 | 176 | } |
quicksandjonas | 1:95286e4370e7 | 177 | |
quicksandjonas | 1:95286e4370e7 | 178 | /* ISR for serial timeout */ |
quicksandjonas | 1:95286e4370e7 | 179 | void sertmout() |
quicksandjonas | 1:95286e4370e7 | 180 | { |
quicksandjonas | 1:95286e4370e7 | 181 | ser_timeout = true; |
quicksandjonas | 1:95286e4370e7 | 182 | } |
quicksandjonas | 1:95286e4370e7 | 183 | |
quicksandjonas | 1:95286e4370e7 | 184 | |
quicksandjonas | 1:95286e4370e7 | 185 |