// 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