Ariani Gomez
Published

Lane Tech HS - Solar Flare Clock

Synced up with NASA's API, my LED strip will create a light show of colors during the beginning, peak, and end of a Solar Flare event.

BeginnerFull instructions provided4 hours222
Lane Tech HS - Solar Flare Clock

Things used in this project

Hardware components

Argon
Particle Argon
×1
WS2812B LED strip
×1
Male/Male Jumper Wires
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE
NASA DONKI API

Story

Read more

Schematics

Circuit Diagram

Circuit Schematic

Code

Solar Flare

C/C++
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)

unsigned long lastSync = millis();
String d;
String m;
int bHour;
int bMin;
int pHour;
int pMin;
int eHour;
int eMin;

String bH;
String bM;
String d1;
String pH;
String pM;
String d2;
String eH;
String eM;

unsigned long currMonth;
unsigned long currDay; 
unsigned long currHour; 
unsigned long currMin; 

bool stripRan=false;
void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t r, uint32_t l,uint32_t rr, uint32_t ll,uint8_t wait);
void rainbowCycle(uint8_t wait);
void breathing(uint8_t r, uint8_t g, uint8_t b);
uint32_t Wheel(byte WheelPos);
void colorDot(uint32_t r, uint32_t l, uint8_t wait);



SYSTEM_MODE(AUTOMATIC);

// Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 144
#define PIXEL_PIN D5
#define PIXEL_TYPE WS2812B


Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);


void setup() 
{    
    // Subscribe to the integration response event
    Particle.subscribe("hook-response/flare/0", myHandler, MY_DEVICES);
    Serial.begin(9600);
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'
    //Sync time check to my actual time zone
    Time.zone(-6);
}

void myHandler(const char *event, const char *data)
{
    String dataStr  = String(data);
    char strBuffer[53] = "";
    dataStr.toCharArray(strBuffer,53);
    
    //all the d's are irrelevant, just the date repeated so I could get the actual times
    String d = strtok(strBuffer, "T");
    //beginning, peak, and end: hour/min 
    bH= strtok(NULL, ":");
    bM = strtok(NULL, "Z");
    d1 = strtok(NULL, "T");
    pH = strtok(NULL, ":");
    pM = strtok(NULL, "Z");
    d2 = strtok(NULL, "T");
    eH = strtok(NULL, ":");
    eM = strtok(NULL, "Z");
    
    if(bH.indexOf("0")==0)
    {
        bH=bH.remove(0,1);
    }
    if(bM.indexOf("0")==0)
    {
        bM=bM.remove(0,1);
    }
    if(pH.indexOf("0")==0)
    {
        pH=pH.remove(0,1);
    }
    if(pM.indexOf("0")==0)
    {
        pM=pM.remove(0,1);
    }
    if(eH.indexOf("0")==0)
    {
        eH=eH.remove(0,1);
    }
    if(eM.indexOf("0")==0)
    {
        eM=eM.remove(0,1);
    }
    //checking data
    Serial.println(dataStr);
    Serial.println(bH);
    Serial.println(bM);
    Serial.println(pH);
    Serial.println(pM);
    Serial.println(eH);
    Serial.println(eM);
    

    
}

void loop() 
{
    bHour=bH.toInt();
    bMin=bM.toInt();
    pHour=pH.toInt();
    pMin=pM.toInt();
    eHour=eH.toInt();
    eMin=eM.toInt();
    //Sync time every 24 hours
    if (millis() - lastSync > ONE_DAY_MILLIS) 
    {
        // Request time synchronization from the Particle Device Cloud
        Particle.syncTime();
        lastSync = millis();
    }
    
    currMin=Time.minute();
    currHour=Time.hour();
    
    //if it is currently 1:01 a.m, get yesterday's date for the start variable in my web hook
    //and then publish "flare" so data can be used for LEDs
    if(currHour == 1 && currMin ==1)
    {
        int month = Time.month();
        int day = Time.day();
        if (day==1)
        {
            if (month==3)
            {
              d ="28";
              month--;
            }
            else if(month==1)
            {
              month=12;
            }
            else 
            {
              d ="30";
              month--;
            }
        }
        else if (day<11)
        {
          d ="0" + String(day-1);   
        }
        else
        {
          d = String(day-1);
        }
        if (month<10)
        {
          m ="0" + String(month);
        }
        else
        {
          m = String(month);
        }
       
        
        String start = "2021-"+ m +"-"+ d;
        Particle.variable("start", start);
        Particle.publish("flare", PRIVATE);
    }   
    }   
    if(stripRan == false)
    {
        colorAll(strip.Color(220, 20, 60), 150);
    }
    
    if((currHour == bHour)||(currHour == pHour)||(currHour == eHour))
    {
        if(bMin<=currMin&& currMin<pMin)
        {
            colorWipe(strip.Color(255, 0, 0), strip.Color(255,69,0),strip.Color(249, 166,2),strip.Color(252, 209, 42), 15);
            stripRan=true;
        }
        else if(currMin==pMin)
        {
            rainbowCycle(10);
            
        }
        else if(pMin<currMin&&currMin<=eMin)
        {
            colorDot(153, 204, 59);
        }
    }
    
    if((currHour >= eHour) && (currMin > eMin) && (stripRan != false))
    {
        breathing(0,155, 155);
    }


    
}

//colors the whole strip one color
void colorAll(uint32_t c, uint8_t wait) 
{
  uint16_t i;
  for(i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(wait);
}

// Fill the dots one after the other with a color, wait (ms) after each one
// cycles through four different colors
void colorWipe(uint32_t r, uint32_t l,uint32_t rr, uint32_t ll,uint8_t wait) 
{
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, r);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, l);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, rr);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, ll);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
}


// cycles through whole rainbow evenly
void rainbowCycle(uint8_t wait) 
{
  uint16_t i, j;
   // 1 cycle of all colors on wheel
  for(j=0; j<256; j++) 
  {
    for(i=0; i< strip.numPixels(); i++) 
    {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) 
{
  if(WheelPos < 85) 
  {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } 
  else if(WheelPos < 170) 
  {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } 
  else 
  {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

//brightness dims and brightens, like the breathing cyan on the Argon
void breathing(uint8_t r, uint8_t g, uint8_t b)
{
    strip.setPixelColor(144, r, g, b);
    for (int i=50; i<200; i++) 
    {
        strip.setBrightness(i); 
        strip.show(); 
        delay(1); 
    }
    for (int i=200; i>50; i--) 
    { 
        strip.setBrightness(i); 
        strip.show(); 
        delay(1);  
    }
}
//lights up a singular LED on the strip
void colorDot(uint32_t r, uint32_t l, uint8_t wait) 
{
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, r);
    strip.show();
    strip.clear();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, l);
    strip.show();
    strip.clear();
    delay(wait);
  }
  strip.clear();
  strip.show();
}
    
    

LED

C/C++
Just the LED code
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>


void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t r, uint32_t l,uint32_t rr, uint32_t ll,uint8_t wait);
void colorDot(uint32_t r, uint32_t l, uint8_t wait); 
void rainbowCycle(uint8_t wait);
void breathing(uint8_t r, uint8_t g, uint8_t b);
uint32_t Wheel(byte WheelPos);



SYSTEM_MODE(AUTOMATIC);

// Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 144
#define PIXEL_PIN D5
#define PIXEL_TYPE WS2812B


Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);



void setup() 
{
    Serial.begin(9600);
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'

}

void loop() 
{
  //call functions here
}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) 
{
  uint16_t i;
  for(i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(wait);
}

// fill the dots one after the other with a color, wait (ms) after each one
//cycles through 4 different colors
void colorWipe(uint32_t r, uint32_t l,uint32_t rr, uint32_t ll,uint8_t wait) 
{
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, r);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, l);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, rr);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, ll);
    strip.show();
    delay(wait);
  }
  strip.clear();
  strip.show();
}

//one dot on the strip lights up around the strip
void colorDot(uint32_t r, uint32_t l, uint8_t wait) 
{
  for(uint16_t i=0; i<strip.numPixels(); i++) 
  {
    strip.setPixelColor(i, r);
    strip.show();
    strip.clear();
    delay(wait);
  }
  strip.clear();
  strip.show();
  for(uint16_t i=strip.numPixels(); i>0; i--) 
  {
    strip.setPixelColor(i, l);
    strip.show();
    strip.clear();
    delay(wait);
  }
  strip.clear();
  strip.show();
}


// cycle through whole rainbow evenly
void rainbowCycle(uint8_t wait) 
{
  uint16_t i, j;
   // 1 cycle of all colors on wheel
  for(j=0; j<256; j++) 
  {
    for(i=0; i< strip.numPixels(); i++) 
    {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) 
{
  if(WheelPos < 85) 
  {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } 
  else if(WheelPos < 170) 
  {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } 
  else 
  {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

//brightness dims and brightens, like the breathing cyan on the Argon
void breathing(uint8_t r, uint8_t g, uint8_t b)
{
    strip.setPixelColor(144, r, g, b);
    for (int i=20; i<150; i++) 
    {
        strip.setBrightness(i); 
        strip.show(); 
        delay(25); 
    }
    for (int i=150; i>20; i--) 
    { 
        strip.setBrightness(i); 
        strip.show(); 
        delay(25);  
    }
}

Credits

Ariani Gomez

Ariani Gomez

3 projects • 2 followers

Comments

Add projectSign up / Login