Our creative project is to help friends and couples connect with each other in a subtle and fun way. The device is a basic 8 by 8 square LED matrix and serves as a canvas for both sides to draw.

0

Introduction

Our creative project is to help friends/couples connect with each other in a subtle and fun way. There will be 64 LED pixels (8x8) attached in this installation. Each person can light up 1 pixel a day to make a drawing together. If one person stops responding for over a day, the lights on both sides will be turned off and the game will start over. If either side feels the drawing is completed, they can press the button to stop and restart the game, and at the same time, the drawing will be archived and sent to both sides as a memory. The little cubic stature can be a nice decoration on your desk, as well as a vessel to carry social interactive experiences. With Pixel Away, friends or couples who are far from each other can be just pixels away through shared experience on the same canvas.

Slow Game designed by Bertran is our inspiration for PixelAway. Other than the romance of Slow Game, Pixel Away is a social game that involves two people to play. Users can be friends, lovers, and families. (http://www.ishback.com/slowgames/index.html)

0

Storyboard


0

Process

Step 1: First Working Prototype with Neopixel

For our first working prototype, we want to create a set of two connected Neopixel devices. If one presses the button, the corresponding LED will light up on both devices.

Step 2: Get Familiar with LED Matrix

To learn how LED matrix works, we referred to the code and examples by Chrisloris ( https://github.com/chrisloris/LedControl-MAX7219-MAX7221). In this step, we successfully implemented a simple demo in which we can control the movement of LED dots on the matrix. Here is the code for this step:


Step 3: Connect Two Devices



Step 4: Design the Cubes

We made two boxes with foam board and used them as the containers of all the components. To make the product more adorable, we painted each cube with different colors.



Step 5: Assemble the Final Prototype

The biggest challenge we met here was the circuit shortcut. Since the cubes are small and the wires are easy to be pulled out from the breadboard, we used tapes to stabilize them, while resulting in wires touching each other. Finally, we solved the problem by removing the tapes.


0

Circuit


0

Bill of Materials

Assembly List

LabelPart TypeProperties
Part1Particle Argonvariant variant 1s; part # Adafruit #3405
Part2LED Matrix - Serial Interface - Red/Green/Bluetype 8x8 Dot Matrix; interface Serial
S1Pushbuttonpackage [SMD]
S2Pushbuttonpackage [SMD]
S3Pushbuttonpackage [SMD]

Shopping List

AmountPart TypeProperties
1Particle Argonvariant variant 1s; part # Adafruit #3405
1LED Matrix - Serial Interface - Red/Green/Bluetype 8x8 Dot Matrix; interface Serial
3Pushbuttonpackage [SMD]

For the Prototype:
  1. Foamcore sheet
  2. Acrylic Colors (green and yellow)
  3. Postits
0

Code

0
//Date - 02/16/2019  - Final code for the concept Pixel Away. Contributors: Ranveer Katyal, Menghan Zhang, and Sijia Li
//Idea: The follwoing code lets a user light up a specific Pixel on a 8x8 LED Matrix and transmit it to another device 

// This #include statement was automatically added by the Particle IDE.
#include <LedControl-MAX7219-MAX7221.h>
// IMPORTANT: Set pixel COUNT, PIN and TYPE
LedControl *led;
int phase = 0;
char message[64];
int messageLength = 0;
int myUptime = 0;
uint8_t data = A5;
uint8_t load = A4;
uint8_t myclock = A3;
int rowButtonPin = D1;
int colButtonPin  = D2;
int oldRowButtonState = HIGH;
int oldColButtonState = HIGH;
long lastPublishedAt = 0;
int publishAfter = 10000;
int pushSendButton = D6;
int rowIndex = -1;
int colIndex = -1;
String indices;

void setup() {
    Particle.subscribe(  "diot2019/PixelAway/" , handleSharedEvent );
    pinMode(pushSendButton, INPUT_PULLUP);
    
    led = new LedControl(data,myclock,load,1); //DIN,CLK,CS,HowManyDisplays
    led-> shutdown(0,false); //Turn it on
    led-> setIntensity(0,1);
    
    pinMode(rowButtonPin, INPUT_PULLUP);
    pinMode(colButtonPin, INPUT_PULLUP);
}

void loop() {
   
    String RowCol = pixelCounter();
    if (digitalRead(pushSendButton) == 0){
    publishMyEvent(RowCol);
    }

    // delay for a bit
    delay(100);
   

}


void publishMyEvent(String Loc)
{
  if( lastPublishedAt + publishAfter < millis() )
  {

      String eventName = "diot2019/PixelAway/" + System.deviceID();
      Particle.publish(eventName, Loc);
      lastPublishedAt = millis();
  }

}
void handleSharedEvent(const char *event, const char *data)
{
    String eventName = String( event ); // convert to a string object
    String deviceID = System.deviceID();
    String Loc = String(data);
    char colLoc = Loc[1];
    char rowLoc = Loc[0];
   // int colInd = colLoc.toInt(); //convert the string data  into Int
    // int rowInd = rowLoc.toInt(); //convert the string data  into Int
    
    Particle.publish("col", String(Loc[1]));
    Particle.publish("row", String(Loc[0]));

    if( eventName.indexOf( deviceID ) != -1 ){
      return;
    } else {
        ledLit(Loc[0],Loc[1]); // Lights up the Pixel sent byt the other device
        
    }

}

//The function PixelCounter lets the user select the specific pixel they want to light up by the press of push button
//The function returns the pixel locetion to be transmiited to other devices.

String pixelCounter(){
    int newRowButtonState = digitalRead(rowButtonPin);
    int newColButtonState = digitalRead(colButtonPin);
    
    if (newRowButtonState == LOW && oldRowButtonState == HIGH) {
        if (rowIndex == 7) {
            rowIndex = 0;
            led-> setLed(0, 7, colIndex, false);
            
        } else {
            rowIndex++;
        }
        
        if (colIndex == -1) {
            colIndex = 0;
        }
        led-> setLed(0, rowIndex, colIndex, true);
        led-> setLed(0, rowIndex-1, colIndex, false);
    }
    oldRowButtonState = newRowButtonState;
    
    if (newColButtonState == LOW && oldColButtonState == HIGH) {
        if (colIndex == 7) {
            colIndex = 0;
            led-> setLed(0, rowIndex, 7, false);
        } else {
            colIndex++;
        }
        
        if (rowIndex == -1) {
            rowIndex = 0;
        }
        led-> setLed(0, rowIndex, colIndex, true);
        led-> setLed(0, rowIndex, colIndex-1, false);

    }
    oldColButtonState = newColButtonState;
    
    delay(100);
    String indices = String(rowIndex)+String(colIndex);
    return indices;
}

void ledLit(char rowLoc, char colLoc){
    int intRow = rowLoc - '0';
    int intCol = colLoc - '0';
    led-> setLed(0, intRow, intCol, true);
    delay( 100 );
    
}
Click to Expand
0

Network Diagram

Data on both sides always sync with each other. The diagram below is a demonstration of how the two installations work together. There will be three buttons involves, X (controlling the pixel movement on the X-axis), Y (controlling the pixel movement on the Y-axis), Send (sending data to the other device). 

0

Outcomes

We finished the circuit and fit them into our cubic prototypes. The square hole in the middle is the "window" of showing the game. Here below is a working prototype video of our final outcome. 

0
0

Challenges

Software

Debugging
We had many bugs during the process of creating the working code for the prototype, however, everything got figured out by the end of the day. Careful checking is always the best technique for dealing with bugs. 

Hardware

Integration of physical prototype
Fitting the circuit prototype into the physical cubes is not an easy job. We faced many problems such as cannot fit the USB end in the box, instability of the LED matrix, and the stability of the lid. We later re-organize the layout in the box and stabilized some parts firmly to fit everything in our box models. 

Short cut
While we were trying to find out a way to stabilize our circuit at the bottom, we taped the wires up. But it was not a good idea because we got a short circuit from it. One lesson learned from this experience is never to tape circuit up and it could be dangerous.


0

Next Steps

One of the next steps would be implementing the feature that enables the drawing to be archived and sent to both sides as a memory. It could be either a simple mobile app or just an image sent via chatbot to both sides. In this way, the image created by both sides together can be saved forever. 

Also, the existing prototypes don't support different colors due to the limitation of the LED matrix components, making it impossible to differentiate the dots drawn by different users. In the next step, we may use LED matrixes that support customizable colors to make the experience better.

x
Share this Project

Courses

49713 Designing for the Internet of Things

· 18 members

A hands-on introductory course exploring the Internet of Things and connected product experiences.


Focused on
About

Our creative project is to help friends and couples connect with each other in a subtle and fun way. The device is a basic 8 by 8 square LED matrix and serves as a canvas for both sides to draw.

Created

February 16th, 2019