Joeseph Arnoux
Published © MIT

Tread Lightly

Capstone project for Rail Trail CABQ. Using art and technology to spread awareness about Indigenous communities and care taking of the land.

IntermediateFull instructions providedOver 2 days42
Tread Lightly

Things used in this project

Story

Read more

Custom parts and enclosures

Shell Housing

Solidworks and Bambu Lab 3D printed shell housing for the photon 2.

Heat Sensor

Solidworks and Bambu Lab

Schematics

Fritz

Capstone "Tread Lightly" Fritzing.

Schematics

Capstone "Tread Lightly" Schematics.

Code

Tread Lightly

C/C++
C++ coding for Tread Lightly Rail Trail Project for CABQ.
#include "Particle.h"
#include "IoTClassroom_CNM.h"
#include "Button.h"
#include "colors.h"
#include <math.h>
#include <neopixel.h>
#include <credentials.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT/Adafruit_MQTT_SPARK.h" 
#include "Adafruit_MQTT/Adafruit_MQTT.h"
 
unsigned int last, lastTime;
float buttonOnOff;
float pirsensorValue;
const int PIXELCOUNT = 113;
const int PIR_SENSOR_OUTPUT_PIN = D4;
int some_long_process_within_loop;
const float amplitude = 127.5;
const float offset = 127.5;
float frequency = .2;
float t;
float brightness;

TCPClient TheClient;
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY);
Adafruit_MQTT_Subscribe buttonOnOffFeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/buttonOnOff");
Adafruit_MQTT_Publish pirsensorFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/pirsensor"); 

Adafruit_NeoPixel pixel (PIXELCOUNT,SPI1,WS2812B);
void PixelFill(int startPixel, int endPixel, int color);

ApplicationWatchdog *wd;
void watchdogHandler() {
   System.reset(RESET_NO_WAIT);
}

void MQTT_connect();
bool MQTT_ping();
void WebPublish();

SYSTEM_MODE(AUTOMATIC);


void setup() {
pinMode (PIXELCOUNT,OUTPUT);
pinMode(PIR_SENSOR_OUTPUT_PIN, INPUT);

Serial.begin(9600);
waitFor(Serial.isConnected,10000);

pixel.begin();
pixel.setBrightness(255);
pixel.show();

mqtt.subscribe(&buttonOnOffFeed);

wd = new ApplicationWatchdog(60000, watchdogHandler, 1536);

}


void loop() {

int sensor_output;
sensor_output = digitalRead(PIR_SENSOR_OUTPUT_PIN);

MQTT_connect();
MQTT_ping();

Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(100))) {
    if (subscription == &buttonOnOffFeed) {
      buttonOnOff = atof((char *)buttonOnOffFeed.lastread);
    }
  }

//Button
   if(buttonOnOff == true) {
      PixelFill(19,69,turquoise);
      PixelFill(70,113,red);
      PixelFill(0,18,red);
      Serial.printf("FEAST DAY %f\n",buttonOnOff);
      }
   pixel.show();
   delay(2500);
   pixel.clear();
 
//Narrative: 
if(sensor_output == HIGH) {
Serial.printf("Sunrise %i\n",sensor_output);
PixelFill(86,113,red);
   delay(1000);
      PixelFill(0,13,red);
      PixelFill(74,85,red);
      delay(1000);
       PixelFill(14,28,blue);
       PixelFill(60,73,blue);
       delay(1000);
         PixelFill(29,59,yellow);
         delay(1000);

         delay(2000);
         pixel.clear();

   PixelFill(98,113,yellow);
   delay(1000);
   PixelFill(0,18,red);
   delay(1000);
   PixelFill(19,31,red);
   delay(1000);
   PixelFill(32,44,violet);
   delay(1000);
      PixelFill(45,54,violet);
      delay(1000);
      PixelFill(55,69,red);
      delay(1000);
      PixelFill(70,84,red);
      delay(1000);
      PixelFill(85,97,yellow);
      delay(1000);
         
      delay(2000);
      pixel.clear();

Serial.printf("Time Warp Reverse %i\n",sensor_output);
         PixelFill(98,113,green);
         PixelFill(0,44,green);
         PixelFill(45,97,red);
         delay(1000);

         delay(2000);
         pixel.clear();

PixelFill(0,55,yellow);
PixelFill(56,113,purple);
delay(2000);
pixel.clear();

   PixelFill(20,68,olive);
   PixelFill(69,113,chocolate);
   PixelFill(0,19,chocolate);
   delay(2000);
   pixel.clear();

PixelFill(0,32,blue);
PixelFill(33,86,orange);
PixelFill(87,113,blue);
delay(2000);
pixel.clear();

Serial.printf("Ceremony Dance %i\n",sensor_output);
PixelFill(20,68,red);
PixelFill(69,113,orange);
PixelFill(0,19,orange);
delay(500);
pixel.clear();
   PixelFill(20,68,orange);
   PixelFill(69,113,yellow);
   PixelFill(0,19,yellow);
   delay(500);
   pixel.clear();
      PixelFill(20,68,yellow);
      PixelFill(69,113,green);
      PixelFill(0,19,green);
      delay(500);
      pixel.clear();
         PixelFill(20,68,green);
         PixelFill(69,113,blue);
         PixelFill(0,19,blue);
         delay(500);
         pixel.clear();
            PixelFill(20,68,blue);
            PixelFill(69,113,indigo);
            PixelFill(0,19,indigo);
            delay(500);
            pixel.clear();
               PixelFill(20,68,indigo);
               PixelFill(69,113,violet);
               PixelFill(0,19,violet);
               delay(500);
               pixel.clear();

Serial.printf("Time Warp Present %i\n",sensor_output);
         PixelFill(98,113,red);
         PixelFill(0,44,red);
         PixelFill(45,97,green);
         delay(1000);

         delay(2000);
         pixel.clear();

PixelFill(56,113,yellow);
PixelFill(0,55,purple);
delay(2000);
pixel.clear();

   PixelFill(20,68,chocolate);
   PixelFill(69,113,olive);
   PixelFill(0,19,olive);
   delay(2000);
   pixel.clear();

PixelFill(0,32,orange);
PixelFill(33,86,blue);
PixelFill(87,113,orange);
delay(2000);
pixel.clear();

Serial.printf("Sunset %i\n",sensor_output);
      PixelFill(85,97,yellow);
      delay(1000);
      PixelFill(70,84,red);
      delay(1000);
      PixelFill(55,69,red);
      delay(1000);
      PixelFill(45,54,violet);
      delay(1000);
   PixelFill(32,44,violet);
   delay(1000);
   PixelFill(19,31,red);
   delay(1000);
   PixelFill(0,18,red);
   delay(1000);
   PixelFill(98,113,yellow);
   delay(1000);

   delay(2000);
   pixel.clear();

         PixelFill(29,59,yellow);
         delay(1000);
       PixelFill(14,28,blue);
       PixelFill(60,73,blue);
       delay(1000);
      PixelFill(0,13,red);
      PixelFill(74,85,red);
      delay(1000);
   PixelFill(86,113,red);
   delay(1000);

   delay(2000);
   pixel.clear();

t = millis()/1000.0;  
brightness = amplitude*sin(2*M_PI*frequency*t)+offset;
analogWrite (PIXELCOUNT,brightness);
}
pixel.show();

//OFF
      if(sensor_output == LOW) {
         PixelFill(0,113,black);
            Serial.printf("shapeShift = %i\n",sensor_output);
      }
      pixel.show();

//Data Dashboard
if((millis()-lastTime > 6000)) {
    if(mqtt.Update()) {
      
      pirsensorFeed.publish(sensor_output);
      Serial.printf("7 Generations = %i \n",sensor_output);
      } 
    lastTime = millis();
  }

while (some_long_process_within_loop) {
   ApplicationWatchdog::checkin();
  }

 WebPublish();

}


//END

void PixelFill(int startPixel, int endPixel, int color) {
    int litPixel;;

   for(litPixel=startPixel;litPixel<=endPixel;litPixel++) {
      pixel.setPixelColor(litPixel,color);
   }
   pixel.show();
   delay(100);

}

void MQTT_connect() {
  int8_t ret;
 
  if (mqtt.connected()) {
    return;
  }
 
  while ((ret = mqtt.connect()) != 0) { 
       Serial.printf("Error Code %s\n",mqtt.connectErrorString(ret));
       Serial.printf("Retrying MQTT connection in 5 seconds...\n");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds and try again
  }
  Serial.printf("MQTT Connected!\n");
}

bool MQTT_ping() {
  static unsigned int last;
  bool pingStatus;

  if ((millis()-last)>120000) {
      Serial.printf("Pinging MQTT \n");
      pingStatus = mqtt.ping();
      if(!pingStatus) {
        Serial.printf("Disconnecting \n");
        mqtt.disconnect();
      }
      last = millis();
  }
  return pingStatus;
}

void WebPublish() {
  static int PIRSensorTimer;

if((millis()-PIRSensorTimer>5000)) {
    if (mqtt.Update()) {
      pirsensorFeed.publish(PIR_SENSOR_OUTPUT_PIN);
      }

  PIRSensorTimer = millis();
  }
}

Credits

Joeseph Arnoux
3 projects • 7 followers
Deep Dive Artist designing for the CABQ Rail Trail. (2024)
Contact

Comments

Please log in or sign up to comment.