Park Information Tracker
Made by lortega, Lillie Widmayer and Maya Pandurangan
Made by lortega, Lillie Widmayer and Maya Pandurangan
Created: December 13th, 2019
Problem Statement: Create an IoT device to improve guest experience at Panther Hollow Park.
Solution: We decided to create a system of interconnected devices which would be spread throughout the area, collecting park information. These devices would then communicate with a map representation of the park to indicate which areas are in need of maintenance.
Intended Audience: Park managers. Our device is multifunctional and will optimize the distribution of human resources by alerting park managers when a particular trash can needs to be emptied or a particular area needs maintenance.
How It Works:
The device is mounted onto a trash can.
1. The device emits a high frequency noise to keep animals from coming onto park pathways.
2. When the trash can is filled, an LED on the device lights up and a corresponding LED on the map is illuminated to inform park managers that a trash can needs to be emptied. LEDs automatically turn off once the trash is emptied.
3. The device collects data about how many people visit the park and lights 1,2, or 3 LEDs on the map to ambiently tell park managers how many visitors their park has had.
4. If visitors think an area needs maintenance, they can press a maintenance request button. When a set amount of people press the button, park managers will get an email telling them there is an issue in a certain area.
Process: The main goals for this project were to (1) detect if a trash can is full and update the map/email the park managers if it is, (2) allow park goers to give input about the current state of the park through a button press, (3) count the number of people currently visiting the park (4) keep animals away with sound. Our first iteration was less design focused and more functionality driven.
For the final iteration of the project we decided to create a more artistic map representation of the park. We created a topographical map and incorporated a blue acrylic piece for the lake. We cleaned up the devices that would be mounted on the trash cans to perfectly fit the sensors. We implemented an IFTTT to send emails to park managers, and implemented publishing/subscribing between particles so that the map could receive information from the devices mounted on trash cans.
Difficulties: The largest challenge of this project was interfacing with the Particles. There were points in time where we were able to successfully connect the particles to the cloud. In the end, we had to use an Arduino and not use publishing/subscribing in our final demo because our Particle Argons were not connecting to the cloud properly.
Another difficulty we faced was getting IR sensors to be as accurate as possible and detect people in the correct range.
// This #include statement was automatically added by the Particle IDE.
#include <SharpIR.h>
#include <math.h>
//Deep Dive for Trashcan 1
//People counter -> IR Distance sensor
const int IR = A5;
float value = 0.0;
bool seeingPerson = false;
long lastCount = millis();
int passCount = 0;
//Person maintenance request -> button
int button = D4;
int buttonCount = 0;
long lastPress = millis();
//Trash maintenance request -> ir sensor for trash can
const int trashDown = A3; // IR distance apart sensor
const int trashSide = D8; // IR pull apart sensor
const int trashLED = D6; //LED on box
bool trashType = true;
int currBeamState = 0;
int beamOn = 0;
//Animal Repellent -> piezo (aka speaker)
int speaker = D2;
void setup() {
//counter
pinMode(IR, INPUT);
//button
pinMode(button, INPUT);
//trashcan sensor
pinMode(trashDown, INPUT_PULLUP);
pinMode(trashSide, INPUT_PULLUP);
pinMode(trashType, INPUT);
pinMode(trashLED, OUTPUT);
//sound
pinMode(speaker, OUTPUT);
tone(speaker, 3500, 0);
}
void loop() {
//button
if (digitalRead(button)){
Particle.publishVitals();
Particle.publish("button", "p", PUBLIC);
if (millis() - lastPress > 60){
lastPress = millis();
buttonCount++;
if (buttonCount > 10){
//send email using IFTTT
Particle.publish("button_pressed", "pressed", PUBLIC);
buttonCount = 0;
}
}
}
//trashcan sensor for trashSide
if (trashType){
currBeamState = digitalRead(trashSide);
if(!currBeamState && !beamOn) {
digitalWrite(trashLED, HIGH);
beamOn = currBeamState;
Particle.publish("trashFull", "trash1", PUBLIC);
}
else{
beamOn = false;
digitalWrite(trashLED, LOW);
Particle.publish("trashEmpty", "trash1", PUBLIC);
}
}
//trashcan sensor for trashDown USES IR SENSOR
if (!trashType){
float volts = float(analogRead(IR))*0.0048828125;
int distance = 13 * pow(volts, -1);
value = (value * 0.7) + (distance * 0.3);
//HAVE TO CHANGE VAL w/ FURTHER TESTING
if (value <= 2){
Particle.publish("trashFull", "trash1", PUBLIC);
//Serial.println(int(value));
}
else{
Particle.publish("trashEmpty", "trash1", PUBLIC);
}
}
//counter (will paste in based on final model. idk what to look for yet)
//USES IR SENSOR
float volts = float(analogRead(IR))*0.0048828125;
int distance = 13 * pow(volts, -1);
value = (value * 0.7) + (distance * 0.3);
if (value <= 2){
if(!seeingPerson && (millis() - lastCount > 2000)){
lastCount = millis();
if (passCount < 50) {
passCount++;
Particle.publish("counter", "1", PUBLIC);
}
if (passCount > 50 && passCount < 100){
passCount++;
Particle.publish("counter", "2", PUBLIC);
}
else{
Particle.publish("counter", "3", PUBLIC);
passCount = 0;
}
//Serial.println(int(passCount));
seeingPerson = true;
}
//Serial.println(int(value));
}
else{
seeingPerson = false;
}
}
Click to Expand
//Deep Dive for Map
//People counter -> radar sensor
int countLowLED = D1;
int countMedLED = D1;
int countHighLED = D1;
//Trash maintenance request -> ir sensor for trash can
int trash1LED = D1;
int trash2LED = -1;
int trash3LED = -1;
int trash4LED = -1;
//Person maintenance request -> button
//no LED, will send maintenance request to park managers
int map1LED = D1;
int map2LED = -1;
int map3LED = -1;
int map4LED = -1;
//Animal Repellent -> piezo
//no LED, will constantly buzz
void setup() {
Particle.subscribe("counter", counter, ALL_DEVICES);
Particle.subscribe("trashFull", trashFull, ALL_DEVICES);
Particle.subscribe("trashEmpty", trashEmpty, ALL_DEVICES);
//counter
pinMode(countLowLED, OUTPUT);
pinMode(countMedLED, OUTPUT);
pinMode(countHighLED, OUTPUT);
//trash
pinMode(trash1LED, OUTPUT);
pinMode(trash2LED, OUTPUT);
pinMode(trash3LED, OUTPUT);
pinMode(trash4LED, OUTPUT);
//button
pinMode(map1LED, OUTPUT);
pinMode(map2LED, OUTPUT);
pinMode(map3LED, OUTPUT);
pinMode(map4LED, OUTPUT);
}
void loop() {
}
void counter(const char *event, const char *data){
if (strcmp(data, "1")==0){
digitalWrite(countLowLED, HIGH);
digitalWrite(countMedLED, LOW);
digitalWrite(countHighLED, LOW);
}
if (strcmp(data, "2")==0){
digitalWrite(countLowLED, LOW);
digitalWrite(countMedLED, HIGH);
digitalWrite(countHighLED, LOW);
}
if (strcmp(data, "3")==0){
digitalWrite(countLowLED, LOW);
digitalWrite(countMedLED, LOW);
digitalWrite(countHighLED, HIGH);
}
}
void trashFull(const char *event, const char *data){
if (strcmp(data, "trash1")==0){
digitalWrite(trash1LED, HIGH);
digitalWrite(map1LED, HIGH);
}
if (strcmp(data, "trash2")==0){
digitalWrite(trash2LED, HIGH);
digitalWrite(map2LED, HIGH);
}
if (strcmp(data, "trash3")==0){
digitalWrite(trash3LED, HIGH);
digitalWrite(map3LED, HIGH);
}
if (strcmp(data, "trash4")==0){
digitalWrite(trash4LED, HIGH);
digitalWrite(map4LED, HIGH);
}
}
void trashEmpty(const char *event, const char *data){
if (strcmp(data, "trash1")==0){
digitalWrite(trash1LED, LOW);
digitalWrite(map1LED, LOW);
}
if (strcmp(data, "trash2")==0){
digitalWrite(trash2LED, LOW);
digitalWrite(map2LED, LOW);
}
if (strcmp(data, "trash3")==0){
digitalWrite(trash3LED, LOW);
digitalWrite(map3LED, LOW);
}
if (strcmp(data, "trash4")==0){
digitalWrite(trash4LED, LOW);
digitalWrite(map4LED, LOW);
}
}
Click to Expand
Thermostats, locks, power sockets, and lights are all being imbued with smarts making them increasingly aware and responsive to their environment and users. This course will chart the emergence of ...more
~