DuinO'Clock - Small watch
### DESCRIPTION
Hi, 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 / COMPONENTS
The 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 MATERIALS
C1 - 10uf
C2 - 100nf
C3 - 100nf
C4 - 100nf
C5 - 10uf
C6 - 100nf
C7 - 100nf
C8 - 22pf
C9 - 22pf
C10 - 22pf
C11 - 22pf
D1:D16 - LED
PWR - LED
J1 - Conector USB(UX60SC-MB-5ST)
J2 - Conector(FH12-8S-1SH)
J3 - Conector(FH12-6S-1SH)
R1 - 1k
R2 - 1k
R3 - 10k
R4 - 1k
R5 - 1k
R6 - 1k
R7 - 470R
R8 - 470R
R9 - 470R
RPWR - 470R
S1 - Switch(B3U-wB)
SL - B3SL
SM - B3SL
SR - B3SL
U1 - 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 Crystal
Y2 - 12Mhz Crystal
### LEARN / TOPIC / BUILD INSTRUCTIONS
For 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.
### CODE
// DuinO'Clock
// 22/Nov/2018
// Benjamín Alejandro Luna Ramírez
// Versión 1.1
#include <avr/sleep.h>
// Constants
const 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 globales
byte 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;
}
DuinO'Clock - Small watch
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
- Comments(8)
- Likes(50)
- Engineer Nov 04,2024
- Engineer Sep 29,2024
- Engineer Jan 18,2022
- Engineer Dec 19,2018
- Engineer Dec 19,2018
- Engineer Dec 18,2018
- Manuel Ortiz Dec 13,2018
- Engineer Dec 13,2018
- ELB Dec 12,2018
- Engineer Dec 11,2018
- Engineer Dec 11,2018
- chidgear Dec 10,2018
- dceajm07 Dec 10,2018
- Engineer Dec 10,2018
- Engineer Dec 10,2018
- Engineer Dec 10,2018
- Engineer Dec 04,2018
- Engineer Dec 04,2018
- Engineer Dec 04,2018
- Engineer Dec 04,2018
- Engineer Dec 04,2018
- Engineer Dec 04,2018
- Engineer Nov 28,2018
- Engineer Nov 21,2018
- Engineer Nov 21,2018
- Engineer Nov 20,2018
- Engineer Nov 18,2018
- Engineer Nov 18,2018
- Engineer Nov 18,2018
- Engineer Nov 18,2018
- Engineer Nov 05,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- arqcervantesfq Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- c77 Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Engineer Oct 25,2018
- Alex L Oct 25,2018
- Engineer Oct 20,2018
- 40 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
8usability
-
9creativity
-
8content
-
9design
-
9usability
-
7creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
9design
-
10usability
-
9creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
9creativity
-
9content
-
9design
-
9usability
-
9creativity
-
9content
-
10design
-
10usability
-
5creativity
-
7content
-
10design
-
10usability
-
9creativity
-
9content
-
8design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
9creativity
-
10content
-
10design
-
10usability
-
10creativity
-
8content
-
10design
-
10usability
-
10creativity
-
9content
-
9design
-
10usability
-
8creativity
-
10content
-
10design
-
10usability
-
9creativity
-
10content
-
9design
-
10usability
-
9creativity
-
9content
-
10design
-
9usability
-
8creativity
-
9content
-
10design
-
10usability
-
9creativity
-
8content
-
10design
-
10usability
-
8creativity
-
10content
-
10design
-
9usability
-
8creativity
-
9content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
8creativity
-
9content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
8creativity
-
9content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
10usability
-
10creativity
-
10content
-
9design
-
9usability
-
8creativity
-
9content
-
10design
-
10usability
-
10creativity
-
10content
-
10design
-
7usability
-
8creativity
-
9content
-
10design
-
10usability
-
8creativity
-
10content
-
10design
-
10usability
-
9creativity
-
10content
More by Benjamín Alejandro Luna Ramírez
-
-
-
-
-
-
3D printed Enclosure Backplate for Riden RD60xx power supplies
153 1 1 -
-