Dawit Negatu
Published © GPL3+

A Real Time NYC EMS Data Visualizer

This combined project takes New York city EMS emergency response data and turns into something tangible and real.

IntermediateFull instructions provided16
A Real Time NYC EMS Data Visualizer

Things used in this project

Hardware components

Photon
Particle Photon
×1
Resistor 330 ohm
Resistor 330 ohm
×3
Through Hole Resistor, 10 ohm
Through Hole Resistor, 10 ohm
×3
Wire, Solid
Wire, Solid
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Jumper wires (generic)
Jumper wires (generic)
×1
SparkFun Snappable Protoboard
SparkFun Snappable Protoboard
×1
L298N Motor Drive Controller Board Module Dual H Bridge DC Stepper For Arduino
×1
Darlington High Power Transistor
Darlington High Power Transistor
×3
0.91 inch 128x32 I2C IIC Serial OLED LCD Screen DIY Module 4-PIN DC 3.3V 5V 12832 SSD1306 Low Consumption LED Display Compatible with PIC Ar-duino
×1

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Wire Stripper & Cutter, 32-20 AWG / 0.05-0.5mm² Solid & Stranded Wires
Wire Stripper & Cutter, 32-20 AWG / 0.05-0.5mm² Solid & Stranded Wires
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Schematics

Wiring

Code

EMS Data collector

C/C++
#include <Adafruit_SSD1306.h>
#include "Particle.h"

SYSTEM_MODE(AUTOMATIC);

const int RED_PIN   = D2;
const int GREEN_PIN = D3;
const int BLUE_PIN  = D4;
const int MOTOR_IN1 = D5;
const int MOTOR_IN2 = D6;
const int MOTOR_ENA = D7;

int todaySaves     = 0;
int yesterdaySaves = 0;

#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);

void emsHandler(const char *event, const char *data);
void heartbeat(int restTime);

void setup() {
    Serial.begin(9600);

    // LED pins off at start
    pinMode(RED_PIN, OUTPUT);
    pinMode(GREEN_PIN, OUTPUT);
    pinMode(BLUE_PIN, OUTPUT);
    digitalWrite(RED_PIN, LOW);
    digitalWrite(GREEN_PIN, LOW);
    digitalWrite(BLUE_PIN, LOW);

    // Motor off at start
    pinMode(MOTOR_IN1, OUTPUT);
    pinMode(MOTOR_IN2, OUTPUT);
    pinMode(MOTOR_ENA, OUTPUT);
    digitalWrite(MOTOR_ENA, LOW);

    // Start OLED
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.clearDisplay();
    display.display();

    while (Particle.disconnected());
    Serial.println("Connected to Particle Cloud");

    // Run emsHandler when webhook response arrives
    Particle.subscribe("hook-response/getEMS", emsHandler);

    // Eastern Time (NYC)
    Time.zone(-4);

    // Calculate this date one year ago and the day before
    time_t lastYear          = Time.now() - (365 * 86400);
    time_t yesterdayLastYear = lastYear - 86400;

    // Format dates for the API
    String todayStart     = Time.format(lastYear, "%Y-%m-%d") + "T00:00:00";
    String todayEnd       = Time.format(lastYear, "%Y-%m-%d") + "T23:59:59";
    String yesterdayStart = Time.format(yesterdayLastYear, "%Y-%m-%d") + "T00:00:00";
    String yesterdayEnd   = Time.format(yesterdayLastYear, "%Y-%m-%d") + "T23:59:59";

    // This fills in webhook URL variables
    String data = "{";
    data += "\"todayStart\":\"" + todayStart + "\",";
    data += "\"todayEnd\":\"" + todayEnd + "\",";
    data += "\"yesterdayStart\":\"" + yesterdayStart + "\",";
    data += "\"yesterdayEnd\":\"" + yesterdayEnd + "\"";
    data += "}";

    Serial.println("Publishing: " + data);
    delay(1000);
    Particle.publish("getEMS", data, PRIVATE);
}

void loop() {
    // Spin motor if today beats yesterday
    if (todaySaves > yesterdaySaves) {
        digitalWrite(MOTOR_ENA, HIGH);
        digitalWrite(MOTOR_IN1, HIGH);
        digitalWrite(MOTOR_IN2, LOW);
    } else {
        digitalWrite(MOTOR_ENA, LOW);
    }

    // Faster heartbeat if today beats yesterday
    int beatDelay = (todaySaves > yesterdaySaves) ? 400 : 900;
    heartbeat(beatDelay);
}

void heartbeat(int restTime) {
    // Two quick red pulses then a pause
    digitalWrite(RED_PIN, HIGH);
    delay(120);
    digitalWrite(RED_PIN, LOW);
    delay(80);
    digitalWrite(RED_PIN, HIGH);
    delay(120);
    digitalWrite(RED_PIN, LOW);
    delay(restTime);
}

void emsHandler(const char *event, const char *data) {
    // Copy response into char array for splitting
    char buf[64];
    strncpy(buf, data, sizeof(buf));

    // Split comma-separated response
    String todayStr     = strtok(buf, ",");
    String yesterdayStr = strtok(NULL, ",");

    todaySaves     = todayStr.toInt();
    yesterdaySaves = yesterdayStr.toInt();

    Serial.print("Today: ");     Serial.println(todaySaves);
    Serial.print("Yesterday: "); Serial.println(yesterdaySaves);

    // Show today's count on OLED
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(0, 10);
    display.println(todaySaves);
    display.display();
}

Credits

Dawit Negatu
2 projects • 0 followers

Comments