Sam Fogarty
Published © GPL3+

Sam Fogarty-Sculpture that Responds to Data

Using a Particle Photon 2 and collaborating with a sculpture student at my high school to create a sculpture that responds to live data.

IntermediateShowcase (no instructions)15 hours10
Sam Fogarty-Sculpture that Responds to Data

Things used in this project

Hardware components

Photon
Particle Photon
×1
Jumper wires (generic)
Jumper wires (generic)
×12
Stepper Motor
Digilent Stepper Motor
×1
Protoboard(generic)
×1
LED Strip, NeoPixel Digital RGB
LED Strip, NeoPixel Digital RGB
×1

Software apps and online services

Open-Meteo

Hand tools and fabrication machines

Solder Flux, Soldering
Solder Flux, Soldering
Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Schematics

Extremely Inaccurate Schematic

This is a very rough representation, as tinker cad does not include exact components. The Arduino presents the Particle Photon 2, the two motors represent the 28BYJ-48 Stepper Motor and ULN2003 Driver, and I used a strip of 9 neopixel lights for the illumination of my project.

Code

Particle Coding Environment

C/C++
// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// This #include statement was automatically added by the Particle IDE.
#include <AccelStepper.h>



// IMPORTANT: Set pixel COUNT, PIN and TYPE
#if (PLATFORM_ID == 32)
// MOSI pin MO
#define PIXEL_PIN SPI1
// MOSI pin D2
// #define PIXEL_PIN SPI1
#else // #if (PLATFORM_ID == 32)
#define PIXEL_PIN D2
#endif
#define PIXEL_COUNT 9
#define PIXEL_TYPE WS2812B

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);



#define motorPin21  D10     // IN1 on the ULN2003 driver 1
#define motorPin22  D7     // IN2 on the ULN2003 driver 1
#define motorPin23  D6     // IN3 on the ULN2003 driver 1
#define motorPin24  D5 // IN4 on the ULN2003 driver 1

#define motorPin31  A0     // IN1 on the ULN2003 driver 1
#define motorPin32  A1    // IN2 on the ULN2003 driver 1
#define motorPin33  A2     // IN3 on the ULN2003 driver 1
#define motorPin34  A5


AccelStepper stepper2(AccelStepper::FULL4WIRE, motorPin21, motorPin23, motorPin22, motorPin24);
AccelStepper stepper3(AccelStepper::FULL4WIRE, motorPin31, motorPin33, motorPin32, motorPin34); // FIXED

#define CLOUD_TRAVEL 4096   // steps to fully close clouds
bool cloudsIn = false;      // track cloud state
int quality = 0;

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

    strip.begin();
    strip.show();

    Particle.subscribe("hook-response/air_qual/", extractInfo);

    // Motors 1 & 2: cloud gears, move to open position on start
   
    stepper2.setMaxSpeed(800.0);
    stepper2.setAcceleration(200.0);

    // Motor 3: top spinner, runs continuously
    stepper3.setMaxSpeed(1000.0);
    stepper3.setAcceleration(100.0);
    stepper3.setSpeed(300);  // default speed
    int i=0;
}
int tE=0;
void loop() {
   if(millis()-tE>=1800000){
    Particle.publish("air_qual");
    
    stepper2.run();
    strip.show();

    // Motor 3 runs continuously in one direction
    stepper3.runSpeed();
    tE=millis();
  }
  
 
    
}

void extractInfo(const char *event, const char *data) {
    Serial.println("Handler starting...");
    int quality = atoi(data);
    //quality = 34;
    Serial.print("AQI: ");
    Serial.println(quality);

    if (quality <= 35) {
        goodAir();
    } else {
        badAir();
    }
}

void goodAir() {
    Serial.println("Good air - retracting clouds, spinning fast");

    // Retract clouds (move back to 0)
    if (cloudsIn) {
        
        stepper2.moveTo(2000);
        cloudsIn = false;
    }

    // Spin top motor faster
    stepper3.setSpeed(600);

    // white LEDs
    for (int i = 0; i < PIXEL_COUNT; i++) {
        strip.setPixelColor(i, 245,245,245);
    }
    strip.show();
    
}

void badAir() {
    Serial.println("Bad air - pushing clouds in, spinning slow");

    // Push clouds in
    if (!cloudsIn) {
       
        stepper2.moveTo(-5000);
        cloudsIn = true;
    }

    // Spin top motor slower
    stepper3.setSpeed(200);

    // yellow LEDs
    for (int i = 0; i < PIXEL_COUNT; i++) {
        strip.setPixelColor(i, 210, 230, 0);
    }
    strip.show();
    
}

Particle Coding Environment

C/C++
No preview (download only).

Credits

Sam Fogarty
2 projects • 0 followers
Thanks to Yohan Encarnacion.

Comments