Network Everything’s Final Project

DOCUMENTATION

The story?

The idea comes from my own problem of having problems finishing a physical book (eBook too actually but that’s another story). I thought, perhaps, if I incentivise myself with some candies, I’d finish a book or two.

All the books I've never got to finish

All the books (and more tbh) that I’ve never got to finish

What does this do?

This project consists of two parts. The first one being a bookmark, while the other one is a candy box. The idea is to make a bookmark that’s placed in between pages that I plan to reach/read. When I reach the page (where the bookmark is placed at), a candy will get dispensed.

The bookmark and the candy box would communicate via wifi. The idea is wherever you are in the world (okay maybe more like, when you’re bookmark and the candy box are in the same city), you can still trigger the candy box (and get candies cos candies are awesome) as long as you’re connected to the wifi. So an example of this would be you would be able to read a book on a subway (so long as you’re connected to the net) and find some candies when you’re home.

What are the materials?

I used two MKR1000, one for the bookmark and the other one for the candy dispenser.

For the bookmark, I used two copper strips hooked up to a MKR1000. They act like a button that activates the candy box. I used pull-up to activate the candy box on the other side.

As for the candy box, I laser-cut a candy box with ramps (FTW!) in it. There will be a gate controlled by a servo that’ll open when you reach the page you’ve placed your bookmark in. When the gate opens, candies will roll out.

The candy box and the bookmark will be connected through wifi via IFTTT’s Maker Webhooks, a project that lets my two MKR1000 talk to each other

Assemble!

The assembly process itself was rather straightforward, except for the constant adjustments, e.g. adjusting the position of the gate, adjusting the delay time, adjusting the position of cables, etc.

Software for the software part, it is rather straightforward except for the part where I was to connect my MKR1000 to IFTTT. This process didn’t feel as intuitive to me and the documentations online didn’t quite feel that helpful either, but after a *while* of tinkering, *good* things started to happen, so that’s great. I tried my best not to jump into making a bookmark that triggers the candy box right away. I tried to start small with turning on an LED with a push of a button (connected via the wifi). From there, when things worked fine, I swapped the LED with servo. I ran into issues incorporating the servo into the equation, but it went fine after a while. Afterwards, I then modified the code of the button to make it trigger the servo with pull-up resistance.

Although the whole process took quite a while, I’m glad that I did it all in small steps as opposed to diving into connecting a servo with a pull up button right away. That helped a lot in identifying issues (and fixing them).

For the bookmark, I combined the code from Marco Schwartz’s IoT Cookbook and Arduino’s Pull Up. As for the candy dispenser, I combined the code from the same book and Arduino’s Mini Servo. For the Mini Servo, I did some modifications with the delay (thanks to Angelica for suggesting how much the delay should be!) and the angle that the servo should move.

Hardware I was wrong when I thought that the software part of this project would’ve taken more time than the hardware part. For the hardware part, there are two components I had to take into account: the bookmark and the candy box.

The bookmark. Initially, I was set on using touch/pressure sensor to trigger my candy box. However, Scott suggested that I swapped the sensors for copper strips because copper strips could get the system running with little to no force/pressure. This would be more suitable because a bookmark that’s placed in between pages won’t usually receive that much force/pressure.

IMG_20170518_121304

The-initially-dispenser-turned-candy-box Initially I wanted to make a candy dispenser that looks like an actual dispenser (sigh). However, after hours of tinkering with 3D modelling software, I figured that I had been spending too much time on it and should probably opt for something simpler, thus the candy box. I laser cut MDF boards and assembled them by using wood glue. For the front part, I use an acrylic board. 

The Result The result is this bookmark that triggers candy dispenser when they two sides of the bookmark aren’t touching.

What I Wish I Could’ve Done Differently

Size of the bookmark I’d love to have a bookmark that’s not as big as the one I designed. I’d love it to be a lot smaller and thinner, and possibly, not wired to a power bank. I imagined it would need a bit more research and thinner-battery hunting.

The dispenser If I had more time, I’d love to work more on the dispenser and make it look like an actual dispenser. I guess there isn’t exactly any problem with this candy box, but I personally would’ve liked to see a better-looking candy box.

Weight sensor I think it would’ve been more fun to have the weight sensor and the notification system, too. I’ve actually made the whole notification system working (using Temboo and Google Mail), but I never got around adding the weight sensor so I had to forgo the idea.

//servo code
// Import required libraries
#include <SPI.h>
#include <WiFi101.h>
#include <PubSubClient.h>
#include <aREST.h>

//servo 
#include <Servo.h>;
Servo servo1; 
int pos;

// Status
int status = WL_IDLE_STATUS;

// WiFi parameters
const char* ssid     = "Tirza";
const char* password = "tirzacarlo";

// Clients
WiFiClient wifiClient;
PubSubClient client(wifiClient);

// Create aREST instance
aREST rest = aREST(client);

// Variables to be exposed to the API
bool ledState = false;

// Function
int ledControl(String command);
void callback(char* topic, byte* payload, unsigned int length);

void setup(void)
{
  // Start Serial
  Serial.begin(115200);

  // Set callback
  client.setCallback(callback);

  // Function to be exposed
  rest.function("toggle", ledToggle);

  // Give name and ID to device
  rest.set_id("didiLED");
  rest.set_name("mkr_led");

  // Connect to WiFi
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);

    // Wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("WiFi connected");

  // Pin 6 as output
//  pinMode(6, OUTPUT);

  servo1.attach(6);
}

void loop() {
  
  // Connect to the cloud
  rest.handle(client);

}

// Custom function accessible by the API
int ledToggle(String command) {

  ledState = !ledState;

  servo1.write(90);
  
//  for(position = 180; position >= 0; position -= 1)
//  {                                
//    servo1.write(position);  // Move to next position
//    delay(20);               // Short pause to allow it to move
//  }

  for (pos = 90; pos >= 55; pos -= 1) { // goes from 180 degrees to 0 degrees
    servo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 55; pos <= 90; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    servo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
  delay(5000);
//  delay(1000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //5
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //10 - 10 * 10 * 1000ms
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //15
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //20 - 20 * 10 * 1000ms
  return 1;
}

// Handles message arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length) {

  // Handle
  rest.handle_callback(client, topic, payload, length);

}




// Bookmark Code 
// Libraries
#include <SPI.h>
#include <WiFi101.h>

// Status
int status = WL_IDLE_STATUS;

// Credentials
const char* ssid     = "Tirza";
const char* password = "tirzacarlo";

// IFTTT settings
const char* host = "maker.ifttt.com";
const char* eventName   = "toggle";
const char* key = "p96PFiscY---nII2hLRkE7BOhVGjUHfgLpz30adDNrm";

void setup() {

  // Seroa;
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);

    // Wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("WiFi connected");

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //pulllup
  //start serial connection
  Serial.begin(9600);
  //configure pin 6 as an input and enable the internal pull-up resistor
  pinMode(6, INPUT_PULLUP);
}


void loop() {
  int sensorVal = digitalRead(6);
  
  if (sensorVal==HIGH) {

    // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/trigger/";
  url += eventName;
  url += "/with/key/";
  url += key;
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1rn" +
               "Host: " + host + "rn" + 
               "Connection: closernrn");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
  
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("Closing connection");
  delay(5000);
//  delay(1000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //5
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //10 - 10 * 10 * 1000ms
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //15
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //20 - 20 * 10 * 1000ms - 3 minutes 

  }else{
    Serial.println("You're not at the page you want yet!");
  }
  
}

Leave a Reply