// Adafruit IO IFTTT Example - Gmailbox
// Tutorial Link: https://learn.adafruit.com/gmailbox
//
// Adafruit invests time and resources providing this open source code.
// Please support Adafruit and open source hardware by purchasing
// products from Adafruit!
//
// Written by Brent Rubell for Adafruit Industries
// Copyright (c) 2018 Adafruit Industries
// Licensed under the MIT license.
//
// All text above must be included in any redistribution.
/************************** Configuration ***********************************/
// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <SD.h>
#include <Adafruit_VS1053.h>
// These are the pins used
#define VS1053_RESET   -1     // VS1053 reset pin (not used!)
// a bunch of ifs for different feather boards
// Feather ESP8266
#if defined(ESP8266)
  #define VS1053_CS      16     // VS1053 chip select pin (output)
  #define VS1053_DCS     15     // VS1053 Data/command select pin (output)
  #define CARDCS          2     // Card chip select pin
  #define VS1053_DREQ     0     // VS1053 Data request, ideally an Interrupt pin
// Feather ESP32
#elif defined(ESP32)
  #define VS1053_CS      32     // VS1053 chip select pin (output)
  #define VS1053_DCS     33     // VS1053 Data/command select pin (output)
  #define CARDCS         14     // Card chip select pin
  #define VS1053_DREQ    15     // VS1053 Data request, ideally an Interrupt pin
// Feather Teensy3
#elif defined(TEENSYDUINO)
  #define VS1053_CS       3     // VS1053 chip select pin (output)
  #define VS1053_DCS     10     // VS1053 Data/command select pin (output)
  #define CARDCS          8     // Card chip select pin
  #define VS1053_DREQ     4     // VS1053 Data request, ideally an Interrupt pin
// WICED feather
#elif defined(ARDUINO_STM32_FEATHER)
  #define VS1053_CS       PC7     // VS1053 chip select pin (output)
  #define VS1053_DCS      PB4     // VS1053 Data/command select pin (output)
  #define CARDCS          PC5     // Card chip select pin
  #define VS1053_DREQ     PA15    // VS1053 Data request, ideally an Interrupt pin
#elif defined(ARDUINO_NRF52832_FEATHER )
  #define VS1053_CS       30     // VS1053 chip select pin (output)
  #define VS1053_DCS      11     // VS1053 Data/command select pin (output)
  #define CARDCS          27     // Card chip select pin
  #define VS1053_DREQ     31     // VS1053 Data request, ideally an Interrupt pin
// Feather M4, M0, 328, nRF52840 or 32u4
#else
  #define VS1053_CS       6     // VS1053 chip select pin (output)
  #define VS1053_DCS     10     // VS1053 Data/command select pin (output)
  #define CARDCS          5     // Card chip select pin
  // DREQ should be an Int pin *if possible* (not possible on 32u4)
  #define VS1053_DREQ     9     // VS1053 Data request, ideally an Interrupt pin
#endif
// edit the config.h tab and enter your Adafruit IO credentials
// and any additional configuration needed for WiFi, cellular,
// or ethernet clients.
#include "config.h"
// Import Servo Libraries
#if defined(ARDUINO_ARCH_ESP32)
  // ESP32Servo Library (https://github.com/madhephaestus/ESP32Servo)
  // installation: library manager -> search -> "ESP32Servo"
  #include <ESP32Servo.h>
#else
  //#include <Servo.h>
#endif
#include <Adafruit_NeoPixel.h>
#define LED_PIN 4
#define LED_COUNT 50
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB+NEO_KHZ800);
Adafruit_VS1053_FilePlayer musicPlayer = 
  Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS);
class Pixel
{
  // Class Member Variables
  // These are initialized at startup
  public:
   int bright;      
   int red;
   int green;
   int blue;    
 
  
  public:
  Pixel()
  {
    bright = 0;
    red = 0;
    green = 0;
    blue = 0;
  }
  
  Pixel(int pbright, int pred, int pgreen, int pblue)
  {
  bright = pbright;
  red = pred;
  green = pgreen;
  blue = pblue;
  }
};
Pixel plist[LED_COUNT];
/************************ Example Starts Here *******************************/
// pin used to control the servo
#define SERVO_PIN 14
// Flag's up position, in degrees
#define FLAG_UP 0
// Flag's down position, in degrees
#define FLAG_DOWN 180
// How long to hold the flag up, in seconds
#define FLAG_DELAY 2
// create an instance of the servo class
//Servo servo;
// set up the feeds
AdafruitIO_Feed *tw_feed = io.feed("Sweater2020_feed");
//AdafruitIO_Feed *tw_feed2 = io.feed("Twitter_feed");
bool received_tweet = false;
bool musicIsWorking = true;
bool wifiIsWorking = true;
String tweettext;  // tweets should only be 280 characters
void setup() {
  // start the serial connection
  Serial.begin(115200);
  // wait for serial monitor to open
  while(! Serial);
  Serial.print("IFTTT Twitter");
  // tell the servo class which pin we are using
  //servo.attach(SERVO_PIN);
  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();
  // set up a message handler for the feed.
  // the handleMessage function (defined below)
  // will be called whenever a message is
  // received from adafruit io.
  tw_feed->onMessage(handleMessage);
  // wait for a connection
  int starttime = millis();
  int curtime = millis();
  
  
   while((io.status() < AIO_CONNECTED) &&(curtime <= starttime + 10000))  
   {
     Serial.print(".");
     delay(500);
     curtime = millis();
   }
   if(curtime >= starttime + 10000)
   {
      Serial.println("");
      Serial.println("Couldn't connect to wifi.");
      wifiIsWorking = false;
      pinMode(1, OUTPUT);
      digitalWrite(1, HIGH);
   }
  // we are connected
  if(wifiIsWorking)
  {
    Serial.println();
    Serial.println(io.statusText());
    tw_feed->get();
  }
  strip.begin();
  strip.clear();
  strip.show();
  strip.setBrightness(40);
  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     musicIsWorking = false;
  }
    if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    musicIsWorking = false;  // don't do anything more
  }
  else
  {
    Serial.println("SD OK!");
  }
  
  
  // list files
  printDirectory(SD.open("/"), 0);
  
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(0,0);
  
#if defined(__AVR_ATmega32U4__) 
  // Timer interrupts are not suggested, better to use DREQ interrupt!
  // but we don't have them on the 32u4 feather...
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int
#else
  // If DREQ is on an interrupt pin we can do background
  // audio playing
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
#endif
  
}
void loop() {
  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  int btn;
  btn = analogRead(A0);
  // if button is pressed, cue a random animation
  if(btn > 800)
  {
    Serial.println("Button pressed");
    int r = random(125);
    if(r < 25)
    {
      if(musicIsWorking)
      {
        Serial.println("Playing Mariah Carey!");
        musicPlayer.startPlayingFile("/mariah.mp3");
      }
      xmas();
    }
    else if(r >= 25 && r < 50)
    {
      if(musicIsWorking)
      {
        Serial.println("Playing Cher!");
        musicPlayer.startPlayingFile("/forthelonely.mp3");
      }
      lonely();
    }
    else if(r >= 50 && r < 75)
    {
      if(musicIsWorking)
      {
        Serial.println("Playing The Greatest Showman!");
        musicPlayer.startPlayingFile("/thisisme.mp3");
      }
      rainbow(3);
      strip.clear();
      strip.show();
    delayms(600);
    pulseRainbow(100,3);
    }
    else if(r >= 75 && r < 100)
    {
      if(musicIsWorking)
      {
        Serial.println("Playing Andy Grammer!");
        musicPlayer.startPlayingFile("/dontgiveup2.mp3");
      }
     
      theaterChase(strip.Color(255,0,0),80);
      theaterChase(strip.Color(255,0,255),110);
      theaterChase(strip.Color(0,0,255),110);
      delayms(30);
      strip.clear();
      strip.show();
    }
    else
    {
      if(musicIsWorking)
      {
        Serial.println("Playing Phantom!");
        musicPlayer.startPlayingFile("/masquerade.mp3");
      }
      masks();
      strip.clear();
      strip.show();
        
    }
  }
  // need to include this to poll for tweets
  if(wifiIsWorking)
  {
    io.run();
  }
// manage key words in tweets
  if(received_tweet && (tweettext.indexOf("lonely") >= 0))
  {
    if(musicIsWorking)
    {
      musicPlayer.startPlayingFile("/forthelonely.mp3");
    }
    
    lonely();
    received_tweet = false;
  }
  else if(received_tweet && ((tweettext.indexOf("christmas") >= 0) || (tweettext.indexOf("festive") >= 0)))
  {
    if(musicIsWorking)
    {
      musicPlayer.startPlayingFile("/mariah.mp3");
    }
   
    xmas();
    received_tweet = false;
  }
  else if(received_tweet && (tweettext.indexOf("pride") >= 0))
  {
    if(musicIsWorking)
    {
      musicPlayer.startPlayingFile("/thisisme.mp3");
    }
   
    rainbow(3);
    strip.clear();
    strip.show();
    delayms(600);
    pulseRainbow(100,3);
    received_tweet = false;
  }
  else if(received_tweet && (tweettext.indexOf("mask") >= 0))
  {
    if(musicIsWorking)
    {
      musicPlayer.startPlayingFile("/masquerade.mp3");
    }
    masks();
    strip.clear();
    strip.show();
    received_tweet = false;
  }
  else if(received_tweet && ((tweettext.indexOf("solidarity") >= 0) || (tweettext.indexOf("together") >= 0)))
  {
    if(musicIsWorking)
    {
      musicPlayer.startPlayingFile("/dontgiveup2.mp3");
    }
   
    theaterChase(strip.Color(255,0,0),100);
    theaterChase(strip.Color(255,0,255),100);
    theaterChase(strip.Color(0,0,255),100);
    delayms(30);
    strip.clear();
    strip.show();
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("red") >= 0)
  {
    colorWipe(strip.Color(255,0,0),100);
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("green") >= 0)
  {
    colorWipe(strip.Color(0,255,0),100);
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("blue") >= 0)
  {
    colorWipe(strip.Color(0,0,255),100);
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("cyan") >= 0)
  {
    colorWipe(strip.Color(0,255,255),100);
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("yellow") >= 0)
  {
    colorWipe(strip.Color(255,255,0),100);
    received_tweet = false;
  }
  else if(received_tweet && tweettext.indexOf("magenta") >= 0)
  {
    colorWipe(strip.Color(255,0,255),100);
    received_tweet = false;
  }
}
// this function is called whenever a 'tweet' message
// is received from Adafruit IO. it was attached to
// the twitter feed in the setup() function above.
void handleMessage(AdafruitIO_Data *data) {
  Serial.println("A tweet came in!");
  
  Serial.println(data->value());
  tweettext = String(data->value());
  tweettext.toLowerCase();
  received_tweet = true;
   
}
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}
/// File listing helper
void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}
void xmas()
{
  int r;
  
  for(int i = 0; i < 340;i++)
  {
    r = random(LED_COUNT);
    plist[r].bright = 255;
    plist[r].red = 255;
    r = random(LED_COUNT);
    plist[r].green = 255;
    for(int j = 0; j < LED_COUNT; j++)
    {
      if(plist[j].red < 0)
        plist[j].red = 0;
       if(plist[j].green < 0)
        plist[j].green = 0;
      strip.setPixelColor(j,strip.Color(plist[j].red,plist[j].green,0));
      if(plist[j].red > 0)
       plist[j].red = plist[j].red - 20;
      if(plist[j].green > 0)
       plist[j].green = plist[j].green - 20;
    }
    
    strip.show();
    delayms(40);
    
    
  }
  strip.clear();
  strip.show();
    delayms(20);
}
void lonely()
{
  int r;
  int r2;
  int g;
  int b;
  int counter = 0;
  for(int c = 0; c < LED_COUNT; c++)
  {
    plist[c].red = 0;
    plist[c].blue = 0;
    plist[c].green = 0;
  }
  
  for(int i = 0; i < 1200;i++)
  {
    counter++;
    if(counter > 35)
    {
      for(int q = 0; q < 7; q++)
      {
        r = random(LED_COUNT);
        r2 = random(100);
        g = random(100);
        plist[r].bright = 255;
        plist[r].red = r2;
        plist[r].blue = 255;
        plist[r].green = g;
        counter = 0;
      }
    }
    
    for(int j = 0; j < LED_COUNT; j++)
    {
      if(plist[j].red < 0)
        plist[j].red = 0;
      if(plist[j].green < 0)
        plist[j].green = 0;
      if(plist[j].blue < 0)
        plist[j].blue = 0;
      strip.setPixelColor(j,strip.Color(plist[j].red,plist[j].green,plist[j].blue));
      if(plist[j].red > 0)
       plist[j].red = plist[j].red - 1;
      if(plist[j].green > 0)
       plist[j].green = plist[j].green - 1;
      if(plist[j].blue > 0)
       plist[j].blue = plist[j].blue - 3;
    } 
    strip.show();
    delay(10);
  }
  strip.clear();
  strip.show();
    delay(20);
}
// taken from strandtest example program
void rainbow(int wait) {
  for(int q = 0; q < 2; q++)
  {
    for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
      for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
        
        int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
        
        strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
  strip.clear();
  strip.show();
  delay(1);
}
void pulseRainbow(int wait, int numtimes)
{
  
  int i;
  for (i = 0; i < LED_COUNT; i++)
  {
    switch(i%6){
     case 0:
      plist[i].red = 255;
      plist[i].green = 0;
      plist[i].blue = 0;
      break;
    case 1:
      plist[i].red = 255;
      plist[i].green= 100;
      plist[i].blue = 0;
      break;
    case 2:
      plist[i].red = 255;
      plist[i].green= 255;
      plist[i].blue = 0;
      break;
    case 3:
       plist[i].red = 0;
      plist[i].green= 255;
      plist[i].blue = 0;
      break;
    case 4:
       plist[i].red = 0;
      plist[i].green= 0;
      plist[i].blue = 255;
      break;
    case 5:
      plist[i].red = 255;
      plist[i].green= 0;
      plist[i].blue = 255;
      break;
    }
  }
  
  int b;
  for(int x = 0; x < numtimes; x++)
  {
    for(b = 255; b > 1 ; b-=16)
    {  
      for(i = 0; i < LED_COUNT; i++)
      {
        strip.setPixelColor(i,strip.Color((plist[i].red > b ? plist[i].red-b : 0),
                    (plist[i].green > b ? plist[i].green-b : 0),
                    (plist[i].blue > b ? plist[i].blue-b : 0)));      
      }
      strip.show();
      delay(1);
    }
    for(i = 0; i < LED_COUNT; i++)
      {
        strip.setPixelColor(i,strip.Color(plist[i].red,plist[i].green,plist[i].blue));
      }
      strip.show();
      delay(20);
      
    
    for(b = 1; b < 255; b+=4)
    {
      for(i = 0; i < LED_COUNT; i++)
      {
        strip.setPixelColor(i,strip.Color((plist[i].red > b ? plist[i].red-b : 0),
                    (plist[i].green > b ? plist[i].green-b : 0),
                    (plist[i].blue > b ? plist[i].blue-b : 0)));
      }
      strip.show();
      delay(1);
    }
    delayms(wait);
  }
    strip.clear();
    strip.show();
    delay(1);
}
void delayms(int m)
{
  int starttime = millis();
  int curtime = millis();
  while(starttime + m > curtime)
  {
    yield();
    curtime = millis();
  }
}
void masks()
{
  Pixel mlist[] = {Pixel(0,100,100,0),Pixel(0,120,120,0),Pixel(0,160,160,0),Pixel(0,200,200,0),
      Pixel(0,255,255,0),Pixel(0,255,255,50),Pixel(0,255,255,100),Pixel(0,255,255,150),Pixel(0,255,255,200),
      Pixel(0,255,255,255)};  
  int startpixel = 0;
  int curpixel = 0;
  for(int x = 0; x < 1500; x++)
  {
    strip.clear();
    for(int i = 0; i < 10; i++)
    {
      strip.setPixelColor(curpixel, strip.Color(mlist[i].red,mlist[i].green,mlist[i].blue));
      curpixel++;
      if(curpixel > LED_COUNT)
      {
        curpixel = 0;
      }
    }
    strip.show();
    startpixel++;
    if(startpixel > LED_COUNT)
      startpixel = 0;
  
    curpixel = startpixel;
    delayms(5);
  }  
  
}
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<19; a++) {  // Repeat 40 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delayms(wait);  // Pause for a moment
    }
  }
}
Comments
Please log in or sign up to comment.