Arduino People Counter for Rooms
by danielterletzkiy in Circuits > Arduino
1039 Views, 2 Favorites, 0 Comments
Arduino People Counter for Rooms
So basically I made a project that counts how many people are in the room and how much people have walked in and out of a room.
I have made this project because I had the APDS-9960 already on my table and didn't really knew what to do with it jet, because of my bigger project, that I originally bought the sensor for, failed (The sensor doesn't really work with the ESP-8266).
I am still working on the project but it works like it should, except....
...the sensor has a limited range so it only detect "gestures" that are like ~3cm to ~20cm, wich is kinda sad,
so when you have, for example, a door witch is 1m wide, you really need to be on the side of the sensor or kinda walk in the middle of it.
Supplies
What you need:
Lets Get to the Fun Part
First you need the right library's
When you are wiring everything up you need to define an Interrupt Pin only, for example pin 2 on the Arduino UNO.
You can read more about Interrupts here.
#define APDS9960_INT 2 // Needs to be an interrupt pin
I have made some Icons that are already in the code. If you want to make your own Icons for OLED displays, you can check out this great Website.
Then what you need to do is go to the Code section that is marked:
//Image for [thing]
and replace the bytes with the Arduino code you got from the website.
NOTE: i have already configured all images to be 20x20 pixels, all except the "ICON" image wich is full sized(128x64 pixel).
Here is the full Code:
/*=================================================================================
Original Sketch by SparkFunHEAVILY Modified Sketch by Daniel Terletzkiy
//================================================================================= */
#include #include #include "U8glib.h"
#define APDS9960_INT 2 // Needs to be an interrupt pin
const uint8_t icon[] PROGMEM = { //Icon image for startup 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe7, 0xff, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0xff, 0xcf, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xcf, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xcf, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x8f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x9f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x9f, 0xf9, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, 0xf8, 0xdc, 0x1c, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x22, 0x22, 0x60, 0xb0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x40, 0x41, 0x00, 0x98, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x81, 0x00, 0xa4, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x80, 0x81, 0x00, 0xa6, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x7f, 0xf0, 0x40, 0x41, 0x20, 0xa2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x40, 0x43, 0x21, 0x21, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x36, 0x36, 0x1a, 0x20, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0xfe, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x01, 0xff, 0x84, 0xf9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x7f, 0x00, 0x81, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x7f, 0x00, 0x81, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0xfe, 0x00, 0xf1, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0xfe, 0x00, 0x81, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x01, 0xfc, 0x00, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x01, 0xfc, 0x00, 0x81, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const uint8_t left_arrow[] PROGMEM = { //Image for Left arrow 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x1e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t right_arrow[] PROGMEM = { //Image for Right arrow 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x80, 0x1f, 0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t cross[] PROGMEM = { //Image for the "X" 0xc0, 0x00, 0x30, 0xe0, 0x00, 0x70, 0x70, 0x00, 0xe0, 0x38, 0x01, 0xc0, 0x1c, 0x03, 0x80, 0x0e, 0x07, 0x00, 0x07, 0x0e, 0x00, 0x03, 0x9c, 0x00, 0x01, 0xf8, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x01, 0xf8, 0x00, 0x03, 0x9c, 0x00, 0x07, 0x0e, 0x00, 0x0e, 0x07, 0x00, 0x1c, 0x03, 0x80, 0x38, 0x01, 0xc0, 0x70, 0x00, 0xe0, 0xe0, 0x00, 0x70, 0xc0, 0x00, 0x30};
// Global Variables U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); //Search in the Internet for wich model you use! SparkFun_APDS9960 apds = SparkFun_APDS9960(); int isr_flag = 0;
int int_room; int out_room; int people_room = 1;
int in_or_out;
void interruptRoutine(); void handleGesture();
void startupdraw() //Draws the Startup Icon { u8g.drawBitmapP(0, 0, 16, 64, icon); }
void draw(void) //Draws the main Screen { u8g.setFont(u8g_font_fur14);
u8g.setPrintPos(0, 20); u8g.print("In: "); u8g.print(int_room); u8g.setPrintPos(0, 60); u8g.print("Out: "); u8g.print(out_room); u8g.setFont(u8g_font_fur17); u8g.setPrintPos(0, 40); u8g.print("People~ "); u8g.print(people_room);
if (in_or_out == 2) { u8g.drawBitmapP(70, 0, 3, 20, left_arrow); } else if (in_or_out == 1) { u8g.drawBitmapP(70, 40, 3, 20, right_arrow); } else if (in_or_out == 3) { u8g.drawBitmapP(70, 0, 3, 20, cross); u8g.drawBitmapP(70, 40, 3, 20, cross); } }
void draw2() //Drwas the "Clear" Screen { u8g.setFont(u8g_font_fur17);
u8g.setPrintPos(0, 30); u8g.print("Clearing"); u8g.setPrintPos(0, 60); u8g.print("Variables!"); u8g.drawBitmapP(100, 10, 3, 20, cross);
u8g.enableCursor(); }
void setup() {
pinMode(APDS9960_INT, INPUT);
Serial.begin(115200); Serial.println(); Serial.println(F("--------------------------------")); Serial.println(F("-----------Count ´em------------")); Serial.println(F("--------------------------------"));
attachInterrupt(0, interruptRoutine, FALLING);
if (apds.init()) { Serial.println(F("APDS-9960 initialization complete")); } else { Serial.println(F("Something went wrong during APDS-9960 init!")); }
if (apds.enableGestureSensor(true)) { Serial.println(F("Gesture sensor is now running")); } else { Serial.println(F("Something went wrong during gesture sensor init!")); }
apds.setGestureGain(1);
if (u8g.getMode() == U8G_MODE_R3G3B2) { u8g.setColorIndex(255); } else if (u8g.getMode() == U8G_MODE_GRAY2BIT) { u8g.setColorIndex(3); } else if (u8g.getMode() == U8G_MODE_BW) { u8g.setColorIndex(1); } else if (u8g.getMode() == U8G_MODE_HICOLOR) { u8g.setHiColorByRGB(255, 255, 255); }
u8g.firstPage(); do { startupdraw(); } while (u8g.nextPage()); delay(3000); u8g.firstPage(); do { draw(); } while (u8g.nextPage()); }
void loop() { if (isr_flag == 1) { detachInterrupt(0); handleGesture(); isr_flag = 0; attachInterrupt(0, interruptRoutine, FALLING); } }
void interruptRoutine() { isr_flag = 1; }
void handleGesture() { if (apds.isGestureAvailable()) { switch (apds.readGesture()) { case DIR_DOWN: //Depending on Orientation you can change this to the right ones people_room++; Serial.println("Adding" + String(people_room));
u8g.firstPage(); do { draw(); } while (u8g.nextPage());
break; case DIR_UP: //Depending on Orientation you can change this to the right ones people_room--; Serial.println("Subtracting " + String(people_room));
u8g.firstPage(); do { draw(); } while (u8g.nextPage());
break; case DIR_RIGHT: //Depending on Orientation you can change this to the right ones
int_room++; people_room++; Serial.println("IN " + String(people_room)); in_or_out = 2; u8g.firstPage(); do { draw(); } while (u8g.nextPage()); in_or_out = 0; delay(700); u8g.firstPage(); do { draw(); } while (u8g.nextPage()); break; case DIR_LEFT: //Depending on Orientation you can change this to the right ones
out_room++; people_room--; Serial.println("OUT " + String(people_room)); in_or_out = 1; if (people_room == -1) { people_room = 0; } u8g.firstPage(); do { draw(); } while (u8g.nextPage()); in_or_out = 0; delay(700); u8g.firstPage(); do { draw(); } while (u8g.nextPage()); break; case DIR_FAR: //Depending on Orientation you can change this to the right ones Serial.println("FAR"); u8g.firstPage(); do { draw(); } while (u8g.nextPage()); break; case DIR_NEAR: //Depending on Orientation you can change this to the right ones Serial.println("NEAR || RESET"); out_room = 0; int_room = 0; people_room = 1; in_or_out = 0; u8g.firstPage(); do { draw2(); } while (u8g.nextPage());
delay(3000);
u8g.firstPage(); do { draw(); } while (u8g.nextPage());
break; default: Serial.println("NONE");
in_or_out = 3;
u8g.firstPage(); do { draw(); } while (u8g.nextPage());
in_or_out = 0;
delay(700); u8g.firstPage(); do { draw(); } while (u8g.nextPage()); } } }
If you have any questions or problems, you can always message me :)