Living Pictures Code
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include <math.h>
// NEOPIXEL VARIABLES
#define PIXEL_COUNT 4
#define PIXEL_PIN D7
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
// INPUT VARIABLES
int inputPins[] = {D2,D3,D4,D5}; // TOP, RIGHT, BOTTOM, LEFT
bool inputState[] = {false,false,false,false};
// EVENT VARIABLES
long lastPublishedAt = 0;
int publishAfter = 100;
String eventRoot = "diot/2019/css/livingpictures/";
// LED FUNCTIONS WILL MAKE GOOD USE OF THESE
bool home[] = {false,false,false,false};
long hTime[] = {millis(),millis(),millis(),millis()};
bool away[] = {false,false,false,false};
long aTime[] = {millis(),millis(),millis(),millis()};
int red[] = {0,0,0,0};
int blue[] = {0,0,0,0};
int green[] = {0,0,0,0};
int frames = 4;
// ADSR VARIABLES
double attackLevel = 1.0;
double sustainLevel = 0.5;
double vibratoRate = 1000.0;
long attackTime = 3000;
long decayTime = 5000;
long releaseTime = 10000;
//ENDED UP NOT USING THE ADSR FUNCTION
double ADSR(int clr, bool press, double pressTime) {
double v = 0.5;
if(press) {
// ATTACK
if((millis() - pressTime) < attackTime) {
v = double(millis() - pressTime) / double(attackTime);
v = 1 - ((1 - v) * (1-v));
v = (0.0 * v) + (attackLevel * (1-v));
} else {
//SUSTAIN
v = 0.5 + double(sustainLevel * sin(float(millis()/vibratoRate)));}
} else
//RELEASE
{
v = (clr / 255.0) - (1.0/double(releaseTime));
if (v < 0.0) {
v = 0.0;
}
}
return v;
}
void setup()
{
// I/O PINS SETUP
pinMode(PIXEL_PIN, OUTPUT);
for(int i = 0; i < frames; i++) {
pinMode(inputPins[i], INPUT);
}
// NEOPIXEL INITIALIZE
strip.begin();
for(int i = 0; i < frames; i++) {
setRGBColor(i,0,255,0);
}
strip.show();
strip.setBrightness(255);
// HELPS CAPACITIVE TOUCH SENSOR SETTLE
delay(2000);
for(int i = 0; i < frames; i++) {
setRGBColor(i,0,0,0);
}
strip.show();
// EVENT SUBSCRIPTION
Particle.subscribe(eventRoot, handleSharedEvent );
}
void loop()
{
//Checks Strips for touch, publishes event if touch detected or if touch no longer exists
for(int i=0;i<frames;i++){
int buttonState = digitalRead( inputPins[i] );
if( buttonState == LOW)
{
if(!inputState[i]) {
//FIRST TOUCH DETECTED
inputState[i] = true;
String j = String(i);
publishMyEvent( j + "N");
}
}else{
if(inputState[i]) {
//TOUCH FINALIZED
inputState[i] = false;
String j = String(i);
publishMyEvent( j + "F");
}
}
delay(5);
}
//Update lights depending on status
for(int i=0;i<frames;i++){
int redColor = red[i];
int blueColor = blue[i];
int greenColor = green[i];
if(home[i] && away[i]) {
//Both sides are touching the same side of the frame
blueColor = 255;
redColor = 255;
float val = (exp(sin(millis()/2000.0*M_PI)) - 0.36787944)*108.0;
redColor = int(val);
blueColor = int(val);
} else{
if(away[i]) {
redColor = 255;
} else { redColor = int(redColor * 0.9);}
if(home[i]) {
blueColor = 255;
} else { blueColor = int(blueColor * 0.9);}
}
red[i] = redColor;
blue[i] = blueColor;
green[i] = greenColor;
uint32_t c = strip.Color(redColor, 0, blueColor);
strip.setPixelColor(i, c);
strip.show();
}
}
/* if((millis()-pressTime) > 7000)
{
setRGBColor(0,0,0);
strip.setBrightness(255);
}
if(millis()-updateTime > 1000 && (millis()-pressTime) < 7000){
updateTime = millis();
int nw = int(brightness * 0.6);
Particle.publish( "Brightness", "Seema" );
strip.setBrightness(nw);
strip.show(); */
void setRGBColor(int p, int r, int g, int b ){
strip.setPixelColor(p, r, g, b);
}
void publishMyEvent(String data)
{
// Remember that a device can publish at rate of about 1 event/sec,
// with bursts of up to 4 allowed in 1 second.
// Back to back burst of 4 messages will take 4 seconds to recover.
// So we want to limit the amount of publish events that happen.
// check that it's been 10 secondds since our last publish
if( lastPublishedAt + publishAfter < millis() )
{
// Remember our subscribe is matching "db2018/paired/"
// We'll append the device id to get more specific
// about where the event came from
// System.deviceID() provides an easy way to extract the device
// ID of your device. It returns a String object of the device ID,
// which is used to identify your device.
String eventName = eventRoot + System.deviceID();
// now we have something like "diot/2019/paired/0123456789abcdef"
// and that corresponds to this devices info
// then we share it out
Particle.publish( eventName, data );
// And this will get shared out to all devices using this code
// we just pubished so capture this.
lastPublishedAt = millis();
}
}
// MESSAGE DATA PARSER FUNCTIONS
int parseMessageIndex(String data){
if(data.indexOf("0") != -1) {
return 0;
}
if(data.indexOf("1") != -1) {
return 1;
}
if(data.indexOf("2") != -1) {
return 2;
}
if(data.indexOf("3") != -1) {
return 3;
}
return 4; // Means something is wrong
}
bool parseMessageStatus(String data){
if(data.indexOf("N") != -1) {
return true;
}
if(data.indexOf("F") != -1) {
return false;
}
return false;
}
// SETTERS FOR HOME & AWAY ARRAYS
void setHomeStatus(int i, bool s){
if(s) {
hTime[i] = millis();
}
home[i] = s;
}
void setAwayStatus(int i, bool s){
if(s) {
aTime[i] = millis();
}
away[i] = s;
}
void handleSharedEvent(const char *event, const char *data)
{
String eventName = String( event ); // convert to a string object
String eventData = String( data ); // convert to a string object
String deviceID = System.deviceID();
// Parse message to get necessary information
int index = parseMessageIndex(eventData);
bool status = parseMessageStatus(eventData);
if( eventName.indexOf( deviceID ) != -1 ){
//Change the information on corresponding pixel
setHomeStatus(index,status);
return;
}
//Change the information on corresponding pixel
setAwayStatus(index,status);
}
Cem
Click to Expand
Content Rating
Is this a good/useful/informative piece of content to include in the project? Have your say!
You must login before you can post a comment. .