Sam Nagorsky
Published

Visualisation of Antisemetism

This is a project that uses data from the ADL to visualize the quantity of antisemetism in the world over the last week.

IntermediateFull instructions provided20 hours25
Visualisation of Antisemetism

Things used in this project

Hardware components

Photon 2
Particle Photon 2
×1
Jumper wires (generic)
Jumper wires (generic)
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×2
Grove - 16-Channel PWM Driver (PCA9685)
Seeed Studio Grove - 16-Channel PWM Driver (PCA9685)
×1
Adafruit NeoPixel Digital RGB LED Strip 144 LED, 1m White
Adafruit NeoPixel Digital RGB LED Strip 144 LED, 1m White
56 LEDs
×1

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE
Heroku Dynos
Heroku Dynos

Hand tools and fabrication machines

Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Schematic

Code

Main Code

C/C++
This is all of the code to be flashed to the Photon 2 for use in the project.
#include <Adafruit_PCA9685.h>
#include <ArduinoJson.h>
#include <neopixel.h>
#include "Particle.h"

SYSTEM_MODE(AUTOMATIC);

#if (PLATFORM_ID == 32)
#define PIXEL_PIN SPI
#else
#define PIXEL_PIN D15
#endif
#define PIXEL_COUNT 56
#define PIXEL_TYPE WS2812B

unsigned long lastCall = 0;
JsonDocument doc;
String d = "";
Adafruit_PCA9685 pwm = Adafruit_PCA9685();

#define SERVO_MIN 150   // Corresponds to 0 degrees
#define SERVO_MAX 500   // Corresponds to 170 degrees
#define MOTOR_COUNT 2

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

int lights = 0 ;
int dataMode = 3 ;
int button = 5;


void setup() {
    Serial.begin(9600);
    waitFor(Particle.connected, 30000);
    
    Particle.subscribe("hook-response/adlData/0", firstCall);
    Particle.subscribe("hook-response/adlData/1", adlDataHandler);
    Particle.subscribe("hook-response/adlData/2", adlDataHandler);
    Particle.subscribe("hook-response/adlData/3", adlDataHandler);

    Serial.println("Subscription Set!");
    
    strip.begin();
    strip.show();
    
    Serial.println("Initializing PCA9685...");
    Wire.begin();
    pwm.begin();
    pwm.setPWMFreq(50);
    Serial.println("PCA9685 Initialized.");
    
    pinMode(button, INPUT_PULLUP);
}

void loop() {
    if (dataMode == 3){
        lastCall = millis();
        Particle.publish("adlData");
        dataMode = 1 ;
    }
    else if (dataMode == 1){
        if (millis() > lastCall + 300000) {
            lastCall = millis();
            Particle.publish("adlData");
        }
        if (digitalRead(button) == LOW ){
            dataMode = 0 ;
        }
    }
    else if (dataMode == 0){
        rainbow(0) ;
        setMotorAngle(0, 0) ;
        setMotorAngle(1, 180) ;
        Serial.println(0);
        if (digitalRead(button) == LOW ){
            dataMode = 3 ;
        }
    }
    delay(200) ;
}

void firstCall(const char *event, const char *data) {
    d = "";
    adlDataHandler(event, data);
}

void adlDataHandler(const char *event, const char *data) {
    d += String(data);
    
    if (countData() >= 0){
        int dataNum = countData();
                Serial.println(dataNum);

        if (dataNum > 15){
            dataNum = 15 ;
        }
        rainbow(dataNum) ;
        setMotorAngle(0, map(dataNum, 0, 15, 0, 180)) ;
        setMotorAngle(1, map(dataNum, 0, 15, 180, 0)) ;
        Serial.println(dataNum);
    }
}

int countData()
{
    // The deserializeJSON method turns the JSON text object into a JsonDocument object
    // Note: You must retrieve the internal CONSTANT C representation of the string, c_str()
    DeserializationError error = deserializeJson(doc, d.c_str());
    
    // ---- Error handling code from ArduinoJSON
    if (error)
    {
        Serial.print("deserializeJson() failed: ");
        Serial.println(error.c_str());
        return -1;
    }
    // ---- end error handling
    
    // **** Retrieving array of JSON objects
    JsonArray data = doc["time_stamps"];
    int c = 0;
    for (int i = 0; i < data.size(); i++){
        JsonObject iData = data[i];
        int iStamp = iData["time_stamp"];
        if (iStamp >= ((int)Time.now() - 604800)){
            c++ ;
        }
        
    }
    return c ;
}

void rainbow(int mData) {
    uint16_t i, j;
    for(i=0; i<56; i++) {
      strip.setColor(i, map(mData, 0, 15, 0, 255), map(mData, 0, 15, 27, 0), map(mData, 0, 15, 230, 0));
    }
    strip.show();
}

void setMotorAngle(int motorIndex, int angle) {
    int pulseLength = map(angle, 0, 180, SERVO_MIN, SERVO_MAX);
    pwm.setPWM(motorIndex, 0, pulseLength);
}

Credits

Sam Nagorsky
2 projects • 0 followers
Thanks to Grace O'Malley and Michael Marsico.

Comments