Niko Zgonena
Published

Midwest Data Visualization Project

My project is a physical data visualization that shows the difference between fossil fuels and renewable energy in the Midwest using data!

IntermediateFull instructions provided20 hours28
Midwest Data Visualization Project

Things used in this project

Hardware components

Photon
Particle Photon
×1
28BYJ-48 Stepper Motor and ULN2003 Driver SY2526
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Adafruit NeoPixel Silicone Bead LED Strip - 180 LEDs per Meter - 1 meter
×1
SparkFun Snappable Protoboard
SparkFun Snappable Protoboard
×1
5521 Welding-Free Connector 5V 12V 24V 48V Wire to Male Female
×1
5V 2.5A Switching Power Supply
Digilent 5V 2.5A Switching Power Supply
×1

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE

Story

Read more

Code

MIDWEST SERVO / STEPPER CONFIG

C/C++
#include <Stepper.h>
#include <neopixel.h>
#include "Particle.h"

SYSTEM_MODE(AUTOMATIC);
SerialLogHandler logHandler(LOG_LEVEL_INFO);

int LED_Count = 8;
Adafruit_NeoPixel light(LED_Count, SPI, WS2812B);
uint32_t color;

int NG_value = 0;
int WAT_value = 0;

int minNG = 20000;
int maxNG = 50000;

int minWAT = 400;
int maxWAT = 7000;

const int stepsPerRevolution = 2048;
int currentStepPosition = 0;

#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5

int mechanicalOffsetDegrees = -66;

Stepper myStepper(stepsPerRevolution, IN1, IN3, IN2, IN4);

void updateLEDs(int ng);
void updateMotor(int wat);
void myHandler(const char *event, const char *data);

void setup() {
    Serial.begin(9600);
    while (Particle.disconnected());
    Serial.println("Particle connected to cloud!");

    Particle.subscribe("hook-response/get_eia_data", myHandler, MY_DEVICES);

    light.begin();
    light.setBrightness(50);
    light.show();

    myStepper.setSpeed(15);

    Serial.println("Booting...");
}

void loop() {
    Particle.publish("get_eia_data", "request", PRIVATE);
    delay(5000);
}

void myHandler(const char *event, const char *data) {

    Serial.println("Webhook says:");
    Serial.println(data);

    NG_value = 0;
    WAT_value = 0;

    const char* ng_ptr = strstr(data, "NG:");
    const char* wat_ptr = strstr(data, "WAT:");

    if (ng_ptr != NULL) {
        NG_value = atoi(ng_ptr + 3);
    }

    if (wat_ptr != NULL) {
        WAT_value = atoi(wat_ptr + 4);
    }

    Serial.printf("Parsed NG=%d  WAT=%d\n", NG_value, WAT_value);
    
    updateLEDs(WAT_value);
    updateMotor(NG_value);
}

void updateLEDs(int wat) {
    wat = constrain(wat, minWAT, maxWAT);
 
    int count = map(wat, minWAT, maxWAT, 0, LED_Count);

    for (int i = 0; i < LED_Count; i++) {
        if (i < count) {
            if (wat < 2000) {
                light.setPixelColor(i, light.Color(255, 0, 0));
            } else if (wat < 5000) {
                light.setPixelColor(i, light.Color(255, 255, 0));
            } else {
                light.setPixelColor(i, light.Color(0, 255, 0));
            }
        } else {
            light.setPixelColor(i, light.Color(0, 0, 0));
        }
    }

    light.show();
}

void updateMotor(int ng) {

    int targetAngle = map(ng, minNG, maxNG, 0, 180);

    targetAngle += mechanicalOffsetDegrees;  
    targetAngle = constrain(targetAngle, 0, 180);

    float stepsPerDegree = 2048.0 / 360.0;
    int targetStepPosition = targetAngle * stepsPerDegree;

    int stepDifference = targetStepPosition - currentStepPosition;

    myStepper.step(stepDifference);

    currentStepPosition = targetStepPosition;

    Serial.printf("NG=%d  Angle=%d  Steps=%d\n", ng, targetAngle, targetStepPosition);
}

Credits

Niko Zgonena
2 projects • 0 followers
Thanks to Scarlett.

Comments