LED Filament clock

A clock using "LED filament" strips
 
Please watch the video first - I don't have time to write it all out!
Notes
"LK" parts are 1206 zero-ohm links, not shown on schematic.
32K SMD crystal is an Abracon ABS25. You can also use a metal-can type. Note these come in
various accuracy specs - get the best one you can.
RS1D is a 200V 1A fast diode. Anything similar should be fine.
No I can't give you detailed BOM for Digikey etc. Everything you need is on the schematic.
Search Ebay or Aliexpress for "LED Filament" to find the LED filament strips.
Current draw at 12V is approx 150mA with LED voltage set to 75V (depends on LED voltage
setting). (If it draws more than about 250mA, it may go into thermal runaway so reduce LED
voltage)
Reed switches are used for time setting to avoid need for external switches. PCB will
accept a variety of reed or pushbutton switches
Inductor choice is rather critical. Bourns SRR5028 was found to perform best for this
size. If using something else, test it with all segments on and monitor power draw - if
you see it start to increase, bad things may happen.
Check for shorts between the 75V rail and anything else before first powering on to avoid
smoke issues.
No I'm not interested in making one for you or selling PCBs or supplying preprogrammed
PICs, sorry.
For discussion, please use this EEVBLOG
thread.
Things that can be improved
Increase digit spacing.
Tinted front window materials/diffuser to improve contrast between on & off
segments
High voltage PSU is only just good enough for the job - it runs quite warm, and above
about 80V may go into thermal runaway if lots of digits are on. Should probably be
replaced with something more efficient, plus a seperate 5V regulator.
It should be fairly easy to add backup from battery or supercap - isolate PIC supply with
a diode, and add code to sense power fail (Use a spare input pin to sense non backed-up 5V
rail) and go to sleep mode, after setting all outputs low to avoid leaking power to
drivers. Periodically wake on timer 1 interrupt up to maintain time and check if power has
come back.
Light sensing for auto brightness control (using PWM on driver output enable) - the
display will be way too bright to use in a bedroom
Smooth digit fade up/down to look more like a real filament.
Calibration for fine-tuning accuracy.
Schematic. PDF Version

PCB layout - rear view
PDF - colour
PDF - monochrome, mirrored for printing on transparency
to home etching
PCAD2006 PCB file NO! I CAN'T SEND YOU A FILE FOR ***ING
EAGLE, KICAD or any other PCB software OK! (But I think you can import PCAD into
Altium)
Gerber and drill files


Detail of sockets

PIC Code (for Microchip XC8) |
#include <pic.h>
// filament clock
// (c) Mike Harrison 2015
// www.electricstuff.co.uk
// Target PIC16F1824
#pragma config FOSC=INTOSC,MCLRE=ON,WDTE=ON,PWRTE=ON,BOREN=ON,CLKOUTEN=OFF
#pragma config LVP=OFF,BORV=HI,WRT=OFF
#define oe LATA2 // tpic595 latch output enable. Could use PWM for global dimming, or
multi-cycle pulses for per-segment dimming
#define lat LATC1 // tpic595 latch
// set switches
#define minsw RA0
#define hrsw RA1
// segment bits within shift registers
#define sa 4
#define sb 8
#define sc 16
#define sd 32
#define se 64
#define sf 2
#define sg 128
#define sx 1 // 10Hrs, colon
// seven-segment lookup
const char sevenseg[10]={
sa | sb | sc | sd | se | sf,
sb | sc,
sa | sb | sd | se | sg,
sa | sb | sc | sd | sg,
sb | sc | sf | sg,
sa | sc | sd | sf | sg,
sa | sc | sd | se | sf | sg,
sa | sb | sc ,
sa | sb | sc | sd | se | sf | sg,
sa | sb | sc | sd | sf | sg
};
unsigned char hsecs,mins,hours,colon; // NB hsecs counts half-seconds
void spibyte(char c)
{ // send byte to SPI port
SSP1IF=0;
SSP1BUF=c;
while(~SSP1IF);
}
void main(void)
{
OSCCON=0b01110000; // 8MHz
LATA=0;
TRISA=0b00110011;
WPUA =0b00000011; // pullups for switches
ANSELA=0;
LATC=0;
TRISC=0b00000000;
WPUC =0b00000000;
ANSELC=0;
OPTION_REG=0b00000000;
APFCON0=0; APFCON1=0;
// SPI setup
SSP1STAT=0b01000000; // CKE high
SSP1CON1=0b00100000; // master mode, clk=fosc/4
SSP1CON2=SSP1CON3=0;
T1CON=0b10001001; // timer1 on, T1 oscillator
oe=0; // output enable
hours=0; // "power out" indication, prevent counting
mins=0;
hsecs=0;
TMR1IF=1; // force initial update - 32K osc can take a few secs to start
do {
asm("clrwdt");
if (hours==0) if((minsw==0) || (hrsw==0)) hours=1; // start running after powerdown
if(TMR1IF) { // 2Hz tick
TMR1IF=0;
TMR1H|=0xC0; // preload Tmr1 for 2Hz=16384 counts
colon=hsecs&1;
if(minsw==0) if(++mins==60) mins=0;
if(hrsw==0) if(++hours==13) hours=1;
if(hours) // not startup
if(++hsecs==120) {
hsecs=0;
if(++mins==60) {
mins=0;
if(++hours==13) {
hours=1;
}
}
}
lat=0;
spibyte(sevenseg[hours%10] | (hours>9?sx:0));
spibyte(sevenseg[mins/10] | (colon?sx:0));
spibyte(sevenseg[mins%10]);
lat=1;
}
} while(1);
} |
#
|