The main idea of this project was to make a customizable clock, a clock that would have the option to change its appearance very easily, The first option was to make it with RGB LEDs and change the color at will, maybe to have the ability to change the color according to the time of the day or with the ambient temperature, but what is more customizable than a display by itself, nowadays we can find very nice IPS Displays that are very cheap.
Maybe the hardest step of this project was the clock creation, making the graphics for each clock was really challenging as I wanted to look very similar to the real ones, like the Flip Clock, the seven-segment Display clock, the LED matrix clock.
These are only a few clocks that I have created, but it will be awesome to see other designs and that is why I’m sharing the design files of this project, I think it would be awesome to see how a project can evolve in the maker community.
I have also designed a 3D printed enclosure or in this case a frame. It consists of only 3 parts that glued together to make a single clock piece.
The PCB is intended to be compatible with any Microcontroller or SBC like the Raspberry as it only needs some GPIOs and an SPI Port. This makes the PCB compatible with a simple microcontroller as an Arduino to other more advanced microcontrollers. We could say this board is a breakout board for the arrangement of six displays and 4 buttons.
Before writing the clock firmware I decided to test all the designs that I have already created on the computer, so using the Raspberry Pi Pico I have written a simple program that allows me to set an image for each display in order to simulate how the clock would look like.
The code for this simple task consists of the initialization of the displays and just sensing the raw data of each image to the corresponding display.
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#include "ST7735.h"
#include "clockDigital.h"
#include "clockFlip.h"
#include "clockMatrix.h"
#include "clockVFD.h"
#include "clockInk.h"
#include "clockWood.h"
#define ONBOARD_LED 25
int main(){
stdio_init_all();
PIO pio = pio0;
uint sm = 0;
uint offset = pio_add_program(pio, &SPILCD_program);
lcdPIOInit(pio, sm, offset, PIN_SDI, PIN_SCK, SERIAL_CLK_DIV);
gpio_init(ONBOARD_LED);
gpio_set_dir(ONBOARD_LED, GPIO_OUT);
gpio_init(PIN_CS1);
gpio_init(PIN_CS2);
gpio_init(PIN_CS3);
gpio_init(PIN_CS4);
gpio_init(PIN_CS5);
gpio_init(PIN_CS6);
gpio_init(PIN_DC);
gpio_init(PIN_RST);
gpio_init(PIN_BLK);
gpio_set_dir(PIN_CS1, GPIO_OUT);
gpio_set_dir(PIN_CS2, GPIO_OUT);
gpio_set_dir(PIN_CS3, GPIO_OUT);
gpio_set_dir(PIN_CS4, GPIO_OUT);
gpio_set_dir(PIN_CS5, GPIO_OUT);
gpio_set_dir(PIN_CS6, GPIO_OUT);
gpio_set_dir(PIN_DC, GPIO_OUT);
gpio_set_dir(PIN_RST, GPIO_OUT);
gpio_set_dir(PIN_BLK, GPIO_OUT);
gpio_put(ONBOARD_LED, 1);
gpio_put(PIN_CS1, 0);
gpio_put(PIN_CS2, 0);
gpio_put(PIN_CS3, 0);
gpio_put(PIN_CS4, 0);
gpio_put(PIN_CS5, 0);
gpio_put(PIN_CS6, 0);
gpio_put(PIN_RST, 1);
lcdInit(pio, sm, st7735_initSeq);
gpio_put(PIN_BLK, 1);
lcdStartPx(pio,sm);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, one_Flip[i]);
}
gpio_put(PIN_CS1, 1);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, two_Matrix[i]);
}
gpio_put(PIN_CS2, 1);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, three_Digital[i]);
}
gpio_put(PIN_CS3, 1);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, four_VFD[i]);
}
gpio_put(PIN_CS4, 1);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, five_Ink[i]);
}
gpio_put(PIN_CS5, 1);
for (int i = 0; i < 160*80*2; i++){
lcdPut(pio, sm, six_Wood[i]);
}
}
The clock main program#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#include "hardware/rtc.h"
#include "pico/util/datetime.h"
#include "ST7735.h"
#define ONBOARD_LED 25
#define HRS 0
#define MINS 1
#define OFF 0
#define ON 1
#define PIN_BTNA 6
#define PIN_BTNB 7
#define PIN_BTNC 8
#define PIN_BTND 9
bool Backlight = OFF;
bool ConfigureTime_MODE = OFF;
uint Selection = HRS;
// Start on Friday 26th of March 2021 12:34:00
datetime_t t = {
.year = 2021,
.month = 03,
.day = 26,
.dotw = 5, // 0 is Sunday, so 5 is Friday
.hour = 12,
.min = 34,
.sec = 00
};
void gpio_callback(uint gpio, uint32_t events) {
if(gpio == PIN_BTND){
if(ConfigureTime_MODE == ON){
ConfigureTime_MODE = OFF;
rtc_set_datetime(&t);
}else if(ConfigureTime_MODE == OFF){
ConfigureTime_MODE = ON; // Configuration Mode Enabled
}
}
if(ConfigureTime_MODE){
if(gpio == PIN_BTNA){
if(Selection == HRS){
if(t.hour < 23){
t.hour += 1;}}
else if(Selection == MINS){
if(t.min < 59){
t.min += 1;}}
}
if(gpio == PIN_BTNB){
if(Selection == HRS){
if(t.hour > 0 ){
t.hour -= 1;}}
else if(Selection == MINS){
if(t.min > 0){
t.min -= 1;}}
}
if(gpio == PIN_BTNC){
if(Selection == HRS){
Selection = MINS;}
else if(Selection == MINS){
Selection = HRS;}
}
}else if(ConfigureTime_MODE == OFF){
if(gpio == PIN_BTNC){
if(Backlight == ON){
gpio_put(PIN_BLK, OFF);
Backlight = OFF;
}else if(Backlight == OFF){
gpio_put(PIN_BLK, ON);
Backlight = ON;
}
}
}
}
int main(){
stdio_init_all();
// Start the RTC
rtc_init();
rtc_set_datetime(&t);
PIO pio = pio0;
uint sm = 0;
uint offset = pio_add_program(pio, &SPILCD_program);
lcdPIOInit(pio, sm, offset, PIN_SDI, PIN_SCK, SERIAL_CLK_DIV);
gpio_set_irq_enabled_with_callback(PIN_BTNA, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
gpio_set_irq_enabled_with_callback(PIN_BTNB, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
gpio_set_irq_enabled_with_callback(PIN_BTNC, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
gpio_set_irq_enabled_with_callback(PIN_BTND, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
gpio_init(ONBOARD_LED);
gpio_set_dir(ONBOARD_LED, GPIO_OUT);
gpio_init(PIN_CS1);
gpio_init(PIN_CS2);
gpio_init(PIN_CS3);
gpio_init(PIN_CS4);
gpio_init(PIN_CS5);
gpio_init(PIN_CS6);
gpio_init(PIN_DC);
gpio_init(PIN_RST);
gpio_init(PIN_BLK);
gpio_set_dir(PIN_CS1, GPIO_OUT);
gpio_set_dir(PIN_CS2, GPIO_OUT);
gpio_set_dir(PIN_CS3, GPIO_OUT);
gpio_set_dir(PIN_CS4, GPIO_OUT);
gpio_set_dir(PIN_CS5, GPIO_OUT);
gpio_set_dir(PIN_CS6, GPIO_OUT);
gpio_set_dir(PIN_DC, GPIO_OUT);
gpio_set_dir(PIN_RST, GPIO_OUT);
gpio_set_dir(PIN_BLK, GPIO_OUT);
gpio_put(PIN_CS1, 0);
gpio_put(PIN_CS2, 0);
gpio_put(PIN_CS3, 0);
gpio_put(PIN_CS4, 0);
gpio_put(PIN_CS5, 0);
gpio_put(PIN_CS6, 0);
gpio_put(PIN_RST, 1);
lcdInit(pio, sm, st7735_initSeq);
gpio_put(PIN_BLK, ON);
Backlight = ON;
gpio_put(ONBOARD_LED, 1);
lcdStartPx(pio,sm);
while(1){
if(ConfigureTime_MODE == OFF){
rtc_get_datetime(&t);}
if(t.hour >= 1 & t.hour <= 9){
lcdDrawNumber(pio,sm,display1,0);
lcdDrawNumber(pio,sm,display2,t.hour);
}else if(t.hour >= 10 & t.hour <= 12){
lcdDrawNumber(pio,sm,display1,1);
lcdDrawNumber(pio,sm,display2,t.hour-10);
}else if(t.hour >= 13 & t.hour <= 21){
lcdDrawNumber(pio,sm,display1,0);
lcdDrawNumber(pio,sm,display2,t.hour-12);
}else if(t.hour >= 22 ){
lcdDrawNumber(pio,sm,display1,1);
lcdDrawNumber(pio,sm,display2,t.hour-22);
}else if (t.hour == 0){
lcdDrawNumber(pio,sm,display1,1);
lcdDrawNumber(pio,sm,display2,2);
}
if(t.min >= 0 & t.min <= 9){
lcdDrawNumber(pio,sm,display4,0);
lcdDrawNumber(pio,sm,display5,t.min);
}else if(t.min >= 10 & t.min <= 19){
lcdDrawNumber(pio,sm,display4,1);
lcdDrawNumber(pio,sm,display5,t.min-10);
}else if(t.min >= 20 & t.min <= 29){
lcdDrawNumber(pio,sm,display4,2);
lcdDrawNumber(pio,sm,display5,t.min-20);
}else if(t.min >= 30 & t.min <= 39 ){
lcdDrawNumber(pio,sm,display4,3);
lcdDrawNumber(pio,sm,display5,t.min-30);
}else if(t.min >= 40 & t.min <= 49 ){
lcdDrawNumber(pio,sm,display4,4);
lcdDrawNumber(pio,sm,display5,t.min-40);
}else if(t.min >= 50 & t.min <= 59 ){
lcdDrawNumber(pio,sm,display4,5);
lcdDrawNumber(pio,sm,display5,t.min-50);
}
if(t.hour < 12 )
lcdDrawNumber(pio,sm,display6,AM);
else
lcdDrawNumber(pio,sm,display6,PM);
if(ConfigureTime_MODE == OFF){
lcdDrawNumber(pio,sm,display3,COLON);
sleep_ms(500);
lcdDrawNumber(pio,sm,display3,SPACE);
sleep_ms(500);
}else{
if(Selection == HRS){
sleep_ms(200);
lcdDrawNumber(pio,sm,display1,SPACE);
lcdDrawNumber(pio,sm,display2,SPACE);
lcdDrawNumber(pio,sm,display3,COLON);
sleep_ms(200);
}else if(Selection == MINS){
sleep_ms(200);
lcdDrawNumber(pio,sm,display3,COLON);
lcdDrawNumber(pio,sm,display4,SPACE);
lcdDrawNumber(pio,sm,display5,SPACE);
sleep_ms(200);
}
}
}
}
Now the firmware is also available for the ESP32 using the Arduino IDE, you can download the examples in my GitHub and also the example of Youtube Livestreaming Notifier.
https://github.com/JosueAGtz/displayArray
Visit my Tindie Store for the assembled board.
Visit my site to download the Design Files. The UF2 and full source code can be downloaded from my site.
Comments