We are going to produce a product could connect people from long diatance to exchange their emotion or some informations.

Created: December 4th, 2023

0

Historical Case


The Good Night Lamp
For those who miss someone apart and convey their feelings in a non-intrusive way. 

https://www.designswarm.com/good-night-lamp/

0

Proposal

We propose a system featuring two interconnected liquid timers, symbolizing connection over distance. Each liquid timer is controlled by a servo for rotation, controlled by a handle. To transmit a signal, a user rotates the handle by 180 degrees. One end of the handle has a magnet, and a hall effect detector registers changes in magnetic status, transmitting a signal to an argon device. The argon then activates the servos on both the local and remote liquid timers, causing them to rotate by 180 degrees and the colorful liquid will slowly descend. Simultaneously, a neopixel behind a translucent acrylic adding a subtle visual element to the communication process. Given that the liquid timer's rotation is observable for only two minutes, we explore the use of timed, subtle signals as a means of communication.

0
0

Conceptual Design

0

Bill of Materials


  • Liquid timer: Key component of this project. Displaying rotation information.
  • Wood stick: Another key component of this project. Act a a triger for users to input rotation movement.
  • Hall effect sensor and magnet: They are paired for us detecting the rotation movement from wood stick.
  • Servo motor: Transfering  rotation movement form contorllor to liquid timer.
  • Neopixel LED: 
  • Fabrication: Wood, acrylic, Laser cut, 3D printing.
  • {a chart comparation between servo and stepper}

0

Resulting Prototype


We have created a prototype with reed sensor and a magnetic in out argon kit to trigger the system. The reed sensor and a magnetic replace the switch in the previous mock (Homework Dev V). Whenever there is a magnet near the reed sensor, it changes the global variable to 0, and whenever the magnet is faraway, the global variable is set to false. When servo rotate 180 degree whenever there is a change in this global variable.


However, the team has not reach a consensus on how should we control the magnet in terms of triggering . We have experimented the idea of a magic pen that is free to move. the stick that is attached to a pivot in the middle and free to rotate, or a disc that is free to rotate. We will be working on that.

0
0
0

Final Result: Reflection, Feedback


We've received a significant amount of feedback on enhancing the user experience. For instance, it's noted that the initial instinct upon installation is to rotate the clock instead of exploring the magic wand 🪄. People seem to have a ingrained perception of interacting with a liquid timer. Despite not wanting to enclose it, the reality is that it's becoming more of a display, prompting consideration of using a transparent acrylic. This experience highlights the importance of being more decisive in our design approach.

Another point of feedback relates to the 2-minute replay effect. When person B receives a signal from person A, finding an efficient acknowledgment method is crucial. While replicating the signal could work, it risks interrupting A's previous message. To address this, a suggestion is to repeat the action of touching the snoopy with the magic wand, triggering a color change instead of rotating the timer—a quick way for person A to know their message is received.

Other valuable feedback includes slowing down the rotating speed of the timer and swapping the locations of Snoopy and Woodstock. These insights will be considered for future improvements. Reflecting on our three-week experience, we acknowledge underestimating the time required to design, test, and redesign the mechanical aspects, particularly with 3D printing. Consequently, there was a rush to ensure everything was functioning just two hours before the actual presentation.

0
0
0

Application Diagram


Two pieces of Argon independently receive signals via triggers of reed switches.

0

Comparing with Goodnight lamp

  • The Good Night Lamp and Antipode are both IoT devices designed to connect people over distances, but they have different mechanisms and symbolic meanings. 
  • The Good Night Lamp uses a set of lamps connected via the internet to convey simple messages like "I'm home" or "thinking of you," with the state of one lamp reflecting in others globally. On the other hand, the we uses interconnected liquid timers and a more complex system involving servos, magnets, and sensors to communicate subtle signals and emotions over distance. 
  • While the Good Night Lamp offers a straightforward and intuitive mode of communication, the Antipode provides a more interactive and visually engaging experience.
  • We uses physical interaction and liquid timers for emotional communication, contrasting with Good Night Lamp's passive light-based signals.
  • We utilize some advanced IoT technology in Antipode, including servo motors and Argon kits, offers a dynamic experience unlike the simpler technology of Good Night Lamp.
  • Our tactile feedback through the magic pen engages users actively, differing from the Good Night Lamp's straightforward on/off interaction.
  • The emotional resonance in Antipode's design, emphasized by the flow of liquid, provides a multisensory experience compared to the visual-only cues of the Good Night Lamp.
0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// -----------------------------------
// Controlling LEDs over the Internet
// -----------------------------------

// First, let's create our "shorthand" for the pins
// Same as in the Blink an LED example:
// led1 is D0, led2 is D7


// Code for neopixels
#include <neopixel.h>
#include "neopixel.h"
#define PIXEL_PIN D3
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

int status = 0; // 0 for default dark, 1 for going to white, 2 for fading to dark
std::array<int, 3> dark = {0, 0, 0};
std::array<int, 3> white = {255, 255, 255};
long lightDuration = 1000 * 10 ;
long fadeDuration = 1000 * 15 ;
long timerStartAt = -1;

// code for servo
Servo servo;
int servoPin = A2;
int switchPin = D5;
int hallPin = A5;
int curSwitchState;
int ledPin = D2;

int servoPos;
int first = 1;
int hallState;

void setup()
{

    pinMode( switchPin , INPUT_PULLUP); // sets pin as input
    pinMode( hallPin , INPUT_PULLUP); // sets pin as input
    pinMode( ledPin , OUTPUT ); // sets pin as output
    servo.attach( servoPin );
    servo.write(0);
    servoPos = 0;
    curSwitchState = 0;
    Serial.begin( 9600 ); 
    Particle.variable("servoPos", servoPos);
    Particle.variable("hallState", hallState);
    Particle.variable("buttonState", curSwitchState);
    Particle.subscribe("rotate", handleRemoteRotate);
    
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'


}


// Last time, we wanted to continously blink the LED on and off
// Since we're waiting for input through the cloud this time,
// we don't actually need to put anything in the loop


uint32_t getCurrentRGB(int duration, int timeElapsed, std::array<int, 3>  prevColor, std::array<int, 3>  targetColor) {
    int prev_r = prevColor[0];
    int prev_g = prevColor[1];
    int prev_b = prevColor[2];

    int target_r = targetColor[0];
    int target_g = targetColor[1];
    int target_b = targetColor[2];

    int r, g, b;  // Declare variables outside the loop
    
    Serial.println(timeElapsed);
    
    if (timeElapsed == 0) {
        r = prev_r;
        g = prev_g;
        b = prev_b;
        
    }

    r = map(timeElapsed, 0, duration, prev_r, target_r);
    g = map(timeElapsed, 0, duration, prev_g, target_g);
    b = map(timeElapsed, 0, duration, prev_b, target_b);
    Serial.println( r);    
    Serial.println( g);        
    Serial.println( b);   

    
    return strip.Color(r, g, b);
}


void loop() {
    
    // handle servo
    int newSwitchState;
    hallState = analogRead(hallPin);
    
    if (hallState < 3000) {
        newSwitchState = 0;
    } else {
        newSwitchState = 1;
    }
    
    Serial.print(hallState);
    
    if( newSwitchState == LOW ){
        digitalWrite( ledPin, HIGH);
    }else{
        digitalWrite( ledPin, LOW);
    }

    if (curSwitchState != newSwitchState) {
        if (curSwitchState == 1) {
            Particle.publish("triggerRotate");
            rotateServo();
            timerStartAt = millis();
            status = 1;
            curSwitchState  = newSwitchState;
        } else {
            curSwitchState  = newSwitchState;
        }
    }
    
    // handle neoplixels
    uint32_t c = strip.Color(0, 0, 0);
    long timeNow = millis();
    long timeElapsed = timeNow - timerStartAt;
    Serial.print( "timeElapsed"); 
    Serial.println( timeElapsed); 
    
    if (status == 0) {
         // do nothing to change the color
         timerStartAt = timeNow;
    }else if (status == 1) {
        if (timeElapsed <= lightDuration) {
            c = getCurrentRGB(lightDuration, timeElapsed, dark, white);
            // Particle.publish("status is 1");
        } else {
            timerStartAt = timeNow;
            // Particle.publish("Changing to 2");
            timeElapsed = timeNow - timerStartAt;
            c = getCurrentRGB(lightDuration, timeElapsed, white, dark);
            status = 2;
        }
    } else if (status == 2) {
        if (timeElapsed < fadeDuration) {
            c = getCurrentRGB(fadeDuration, timeElapsed, white, dark);
            // Particle.publish("status is 2");
        } else {
            timerStartAt = timeNow;
            status = 0;
        }
    } else {
        Particle.publish("error status");
    }

    for(int i=0; i< strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
		strip.show();
// 		Serial.print( "pixel"); 
// 		Serial.println( i); 
    }
    
    delay(100);
}


// We're going to have a super cool function now that gets called when a matching API request is sent
// This is the ledToggle function we registered to the "led" Particle.function earlier.

int handleRemoteRotate(const char *event, const char *data) {
    timerStartAt = millis();
    rotateServo();
    status = 1;
    return 1;
}


int rotateServo() {
    if (servoPos == 0) {
        servoPos = 180;
        servo.write(180);
        return 1;
    } else if (servoPos == 180) {
        servoPos = 0;
        servo.write(0);
        return 1;
    } else {
        return -1;
    }
}
Click to Expand
0

Fabrication Process


  • We decided to connect the servo motor with the liquid timer using gears. Despite the time constraint, we proceeded with two 3D print prototypes to make adjustments midway. While looking for images to demonstrate the connection where users can bring a magic wand close to a magnet sensor, I edited images of Snoopy and Woodstock that Sherry likes.
  • We devised a laser-cut semi-transparent acrylic cut to easily connect the gears. As a result, although we regretted having to increase the size in terms of design, it was very helpful for the connection, compared to the liquid clock.
  • Regarding the gears, we noticed a slight difference in the spacing between the servo and bevel gears, as well as the vertical gears. We made adjustments in the second prototype to maintain a clearance of about 0.7 mm, which significantly improved the toothed parts.
  • We planned to place the initial NeoPixels behind the liquid timer to create an ambient light effect. However, during the production process, we encountered interference between the wires of the NeoPixels and the frame of the liquid clock, which rotates 180 degrees, and realized that the gears were not sufficiently solid. Therefore, we modified the design to illuminate the character (Snoopy) in the direction of the light.  

Each video below should be expanded to its maximum size. 

0
0
x
Share this Project

Courses

48-675 Designing for the Internet of Things 24

· 11 members

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


About

We are going to produce a product could connect people from long diatance to exchange their emotion or some informations.