Primary Circuit
//Created by Langley V, Swapnil A, and Ussama N on 11/17/2019
//Creative Project II
//Last edited: 11-26-2019
// This #include statement was automatically added by the Particle IDE.
#include <DFPlayer.h>
DFPlayer dfPlayer;
int folder = 0;
int volume = 0;
bool powerOn = false;
//********************************************************************
//Neopixel
//********************************************************************
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
//Set pixel pin, number of pins, and type
#define PIXEL_PIN D2
#define PIXEL_COUNT 7
#define PIXEL_TYPE WS2812
const uint8_t KEYFRAMES[] = {
// Rising
20, 21, 22, 24, 26, 28, 31, 34, 38, 41, 45, 50, 55, 60, 66, 73, 80, 87, 95,
103, 112, 121, 131, 141, 151, 161, 172, 182, 192, 202, 211, 220, 228, 236,
242, 247, 251, 254, 255,
// Falling
254, 251, 247, 242, 236, 228, 220, 211, 202, 192, 182, 172, 161, 151, 141,
131, 121, 112, 103, 95, 87, 80, 73, 66, 60, 55, 50, 45, 41, 38, 34, 31, 28,
26, 24, 22, 21, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
};
int keyframePointer = 0;
int numKeyframes = sizeof(KEYFRAMES) - 1;
//define neopixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
//Global variable delcaration
//int timeDuration;
//Declare booleans that go along with the message received from the sender
bool displayNotif = false; //calendar event boolean
bool isRunning = false;
long timeStartedAt = -1;
int timeElapsed = -1;
//Define colorOff: 0,0,0
uint32_t colorOff = strip.Color( 0, 0, 0 );
//********************************************************************
//Publishing Events
//********************************************************************
// This value will store the last time we published an event
long lastPublishedAt = 0;
int last_published = -1;
//********************************************************************
//Flex Sensor
//********************************************************************
int flexPin = A0;
int flexReading = 0;
//********************************************************************
//LED indicator
//********************************************************************
//int ledPin = A1;
int RedPin = D5; //To identify the state of the RED Button
int GreenPin = D3; //To identify the state of the GREEN Button
int YellowPin = D4; //To identify the state of the YELLOW Button
int BluePin = D6; //To identify the state of the BLUE Button
int RedButton = A1; //For recording the Message
int GreenButton = A2; //For sending the Message
int YellowButton = A3; //For saving the Message
int BlueButton = A4; //For listening to the Message
int publishAfter = 10000;
//High = 1;
int RedButtonState = 0;
int GreenButtonState = 0;
int YellowButtonState = 0;
int BlueButtonState = 0;
bool messageExists = false;
int PreviousRBS = 0;
bool messageHeared = false;
int here = 0;
void setup() {
//another event starts, stop current event and then reset timer, then start over.
Particle.function("startNotif", startNotif);
Particle.function("endNotif", endNotif);
//Code initialization
strip.begin();
strip.show();
//strip.setBrightness(30); //dim lights
//get time particle io started at
timeStartedAt = millis();
//initial color, Yellow glow
uint32_t c = strip.Color(0, 255, 255);
//reset all the colors
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
delay(100);
}
strip.show();
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, colorOff);
delay(100);
}
strip.show();
//********************************************************************
//Declare pin modes for flex, speaker and LED
pinMode(flexPin, INPUT);
pinMode( RedButton , INPUT_PULLUP ); // sets pin as input
pinMode( GreenButton , INPUT_PULLUP); // sets pin as input
pinMode( YellowButton , INPUT_PULLUP); // sets pin as input
pinMode( BlueButton , INPUT_PULLUP); // sets pin as input
pinMode( RedPin , OUTPUT ); // sets pin as output
pinMode( GreenPin , OUTPUT ); // sets pin as output
pinMode( YellowPin , OUTPUT ); // sets pin as output
pinMode( BluePin , OUTPUT ); // sets pin as output
dfPlayer.setLogging(true);
volume = dfPlayer.getVolume();
delay(5000);
Particle.variable("force", flexReading);
Particle.subscribe("swapnil/2019/enchantedBook/" , handleSharedEvent);
Particle.subscribe("langley/2019/iot/enchantedBookMessage/" , handleSharedEventSpeaker);
Particle.variable("RedState", RedButtonState);
Particle.variable("PreviousRBS", PreviousRBS);
Particle.variable("GreenState", GreenButtonState);
Particle.variable("BlueButtonState", BlueButtonState);
Particle.variable("Here", here);
Particle.variable("force", flexReading);
Particle.variable("folder", folder);
Particle.variable("volume", volume);
Particle.variable("power", powerOn);
Particle.function("setVolume", setVolume);
Particle.function("playFolder", playFolder);
Particle.function("setPower", setPower);
setVolume("20");
setPower("true");
folder = 1;
delay(200);
//dfPlayer.playTrack(1);
PlayMessage();
delay(1000);
//playFolder(String(folder));
}
void loop() {
//Get flex sensor reading
flexReading = analogRead(flexPin);
//delay(100);
RedButtonState = digitalRead( RedButton );
GreenButtonState = digitalRead( GreenButton );
YellowButtonState = digitalRead( YellowButton );
BlueButtonState = digitalRead( BlueButton );
//Recording the Message
if( PreviousRBS == HIGH && RedButtonState == LOW)
{
//Start recording
digitalWrite( RedPin, HIGH); // turn the LED On
PreviousRBS = RedButtonState;
messageExists = true;
}
else if(PreviousRBS == LOW && RedButtonState == HIGH)
{
//Stop recording
digitalWrite( RedPin, LOW); // turn the LED Off
}
PreviousRBS = RedButtonState;
//Sending the Message
if( GreenButtonState == LOW && messageExists == true )
{
digitalWrite(GreenPin, HIGH);
delay(100);
digitalWrite(GreenPin, LOW);
SendMessage();
delay(2000);
// delay for a bit
messageExists = false;
}
else
{
digitalWrite( GreenPin, LOW);
}
//If there is a message waiting, go into this loop
if(displayNotif) {
//CASE 1: GLOW
//If there is a message and the flex sensor is bent (book is closed)
if(flexReading > 700) {
for (int i = 0; i < strip.numPixels(); i++) {
uint8_t color = (127 * KEYFRAMES[keyframePointer]) / 256;
strip.setPixelColor(i, 0, 0, color);
}
strip.show();
// Increment the keyframe pointer.
if (++keyframePointer > numKeyframes) {
// Reset to 0 after the last keyframe.
keyframePointer = 0;
}
}
//CASE 2: PLAY MESSAGE
//There is a notification and the book is opened
else if(flexReading < 700) {
//LED glows because there is a message
digitalWrite( BluePin, HIGH);
//delay(1000);
// delay(100);
// PlayMessage();
// delay(4000);
// digitalWrite( BluePin, LOW);
//Play message
if(BlueButtonState == LOW )
{
Particle.publish("bluebutton", "low-prev-high");
here = 1;
PlayMessage();
delay(100);
displayNotif = false;
messageHeared = true;
digitalWrite( BluePin, LOW);
}
//Set notification back to false, message has been heard
//displayNotif = false;
isRunning = false;
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0, 0, 0);
}
strip.show();
//digitalWrite( BluePin, LOW);
}
else {
//do nothing
//return;
}
}
// NO message, do nothing
else {
//do nothing
}
//Save the Message
if(YellowButtonState == LOW && messageHeared == true)
{
// store the time when you last published
int last_published = -1;
digitalWrite(YellowPin, HIGH);
delay(500);
SaveMessage();
messageHeared = false;
}
else
{
digitalWrite( YellowPin, LOW);
}
delay(500);
}
//Particle Functions that change boolean value to true or false
//For now, have console "send the message" to this particle board that there is a message
//Next steps: Use another particle board to publish an event and use this particle board to receive it
bool startNotif(String val) {
//if it is not running then start it
if (!isRunning) {
//timeStartedAt = millis(); //reset time
displayNotif = true;
isRunning = true;
//goes into loop and runs light code
}
//A calendar event ambient notification is already running
else {
//Stop what is happening
//turn all off
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, colorOff);
delay(50);
}
strip.show();
}
}
//End the message notification
bool endNotif(String val) {
//turn all off
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, colorOff);
delay(50);
}
strip.show();
//no ambient notification
displayNotif = false;
//code is not running
isRunning = false;
}
void SendMessage()
{
// 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 = "langley/2019/iot/sendenchantedBookMessage/" + 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, "Message_Sent" );
// And this will get shared out to all devices using this code
// we just pubished so capture this.
lastPublishedAt = millis();
}
}
//Notify other person
void ReceivedMessage()
{
// 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 = "langley/2019/iot/receivedenchantedBookMessage/" + 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, "Message_Sent" );
// And this will get shared out to all devices using this code
// we just pubished so capture this.
lastPublishedAt = millis();
}
}
//Write data to spreadsheet
void SaveMessage() {
// check if 1 minute has elapsed
if( last_published + 10000 < millis() ){
Particle.publish( "messageLogged", String("Hi-I-love-youuuu") );
last_published = millis();
}
}
//
int playFolder(String buffer) {
folder = atoi(buffer);
// the following commands play 6 tracks that were stored in the root folder of the TFCard
// the dfPlayer.playTrack method uses DFPlayer command 0x03
// The tracks were named 001 - 006.
// The tracks were added to the TFCard in the following sequence 001, 002, 003, 005, 004, and 006
// This code plays the tracks in order 001 - 006
delay(3000);
dfPlayer.playTrack(1);
delay(3000);
dfPlayer.playTrack(2);
delay(7000);
return 0;
}
void PlayMessage()
{
// 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 second 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 = "langley/2019/iot/playMessage/" + 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, "Message_Sent" );
// And this will get shared out to all devices using this code
// we just pubished so capture this.
lastPublishedAt = millis();
}
}
void handleSharedEvent(const char *event, const char *data)
{
// Now we're getting ALL events published using "db2018/paired/"
// This includes events from this device.
// So we need to ignore any events that we sent.
// Let's check the event name
String eventName = String( event ); // convert to a string object
// This gives us access to a bunch of built in methods
// Like indexOf()
// Locates a character or String within another String.
// By default, searches from the beginning of the String,
// but can also start from a given index,
// allowing for the locating of all instances of the character or String.
// It Returns: The index of val within the String, or -1 if not found.
// We can use this to check if our event name contains the
// id of this device
String deviceID = System.deviceID();
// device id = 0123456789abcdef
// event = "diot/2019/paired/0123456789abcdef"
if( eventName.indexOf( deviceID ) != -1 ){
// if we get anything other than -1
// the event came from this device.
// so stop doing stuff
return;
}
displayNotif = true;
delay(1000);
ReceivedMessage();
}
void handleSharedEventSpeaker(const char *event, const char *data)
{
// Now we're getting ALL events published using "db2018/paired/"
// This includes events from this device.
// So we need to ignore any events that we sent.
// Let's check the event name
String eventName = String( event ); // convert to a string object
// This gives us access to a bunch of built in methods
// Like indexOf()
// Locates a character or String within another String.
// By default, searches from the beginning of the String,
// but can also start from a given index,
// allowing for the locating of all instances of the character or String.
// It Returns: The index of val within the String, or -1 if not found.
// We can use this to check if our event name contains the
// id of this device
String deviceID = System.deviceID();
// device id = 0123456789abcdef
// event = "diot/2019/paired/0123456789abcdef"
if( eventName.indexOf( deviceID ) != -1 ){
// if we get anything other than -1
// the event came from this device.
// so stop doing stuff
return;
}
digitalWrite(GreenPin, HIGH);
delay(200);
digitalWrite(GreenPin, LOW);
delay(200);
}
// setVolume is a Particle method that can be used to adjust volume via the Particle Console
int setVolume(String buffer) {
volume = atoi(buffer);
dfPlayer.setVolume(volume);
return 0;
}
// setPower is a Particle method that that plays a gong when power is toggled false, and chirping birds when power is toggned true
bool setPower(String buffer) {
if ((buffer[0] == 'f') && (powerOn == true)) {
powerOn = false;
dfPlayer.playFolderTrack(1,2);
}
if ((buffer[0] == 't') && (powerOn == false)) {
powerOn = true;
dfPlayer.playFolderTrack(1,1);
}
return powerOn;
}
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. .