Inspiration

As a busy college student stressed with long days and suboptimal sleep, a nap in the day can be a big contributor to productivity. The problem is that what is meant to be a short break can turn into an hours-long affair for a variety of reasons. Not only do you lose time during the day, but naps longer than 30 minutes can cause sleep inertia, or a period of grogginess and reduced performance caused by waking in the middle of deep sleep. Nap Rite is a means to solve this dilemma.

What it does

Nap Rite is a sleep companion that functions both as an alarm clock and a sleep mask. A microcontroller set with a 30 minute timer activates two haptic drivers and a buzzer embedded in the sleep mask while simultaneously interfacing with a web server that controls stopping and starting the Nap Rite. This facilitates a seamless napping experience for the user that optimizes nap time, nap comfort, and guarantees you wake up to continue with your day.

How we built it

There were two main aspects to building this project: the mask and the web server (essentially hardware and software). For the mask we soldered the two haptic drivers to 2 long running wires that led back to simple arduino pins and then connected them to the mask via hot glue. We directly implemented the buzzer into the mask band by threading the circuit leads through the elastic and then also connecting back to the arduino via two long ground and pin wires.

On the software side we set up a local web server through the Arduino with an MKR1000 Wifi Shield. The board backchannels with the network it connects to and builds the page via the Wifi101 Library with HTML and CSS code we wrote that was sourced from online forums. Through the page we create linked buttons that trigger client requests of different types which we can then read and use to control the actuators via conditionals in the code.

The basis of the project is rooted in simple concepts and tech, but the intricacies of Arduino and the various electrical components involved proved to be somewhat difficult, as we will go into during the next section.

Challenges we ran into

Our main challenge was trying to incorporate the wifi into the project. First, we had to figure out how to send commands from a device to the Arduino. We were able to find code online that served as a basis for our own code. However, editing that code to better serve the purposes of our project was complicated. Another challenge we faced was with simply getting the wifi to connect. The wifi was incredibly inconsistent, as it would sometimes connect quickly and other times not connect at all. This wasn’t exactly something we had control over, but we did decide to change our wifi shield and had more consistent results with the second one. Finally, integrating the hardware onto the sleep mask was slightly difficult at first. The wires of the haptic drivers were very small and broke easily, so when putting everything together, we had to solder wires and fix small components many times.

Accomplishments that we're proud of

We’re proud of our ability to successfully integrate wifi into the project through an HTML server. As this was the most difficult part of the project, its success is what we are most proud of. Additionally, we are proud of our whole project coming together to become a well functioning alarm that will certainly wake up the user.

What we learned

We learned a lot more about how to work with Wifi and Arduino, as we only knew how to send data from the Arduino before. Writing the code for the wifi and learning from other codes online gave us a more in depth understanding of how the wifi works. We also learned a lot about working as a team and using our individual strengths to come together to make our project the best that it could be.

What's next for Nap Rite

Nap Rite is in its earlier stages with its hardware. In the future, we can better integrate the hardware in order to make the sleep mask less bulky. We could use a small battery powered, wifi Arduino that can be attached to the actual sleep mask. We also can put the haptic drivers and buzzer into the sleep mask and use smaller wires in order to make it easier to put on and wear. Finally, we can change the code so that the user can send the command to start the Arduino from a phone instead of a computer, for potentially more convenience.

Promo Video

https://youtu.be/q1X4VF-g1eA

Code

#include <SPI.h>
#include <WiFi101.h>

//#include "arduino_secrets.h"

int vibe1 = 2;
int vibe2 = 9;
int buzzer = 4;

char ssid[] = "Margo's iPhone";        // your network SSID (name)
char pass[] = "squire01";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;                 // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
   Serial.begin(9600);      // initialize serial communication
    pinMode(vibe1, OUTPUT);
    pinMode(vibe2, OUTPUT);
    pinMode(buzzer, OUTPUT);

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while (true);       // don't continue
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();                           // start the web server on port 80
  printWiFiStatus();                        // you're connected now, so print out the status

}

void loop() {
   WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to start the Nap Rite! <br>");
            client.print("Click <a href=\"/L\">here</a> to stop your alarm.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          delay(10000);
          /*while(!currentLine.endsWith("GET /L")){
          vibeOn();
          buzzOn();
          }
          vibeOff();
          buzzOff();*/
          digitalWrite(vibe1, HIGH);   
          digitalWrite(vibe2, HIGH);
          digitalWrite(buzzer, HIGH);
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(vibe1, LOW);   
          digitalWrite(vibe2, LOW);
          digitalWrite(buzzer, LOW);// GET /L turns the LED off
       }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}
void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

Built With

Share this project:

Updates