49713 Designing for the Internet of Things
· 18 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Found in Diot 2019 - Final Project Connected Studio · UNLISTED (SHOWN IN POOLS)
Frustrated by messes being left around the studio? Feeling tired after long group meetings and stressful project work? Bump! has the answer by creating a fun way to gamify the cleaning up experience through a hide and seek type game, allowing students to forget the menial tedium involved with the cleaning task.
We wanted to create a shared experience within the studio to help diffuse stress, create fun, and get students active in the space. We’ve sought to do this through a game of hide and seek with connected objects in the studio to gamify the cleanup experience.
We were seeking to create a quick, easy game that allows students to disconnect from long meetings and get the blood flowing again. We wanted to gamify otherwise mundane activities that people aren’t otherwise motivated to engage in.
We used a rapid brainstorming technique to generate words to fit a script to help guide our ideas. We used a randomized cycle website to get unique combinations of the words we came up with and worked in pairs to develop concept ideas based on these combinations. We sought to use visual cues with Neo-pixel strips to signal elements of the game to those playing, as well as sound once the code was flashed.
We initially developed a connected system to send and receive events with a musical chairs game through an Alexa skill app. We then pivoted to a hide and seek concept game with location sharing, connected objects in the studio that still use the visual and audio cues from our initial concept with sent texts to confirm the event being received and starting the game.
Using the big ball seat as a starting point with a velostat pressure switch on top, it sent a signal through the particle cloud to trigger the other hidden objects. The others being a light with a neopixel attached, a buzzerbox, and a flag stand that visually signals the user.
Within a certain range and a limited number of objects, this code structure should work well and fulfil its desired function. Especially as a rough cut prototype, trying to incorporate too many objects over too far of distances would increase delays in flashing the code, limiting its scope and viability to smaller contexts.
It could turn into a more powerful reminder to clean up and maintain the studio space and become scalable to other studios by providing value in differently situated studio spaces. Personal items could be attached to the visual indicator within a certain zone and allow students to locate missing items or play a game with their own items. Talking to other groups such as ForgetMeNot we could think of combining our projects to create one valuable item location system.
This process has been challenging as we started with one concept but quickly pivoted to another after we encountered difficulties working with Alexa and IFTTT in our initial concept. We were able to maintain the original spirit of our idea with our new concept and implemented in a fun, casual way. However, our idea is very rough and could use more thought to expand its usefulness and value. The cleanup idea in a kids area or gym space is one meaningful application that our concept could expand into with more time, development, and funding.
Within the studio space, it could potentially be adapted to include more of a knowledge function rather than just cleanup. Adding in a social aspect of directing people to others with specialized knowledge or having someone follow tasks instead of just simple buttons would put an aspect to it that would allow the user to gain some value from it and not just a mindless exercise. There is a lot this could potentially segway into and although it was hard to see it at the beginning, getting other perspectives and ideas helped further our own intuition and curiosity regarding the potential.
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#define PIXEL_PIN D6
#define PIXEL_COUNT 9
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE); //Lamp
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
int direction = 0 ; // direction state, +1, 0 or -1
// This value will store the last time we published an event
long lastPublishedAt = 0;
// this is the time delay before we should publish a new event
// from this device
int publishAfter = 10000;
String check = "step0";
int distance = 0;
bool gameState = false;
// DO NOT CHANGE THIS
String sharedEventName = "diot/2019/smartstudio/";
String flagEventName = "diot/2019/smartstudio/flag";
//set up button
int buttonPin = D3;
bool buttonState = HIGH;
int brightness = 20;
void setup()
{
Particle.variable("distance", distance);
Particle.subscribe( "diot/2019/smartstudio/flag", handleSharedEvent );
Particle.subscribe( "diot/2019/smartstudio/lamp", handleSharedEvent ); // Lamp
Particle.variable("checking", check);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode( buttonPin , INPUT_PULLUP); // sets pin as input
myservo.attach(D2); // attach the servo on the D2 pin to the servo object
myservo.write(25); // test the servo by moving it to 25°
}
void loop()
{
int volts_1 = analogRead(A0);
//int calculated = (6762/(reading-9))-4;
int volts = (3.3*(volts_1-900))/2000; // value from sensor * (5/1024)
int distance = 320/(1+10*volts);
// int distance = 13*pow(volts, -1); // worked out from datasheet graph
uint16_t i;
uint32_t c = strip.Color(219, 101, 255);
uint32_t w = strip.Color(255, 255, 255);
uint32_t d = strip.Color(0,0,0);
uint32_t r = strip.Color(255,0,0);
buttonState = digitalRead( buttonPin );
if(distance<15){
publishEndEvent();
gameState = false;
}
//turn off light, LAMP EVENT
if (buttonState == LOW){
publishFlagEvent();
gameState = false;
for (i=0; i< strip.numPixels() ; i++ ){
strip.setPixelColor(i,d);
}
strip.show();
delay(1000);
}
Particle.publish("volts", String(volts));
Particle.publish("distance", String(distance));
if(gameState){
myservo.write(0); // move servo to 0° - ding!
delay(500); // wait 100 ms
myservo.write(45);
delay(500); // wait 100 ms
for (i=0; i< strip.numPixels() ; i++ ){
strip.setPixelColor(i,c);
}
strip.show();
delay(1000);
}
}
void publishEndEvent()
{
// 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() )
{
String eventName = sharedEventName + "end/" + System.deviceID();
// then we share it out
Particle.publish( eventName, "Congrats!" );
lastPublishedAt = millis();
}
}
void publishFlagEvent() //Flag
{
// 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() )
{
String eventName = sharedEventName + "flag/" + System.deviceID();
// then we share it out
Particle.publish( eventName, "Move to next event" );
lastPublishedAt = millis();
}
}
// Our event handlde requires two bits of information
// This gives us:
// A character array that consists of the event name
// A character array that contains the data published in the event we're responding to.
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;
}
if(eventName.startsWith("diot/2019/smartstudio/flag")){
gameState = true;
}
// otherwise do your stuff to respond to
// the paired device here
//motorOn = true;
}
Click to Expand
const int buttonPin = 5; // the number of the pushbutton pin
const int motorPin = 6; // the number of the LED pin
long lastPublishedAt = 0;
int publishAfter = 10000;
bool gameState = false;
// variables will change:
// variable for reading the pushbutton status
int buttonState = HIGH;
void setup() {
// initialize the LED pin as an output:
pinMode(motorPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT_PULLUP);
Particle.subscribe( "diot/2019/smartstudio/start" , handleSharedEvent );
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if (buttonState == LOW){
publishLampEvent();
digitalWrite(motorPin, LOW);
gameState = false;
}
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (gameState) {
digitalWrite(motorPin, HIGH);
delay(50);
} else {
// turn LED off:
digitalWrite(motorPin, LOW);
}
}
void publishLampEvent() // Publish function for the ending event
{
// check that it's been 10 secondds since our last publish
if( lastPublishedAt + publishAfter < millis() )
{
String eventName = "diot/2019/smartstudio/lamp" + System.deviceID();
// then we share it out
Particle.publish( eventName, "data goes here" );
// 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){ // Only need one handle event function for both events
// Let's check the event name
String eventName = String( event ); // convert to a string object
// 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;
}
if(eventName.startsWith("diot/2019/smartstudio/start")){
gameState = true;
}
}
Click to Expand
This project is only listed in this pool. Be considerate and think twice before sharing.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Frustrated by messes being left around the studio? Feeling tired after long group meetings and stressful project work? Bump! has the answer by creating a fun way to gamify the cleaning up experience through a hide and seek type game, allowing students to forget the menial tedium involved with the cleaning task.
March 7th, 2019