Zain Kanji
Published

Chicago Gun Violence Electronic Sculpture

For my physical computing class we chose to display struggle with technology and sculpture to display the state of gun violence in Chicago.

BeginnerShowcase (no instructions)89
Chicago Gun Violence Electronic Sculpture

Things used in this project

Hardware components

Photon
Particle Photon
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×1
SparkFun Snappable Protoboard
SparkFun Snappable Protoboard
×1
NeoPixel Ring: WS2812 5050 RGB LED
Adafruit NeoPixel Ring: WS2812 5050 RGB LED
×1
DC POWER JACK 2.1MM BARREL-TYPE PCB MOUNT
TaydaElectronics DC POWER JACK 2.1MM BARREL-TYPE PCB MOUNT
×1
9V 1A Switching Wall Power Supply
9V 1A Switching Wall Power Supply
×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)
Solder Wire, Lead Free
Solder Wire, Lead Free
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
10 Pc. Jumper Wire Kit, 5 cm Long
10 Pc. Jumper Wire Kit, 5 cm Long

Story

Read more

Code

PCLSculpture - Chi Gun Violence

C/C++
This code works with the Chicago Public Data Portal, pulling queries of gun violence cases through the use of an integration in the Particle IDE. I configured the JSON package that is retrieved from the API links by prioritizing the wards in which the case took place and whether there was a gunshot victim. From this data the algorithm is able to run as shown below in the code.
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include <ArduinoJson.h>
#include "Particle.h"

SYSTEM_MODE(AUTOMATIC);
SerialLogHandler logHandler(LOG_LEVEL_INFO);

#if (PLATFORM_ID == 32)
#define PIXEL_PIN SPI1
#else // #if (PLATFORM_ID == 32)
#define PIXEL_PIN D2
#endif
#define PIXEL_COUNT 10
#define PIXEL_TYPE WS2812B

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
Servo myServo;
int districtIndex[10];
String injureds[10];
const int farNorthSide[] = {41, 45, 39, 50, 49, 48, 40, 33, 47, 46};
const int northwestSide[] = {38,36,26,30,35,31};
const int northSide[] = {44,43,1,32};
const int westSide[] = {29,37,28,24,22,25,34,27};
const int central[] = {42,2,4};
const int southWestSide[] = {14,23,13,12,15,16};
const int southSide[] = {11,3,20,5};
const int farSouthWestSide[] = {18,17,21,19,6};
const int farSouthEastSide[] = {9,10,8,7};

const int* districts[] = {
    farNorthSide,
    northwestSide,
    northSide,
    westSide,
    central,
    southSide,
    southWestSide,
    farSouthWestSide,
    farSouthEastSide
};

const int districtSizes[] = {
    sizeof(farNorthSide) / sizeof(farNorthSide[0]),
    sizeof(northwestSide) / sizeof(northwestSide[0]),
    sizeof(northSide) / sizeof(northSide[0]),
    sizeof(westSide) / sizeof(westSide[0]),
    sizeof(central) / sizeof(central[0]),
    sizeof(southWestSide) / sizeof(southWestSide[0]),
    sizeof(southSide) / sizeof(southSide[0]),
    sizeof(farSouthWestSide) / sizeof(farSouthWestSide[0]),
    sizeof(farSouthEastSide) / sizeof(farSouthEastSide[0])
};
// setup() runs once, when the device is first turned on
void setup() {
    Particle.subscribe("hook-response/getGunCrimes", retrieveValues);
    Serial.begin(9600);
    strip.begin();
    strip.clear();
    strip.setBrightness(255);
    strip.show();
    myServo.attach(1);
    myServo.write(0);
    Particle.publish("getGunCrimes");
}

// loop() runs over and over again, as quickly as it can execute.
void loop() {
    unsigned long msecs = millis();
    if (msecs%3600000 == 0)
    {
        Particle.publish("getGunCrimes");
    }
    gunLights(districtIndex, injureds, 10);
    for (int angle = 0; angle < 90; angle++)
    {
        myServo.write(angle);
        delay(15);
    }
    delay(150);
    strip.clear();
    strip.show();
    for (int angle = 90; angle >= 0; angle--)
    {
        myServo.write(angle);
        delay(15);
    }
    delay(150);
    
}

void retrieveValues(const char *event, const char *data)
{
    String jsonData = data;
    const int queryAmt = getQueryAmt(jsonData);
    String queries[queryAmt];
    int wards[queryAmt];
    String injuries[queryAmt];
    int districtNums[queryAmt];
    splitData(jsonData, queries, queryAmt);
    getWards(queries, wards, queryAmt);
    getInjuries(queries, injuries, queryAmt);
    getDistrictNum(wards, districtNums, queryAmt);
    for (int i = 0; i < queryAmt; i++)
    {
        districtIndex[i] = districtNums[i];
        Serial.print(districtIndex[i]);
    }
    for (int i = 0; i < queryAmt; i++)
    {
        injureds[i] = injuries[i];
        Serial.print(injureds[i]);
    }
}

int getQueryAmt(String data)
{
    int amt = 0;
    for (int i = 0; i < data.length(); i++)
    {
        if (data.charAt(i) == '{')
        {
            amt++;
        }
    }
    return amt;
}

void splitData(String data, String array[], int queryAmt)
{
    for (int i = 0; i < queryAmt; i++)
    {
        int startIndex = data.indexOf('{') + 1;
        int endIndex = data.indexOf('}');
        array[i] = data.substring(startIndex, endIndex);
        data = data.substring(endIndex+1);
    }
}

void getWards(String array1[], int array2[], int queryAmt)
{
    for (int i = 0; i < queryAmt; i++)
    {
        int wardIndex = array1[i].indexOf("ward");
        String str = array1[i].substring(wardIndex);
        int commaIndex = str.indexOf(',');
        array2[i] = str.substring(7, commaIndex - 1).toInt();
    }
}

void getInjuries(String array1[], String array2[], int queryAmt)
{
    for (int i = 0; i < queryAmt; i++)
    {
        int gunIndex = array1[i].indexOf("gunshot_injury_i");
        String str = array1[i].substring(gunIndex);
        array2[i] = str.substring(19, str.length() - 1);
    }
}

void getDistrictNum(int array1[], int array2[], int queryAmt)
{
    for (int i = 0; i < queryAmt; i++)
    {
        for (int a = 0; a < arraySize(districts); a++)
        {
            for (int b = 0; b < districtSizes[a]; b++)
            {
                if (array1[i] == districts[a][b])
                {
                    array2[i] = a;
                }
            }
        }
    }
}

void gunLights(int array1[], String array2[], int queryAmt)
{
    for (int i = 0; i < queryAmt; i++)
    {
        if (array2[i].equals("YES"))
        {
            strip.setPixelColor(array1[i], 255, 0, 0);
            strip.show();
        } 
        else
        {
            strip.setPixelColor(array1[i], 250, 255, 0);
            strip.show();
        }
    }
}

Credits

Zain Kanji
1 project • 0 followers

Comments