Final Project

For the final project we had to integrate as many as possible digital fabrication techniques and as always document our progress. Moreover we also had to make a video to show the final project working.

Make your own Watch

For the final project I decided to make my one watch. I mean why do I need to buy a watch, if I just could make my own one in the FabLab! The first idea was to create a watch that could display the time, temperature, humidity and also measure your heartbeat. With a push button, the display would switch between each mode and there would be a secon button to measure the heartbeat.

License

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

Costs

Picture Name Price
ATMEGA328P-AU 2,78€
16Mhz/18pF Crystal 0,20€
10K Resistor 3 x 0,03€
499 Resistor 0,03€
SMD LED Yellow 0,3€
22pF Capacitor 2x 0,05€
10uF Capacitor 0,15€
1uF Capacitor 0,6€
100nF Capacitor 0,04€
100nF Capacitor 0,04€
Pinheader 0,3€
DHT11 Sensor 1,56€
DS3231 Real Time Clock Raspery Pi 1,41€
Pulse Heart Rate Sensor 2,56€
0,96 Zoll Arduino OLED Display SSD1306 5,85€
SMD Button 2 x 0,99€
InnoFlex Filament 12g = 0,5€
PLA Filament 10g = 0,2€

Creating the code

Before I started to create the PCB and designing the watch, I had to make sure that every device worked properly. That's why I decided to first make the code, using an arduino and then start with the designing part. Below you can find the code I created. As I told before the main function was to change between the modes on the display by pushing a button. In addition I wanted to display the FabLab Logo at the beginning. To do this, I had to convert the image into black and white and also scale it to the dislpay size. Then I used a website that had tool to change images into byte arrays for the use with Arduino and (monochrome) displays such as OLEDs. In this stage I also noticed that the heartbeat sensor did not work as intended.

#include <DS3231.h>
DS3231 rtc(SDA, SCL);
#include  <SimpleDHT.h>
#include  <SPI.h>
#include  <Wire.h>
#include  <Adafruit_GFX.h>
#include  <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int pinDHT11 = A2;
SimpleDHT11 dht11(pinDHT11);

//  Variables
byte temperature = 0;
byte humidity = 0;

int state = 0;
const int Button_PIN = 4;
int buttonPushCounter = 0;   // counter for the number of button presses
boolean buttonState = HIGH;         // current state of the button
boolean lastButtonState = HIGH;     // previous state of the button

//'fablab', 128x64px
const unsigned char myBitmap [] PROGMEM = {
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0x80, 0x00, 0x00, 0x7f, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xe0, 0x00, 0x00, 0x3f, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xe0, 0x00, 0x00, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xf0, 0x00, 0x00, 0x7f, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xf0, 0x00, 0x00, 0x7f, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xf8, 0x0f, 0xff, 0xff, 0xe0, 0x70, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xe0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xe0, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xe0, 0x00, 0x1f, 0xf0, 0x00, 0x07, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xe0, 0x00, 0x1f, 0xe0, 0x00, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xe0, 0x00, 0x1f, 0xe0, 0x00, 0x0f, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0x81, 0xe0, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xf0, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0x07, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xf8, 0x00, 0x1f, 0xe0, 0x00, 0x3f, 0x0f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xf8, 0x00, 0x1f, 0xe0, 0x00, 0x7f, 0x0f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xe1, 0xfc, 0x00, 0x1f, 0xf0, 0x00, 0x7f, 0x0f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xe1, 0xfc, 0x00, 0x1f, 0xf0, 0x00, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xf0, 0x7c, 0x00, 0x3f, 0xf8, 0x01, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x1c, 0x00, 0x7f, 0xfc, 0x07, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x0c, 0x00, 0xff, 0xfe, 0x1f, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};


void setup() {
   rtc.begin();
   //rtc.setDOW(THURSDAY);          // Set Day-of-Week
   //rtc.setTime(17, 18, 20);     // Set the time to 11:40:00 (24hr format)
   //rtc.setDate(24, 1, 2019);   // Set the date to January 4th, 2014
   Serial.begin(9600);
   pinMode(Button_PIN, INPUT);
   //readTime(); 
   //readTemp();
 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println("SSD1306 allocation failed");
    for(;;); // Don't proceed, loop forever
  }
  // Update the display
   display.display();
  // the library initializes this with an Adafruit splash screen.
  delay(2000); // Pause for 2 seconds
  // Clear the buffer
  display.clearDisplay();
   // Draw FabLab Logo
   drawbitmap();
 
}


void loop() {
 buttonState = digitalRead(Button_PIN);

  if (buttonState != lastButtonState) {
    if (buttonState == LOW) { // if the current state is HIGH then the button
      // went from off to on:
      buttonPushCounter++;  // add one to counter
      display.clearDisplay();
      if (buttonPushCounter > 2) // if couter over 3 reset the counter to 1 to show "Jon"
                                 // and not "Hello All"
      {
        buttonPushCounter = 1;
      }
      Serial.println(buttonPushCounter);
      switch (buttonPushCounter) // choose what to display based on buttonPushCounter value
      {
        case 0:
          break;
        case 1:
          displayTime();
          break;
        case 2:
         displayTemp();
          break;
      
      }
    }
    // save the current state as the last state,
    //for next time through the loop
    lastButtonState = buttonState;
  }

}


void drawbitmap(void) {
  // Make sure the display is cleared
  display.clearDisplay();
  // drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
  display.drawBitmap(0, 0, myBitmap, 128, 64, WHITE );
  // Update the display
  display.display();
 
}

void displayTemp() {
 readTemp();
 display.clearDisplay();
 display.drawRect(0, 0, 128, 30, WHITE); 
 display.setTextSize(2); // Draw 2X-scale text
 display.setTextColor(WHITE);
 display.setCursor(5, 8);
 display.print("Temp:");
 display.print((int)temperature);
 display.print(" *C ");
 display.drawRect(0, 33, 128, 30, WHITE);
 display.setCursor(5, 40);
 display.print("Humid:");
 display.print((int)humidity);
 display.print(" H ");
 display.display();      

}

void readTemp() {
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
    return;
  }
  Serial.print((int)temperature); Serial.print(" *C, "); 
  Serial.print((int)humidity); Serial.println(" H");
}

void displayTime() {
  readTime();
 // Make sure the display is cleared
 display.clearDisplay();
 display.drawRect(0, 0, 128, 20, WHITE); 
 display.setTextSize(2); // Draw 2X-scale text
 display.setTextColor(WHITE);
 display.setCursor(5,3);
 display.println(rtc.getDateStr());
 display.drawRect(0, 19, 128, 20, WHITE);
 display.setCursor(30,22);
 display.println(rtc.getDOWStr());
 display.drawRect(0, 39, 128, 24, WHITE);
 display.setCursor(20,41);
 display.setTextSize(3);
 display.print(rtc.getTime().hour);
 display.print(":");
 if (rtc.getTime().min >= 0 && rtc.getTime().min < 10) {
  display.print("0");
 }
 display.println(rtc.getTime().min);
 // Show initial text 
 display.display();      

}

void readTime() { //reads time from RTC Module
 // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
 
}
                    

I thought I could fix the problem with the pulse sensor later on. But the problem wasn't the library I was using. Probably the sensor was not only cheap, but also very sensitive and that's why it maybe did not work the way it supposed to. As you can take out from the video below, the senor caused some interruptions and dysfunctions (of the DHT11 Sensor), when it was connected with the other sensors.

Sometimes it showed some correct heart beat values. So I decided to check out what it would output, when I only used the Anlogread() function. But unfortunately these values were also invalid and it also caused a bug on the display as you can see below. If I would have had more time, I would have used a diffrent sensor. Because of this problem the second button I added in my schematic, didn't have a function anymore.

Electronic Design

After creating the Code I had to make a small PCB that would have the same basic components as the Arduino itself. Moreover the PCB had to be big enough to solder four devices on it. I used the Satshakit Micro as a reference to create my own board. With the learned skills in designig and soldering a PCB, I came up with the idea to create two boards. One that would have the main components (the microcontroller) and another one that would sustain the buttons on the left side. Below you can see the finished design.

The schematic shows that I did not use or route every pin. I routed only the ones I needed, because the PCB had to be as small as possible. So I had to take that risk. Moreover I grouped the pins of every input and output device, so that I had the possibility to solder the devices directly on top of the PCB

Problems

The first time I was milling the PCB some traces didn't get cut properly, because they were designed way to close together.

So I had to modify the design and then accidentally I forget a VCC trace, so I had to bridge that trace. As I mentioned before, I wanted to attach the board with the buttons on the left side of the the other board using some pinheaders. In the final outcome you should be able to see the buttons outside the case.

I also had some difficulties after uploading the code on my board. One problem was, that the code of the button I created and used when I was testing it with the arduino uno did not work. The other problem I faced was, that I attached the GND of the button board to the the VCC on the main board. That's why I did not have a Pull Down Button as I planed in my schematic, but a Pull Up button.

3D Print and Laser Cutter

After finishing my board and soldering all my sensors on it, I could finally measure the size of my case. Here I also needed to measure the sizes of the button and the thickness of the straps. The first time I printed the design with 2mm thickness of the walls and that caused a shortage of space for the PCB, so I had to decrease them to 1mm.

The staps were made with flexible fillament. Here it was important to disable the retraction and to find the proper speed and temperature for the fillament. As the label on the fillament said that the tempertrure should be between 200 - 250, I choose to set 225. I could not change the temperature on cura, so I had to tune it manually at the printer.

The design for the plexiglass was kept simple and should fit perfectly. The configuration I used with the Laser Cuter were: Power 100, Speed 10 and Frequency 50.

Download the Plexiglass Design

click here to download the file!

Download the Design of the Case

click here to download the file!

Download the Design of the Straps

click here to download the file!

Download the Electronic Design of the PCB

click here to download the file!

Music from Vanze-Forever (Instrumental)