### DESCRIPTIONHi, everyone, this project is a wearable wich main function is a watch, but at the same time it can be a development board for other applications or gatgets. The main idea, is to have a very small (35mm x 35mm) wearable board that could be used with a battery. It's based on the Atmega328P microcontroller.Hola a todos, este proyecto es un wearable cuya función principal es la de un reloj de pulsera, pero al mismo tiempo puede ser usado como una tarjeta de desarrollo para otras aplicaciones o gatgets. La idea principal es tener una muy peque?a (35mm x 35mm) tarjeta wearable que pueda ser usada con una batería. El circuito está basado en el microcontrolador Atmega328P.### TECHNICAL DETAILS / COMPONENTSThe electronic design is based in a generic Arduino Nano with a CH340 USB controller, but with some modifications, so it can be operated at
3.3/3.7 volts, this way it can be powered with a small rechargable
lithium battery. Other periphals can be conected trought the 6 analog
I/O with the J3 connector or with the SPI protocol throught the J1
conector. The follow diagram show the base circuit.El dise?o electrónico está basado en un Arduino Nano genérico con un controlador USB CH340, pero con algunas modificaciones, de tal manera que pueda ser operado a 3.3/3,7 voltios, de esta manera pueder ser alimentado con una peque?a batería recargable de litio. Otros periféricos pueden ser conectados a través de las 6 Entradas/Salidas analógicas a través del conector J3, o con el protocolo SPI mediante el conector J1. El siguiente diagrama muestra el circuito base.Half of the device is an Arduino Nano and the other half is the clock style LED array. The follow diagram show the LED array and the connection with the Atmega328P.La mitad del circuito es un Arduino Nano y la otra mitad son los led con arreglo en forma de reloj. El siguiente diagrama muestra la manera en que están organizados los leds y la conexión con el Atmega328P.The follow image shows the expansion conectors pinout.La siguiente imagen muestra la disposición de los pines de los conectores.BILL OF MATERIALSC1 - 10ufC2 - 100nfC3 - 100nfC4 - 100nfC5 - 10ufC6 - 100nfC7 - 100nfC8 - 22pfC9 - 22pfC10 - 22pfC11 - 22pfD1:D16 - LEDPWR - LEDJ1 - Conector USB(UX60SC-MB-5ST)J2 - Conector(FH12-8S-1SH)J3 - Conector(FH12-6S-1SH)R1 - 1kR2 - 1kR3 - 10kR4 - 1kR5 - 1kR6 - 1kR7 - 470RR8 - 470RR9 - 470RRPWR - 470RS1 - Switch(B3U-wB)SL - B3SLSM - B3SLSR - B3SLU1 - Atmega328P (QFP-32 9x9x0.8)U2 - CH340 (SOP-16 7x1.27)U3 - LM7805 (SOT-89)U4 - MMBT3904 (SOT23)U5 - MMBT3904 (SOT23)U6 - MMBT3904 (SOT23)Y1 - 16Mhz CrystalY2 - 12Mhz Crystal### LEARN / TOPIC / BUILD INSTRUCTIONSFor the energy save the power led can be omited. WARNING: This PCB is a prototype and wasn't test. The test was made with a protoboard and an Arduino Nano. Also, the LEDs are placed in counterclockwise direction. The code showed below works with this configuration.Para ahorrar energía el led de encendido puede ser omitido. PRECAUCIóN: Este PCB es un prototipo y no ha sido probado. La prueba se realizó con un protoboard y un Arduino Nano. También, los leds han sido puestos en contrareloj. El código que se muestra a continuación funciona con esa configuración.Also, I designed a box that can be made with a 3D printer. The STL files are liested bellow.También, he dise?ado una caja que puede ser hecha con una impresora 3D. Los archivos STL se muestran abajo.DropBox STL file1 - BoxDropBox STL file2 - Cover### CODE// DuinO'Clock// 22/Nov/2018// Benjamín Alejandro Luna Ramírez// Versión 1.1#include <avr/sleep.h>// Constantsconst byte Button_Left = 2;const byte Button_Center = 3;const byte Button_Right = 4;const byte T1 = 5;const byte T2 = 6;const byte T3 = 7;const byte Led_Circle_Start = 7;const byte Preescaler_Divider = 7; // 7 = 128 times.const byte Preescaler_Frequency = 128;const int Time_Run = 500 / Preescaler_Frequency; // Time the leds are on when the device turn on.const int Time_Led_Blink = 400 / Preescaler_Frequency;const int Time_Led_Between = 200 / Preescaler_Frequency;// Variables globalesbyte volatile timeHour = 1;byte volatile timeMinute = 0;byte volatile timeSecond = 0;int volatile timeMiliseconds = 0;/* currentFunction values are: 0:none 1:Showing Hour 2:Changing Hour*/byte volatile currentFunction = 0;void setup() { // put your setup code here, to run once: CLKPR = 0b10000000; CLKPR = Preescaler_Divider; // Buttons pinMode(Button_Left, INPUT_PULLUP); pinMode(Button_Center, INPUT_PULLUP); pinMode(Button_Right, INPUT_PULLUP);// Transistors pinMode(T1, OUTPUT); pinMode(T2, OUTPUT); pinMode(T3, OUTPUT);// Leds pinMode(Led_Circle_Start + 1, OUTPUT); pinMode(Led_Circle_Start + 2, OUTPUT); pinMode(Led_Circle_Start + 3, OUTPUT); pinMode(Led_Circle_Start + 4, OUTPUT); pinMode(Led_Circle_Start + 5, OUTPUT); pinMode(Led_Circle_Start + 6, OUTPUT);// Enciendo los leds menos significativos en secuencia para indicar que está encendido. digitalWrite(T3, HIGH); digitalWrite(Led_Circle_Start + 1, HIGH); delay(Time_Run); digitalWrite(Led_Circle_Start + 1, LOW); digitalWrite(Led_Circle_Start + 2, HIGH); delay(Time_Run); digitalWrite(Led_Circle_Start + 2, LOW); digitalWrite(Led_Circle_Start + 3, HIGH); delay(Time_Run); digitalWrite(Led_Circle_Start + 3, LOW); digitalWrite(Led_Circle_Start + 4, HIGH); delay(Time_Run); digitalWrite(Led_Circle_Start + 4, LOW); digitalWrite(T3, LOW);// Disable interrupts before changing the preescaler value. noInterrupts();// Synchronous mode. ASSR = (ASSR & 0b11011111);// Operate in CTC mode and preescaler. TCCR2B = 0b00000111; TCCR2A = 0b00000010; TCNT2 = 0;// 10 milisegundos (16,000,000 / 1024 * 0.01) = 156 OCR2A = 255; TIMSK2 = 0b00000010; interrupts(); SleepDevice();}void SleepDevice(){// Attach the interrupts to the pins. attachInterrupt(digitalPinToInterrupt(Button_Center), ShowHour, LOW); attachInterrupt(digitalPinToInterrupt(Button_Left), ChangeHour, LOW);// Enter Power-Save Sleep mode. SMCR = 0b00000111; sleep_cpu();// Disable sleep after waking up and detach interrupt. SMCR = 0b00000000; detachInterrupt(digitalPinToInterrupt(Button_Center)); attachInterrupt(digitalPinToInterrupt(Button_Left), ChangeHour, LOW);}void loop() { switch(currentFunction) {// Showing the hour. case 1: LightHour(); delay(Time_Led_Blink); ClearLeds(); delay(Time_Led_Between); LightMostSignificantMinute(); delay(Time_Led_Blink); ClearLeds(); delay(Time_Led_Between); LightLessSignificantMinute(); delay(Time_Led_Blink); ClearLeds(); currentFunction = 0; break;// Changing hour. case 2: byte next = 0;// Changing hour// Wait for the button. while(digitalRead(Button_Left) == LOW) { delay(1); }// >> Show the current hour. LightHour(); while(next == 0) { // Probes if one of the buttons has been pressed. if(digitalRead(Button_Left) == LOW) { next = 1; while(digitalRead(Button_Left) == LOW) { delay(1); } }else if(digitalRead(Button_Right) == LOW){ if(timeHour <= 11) timeHour++; else timeHour = 1;// >> Show the current hour. LightHour(); while(digitalRead(Button_Right) == LOW) { delay(1); } } } next = 0;// >> Show the current most significant minute. LightMostSignificantMinute();// Changing most significant minute. while(next == 0) {// Probes if one of the buttons has been pressed. if(digitalRead(Button_Left) == LOW) { next = 1; while(digitalRead(Button_Left) == LOW) { delay(1); } }else if(digitalRead(Button_Right) == LOW){ if(timeMinute < 55) timeMinute += 5; else timeMinute += 5 - 60; LightMostSignificantMinute(); while(digitalRead(Button_Right) == LOW) { delay(1); } } } next = 0;// >> Show the current less significant minute. LightLessSignificantMinute();// Changing less significant minute. while(next == 0) {// Probes if one of the buttons has been pressed. if(digitalRead(Button_Left) == LOW) { next = 1; while(digitalRead(Button_Left) == LOW) { delay(1); } }else if(digitalRead(Button_Right) == LOW){ if((timeMinute % 5) < 4) timeMinute++; else timeMinute -= 4; LightLessSignificantMinute(); while(digitalRead(Button_Right) == LOW) { delay(1); } } } ClearLeds(); currentFunction = 0; break; } SleepDevice();}void LightHour(){ ClearLeds();// Show the led for the hour. byte column = T2; byte mostSignificantLed = 0; if(timeHour == 12) { mostSignificantLed = 6; }else if(timeHour > 5){ column = T1; mostSignificantLed = 12 - timeHour; }else{ mostSignificantLed = 6 - timeHour; } digitalWrite(column, HIGH); digitalWrite(mostSignificantLed + Led_Circle_Start, HIGH);}void LightMostSignificantMinute(){ ClearLeds();// Show the leds for the minutes. byte column = T1; byte mostSignificantLed = 0; if(timeMinute < 5) { column = T2; }else if(timeMinute >= 30){ column = T1; }else{ column = T2; } mostSignificantLed = timeMinute / 5; if(mostSignificantLed > 5) { mostSignificantLed = 12 - mostSignificantLed; }else if(mostSignificantLed == 0){ mostSignificantLed = 6; }else{ mostSignificantLed = 6 - mostSignificantLed; } digitalWrite(column, HIGH); digitalWrite(mostSignificantLed + Led_Circle_Start, HIGH);}void LightLessSignificantMinute(){ ClearLeds(); byte mostSignificantLed = timeMinute / 5; byte lessSignificantLed = timeMinute % 5; if(lessSignificantLed > 0) { if(lessSignificantLed < 4) lessSignificantLed = 4 - lessSignificantLed; digitalWrite(T3, HIGH); digitalWrite(lessSignificantLed + Led_Circle_Start, HIGH); }}void ClearLeds(){ digitalWrite(T1, LOW); digitalWrite(T2, LOW); digitalWrite(T3, LOW); digitalWrite(Led_Circle_Start + 1, LOW); digitalWrite(Led_Circle_Start + 2, LOW); digitalWrite(Led_Circle_Start + 3, LOW); digitalWrite(Led_Circle_Start + 4, LOW); digitalWrite(Led_Circle_Start + 5, LOW); digitalWrite(Led_Circle_Start + 6, LOW);}ISR(TIMER2_COMPA_vect){ timeMiliseconds += 2088; if(timeMiliseconds >= 1000) { while(timeMiliseconds >= 1000) { timeMiliseconds -= 1000; timeSecond++; } if(timeSecond >= 60) { timeSecond -= 60; timeMinute++; if(timeMinute == 60) { timeMinute = 0; timeHour++; if(timeHour == 13) { timeHour = 1; } } } }}void ShowHour() { detachInterrupt(digitalPinToInterrupt(Button_Center)); detachInterrupt(digitalPinToInterrupt(Button_Left)); currentFunction = 1;}void ChangeHour() { detachInterrupt(digitalPinToInterrupt(Button_Left)); detachInterrupt(digitalPinToInterrupt(Button_Center)); currentFunction = 2;}