PIC Microcontroller project – 24 hour clock and thermometer displayed via 16f690 microcontroller and LCD programmed in C

I got to thinking that an interest in hi-fi can be a bit geek ( in a good way ) so I thought one of my latest geek projects might be of interest to some of you. You could build the project ‘as is’ without learning embedded C programming or you could use the project as a spring board to extra geekiness and weekend fun – I’ll leave that to you

Learning embedded C can be hugely rewarding and creative. The tool chain needed to get you started is either free (MPXLAB  IDE  and XC8 C compiler are both free downloads from the Microchip website and the pickit 3 needed to download compiled C code to your target microcontroller (16f690 in this case) is less than 50GBP.

PIC Microcontroller project – 24 hour clock and thermometer displayed via 16f690 microcontroller and LCD programmed in CYou might be wondering why this project might be interesting to hi-fi enthusiasts. Well I have a few suggestions … the finished project will allow you to keep tabs on the temperature of your listening room via an LM35 temperature sensor, which is important not just for your own comfort, but electro-mechanical devices such as turntables, phono cartridges and loudspeakers or headphones perform best at temperatures that are comfortable to humans like you and me – 18 Celcius to 23 Celcius for example.

The other feature, the 24 hour clock is simply a clock as implemented at the moment, which is always useful in a gadget, but with additional software development could be used to time the hours of phono cartridge use, or if you have a valve amplifier the hours of valve usage. Either way it’s a great feature as it is and leaves further firmware development up to your imagination.

Here is a roughly drawn but accurate schematic circuit diagram and also the full C source code plus full build details – if you have any questions or queries please ask! Have fun…

Here’s a top view showing the sandwich construction of the thermo_timer – the front is a layer of 4mm clear acrylic, then brass pillars stand this off from the strip board circuit board. Another set of brass pillars then stand off the second layer of 4mm clear acrylic.

Here is the rear of the prototype which shows how simple the circuit really is – just a Microchip PIC 16f690, an LM35 temperature sensor which generates 10mV/ degree Centigrade, a contrast potentiometer for the LCD, and two push buttons to set hours and minutes of the clock.

And here is the C source code for the clock thermometer project, which has been complied with the free Microchip XC8 C complier and downloaded to the 16f690 with Microchip MPLABX IDE. Feel free to copy and use/ enhance this code to learn more about the C language and the PIC range of Microcontrollers, as I did and am still doing :-) I’d be really pleased if you would link to this page if you find it helpful.

/*
// File:   lcd_thermo_clock_16f690.c
* Author: Phil Glazzard
* version 1.03 – firmware modified 1 June 2015
* Created on 26 April 2015, 14:05 – MODIFIED TRM1 PRE-LOAD TO SLOW CLOCK 11/06/2015
*/
//0XDB CHANGED TO 0XA4 IN TMR1L

// PIC16F690 Configuration Bit Settings

// ‘C’ source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#define _XTAL_FREQ 4000000      // 4MHz clock defined for __delay_ms() function
#define RS PORTBbits.RB7        // RS = RB7
#define E PORTBbits.RB5         // E = RB5

int thous, huns, tens, units;   // define global variables
int temp, temp1;
char tick,seconds_lsb,seconds_msb, seconds, minutes,minute_msb, minute_lsb, minutes_msb, hundreds_lsb, hundreds_msb, hours = 0;
void config_timer1(void)
{
TMR1IF = 0;                 //clear timer1 interrupt flag
TMR1L = 0;                  // clear low byte of 16 bit timer1
TMR1H = 0;                  // clear high byte of 16 bit timer1
T1CONbits.T1CKPS0 = 1;      // select 1:8 pre-scaler
T1CONbits.T1CKPS1 = 1;
PIE1bits.TMR1IE = 1;        //enable timer1 interrupt
INTCONbits.PEIE = 1;        //enable peripheral interrupt enable
INTCONbits.GIE = 1;         // enable global interrupt enable
}
void timer1_on(void)
{
TMR1H = 0x0B;               // pre-load 16 bit timer1 with 0x0BA4
TMR1L = 0xA4;               // 0.5 sec/ 2Hz frequency before overflow
T1CONbits.TMR1ON = 1;       // start timer1
}
int interrupt isr (int)
{

if (TMR1IF == 1)                   // check to see if the interrupt was caused by TMR1 overflowing
{
TMR1ON = 0;                           // turn TMR1 off
seconds = seconds + 1;                // increment seconds variable
TMR1H = 0x0B;               // pre-load 16 bit timer1 with 0x0BA4
TMR1L = 0xA4;               // 0.5 sec/ 2Hz frequency before overflow
T1CONbits.TMR1ON = 1;       // start timer
TMR1IF = 0;                 // clear TMR1 interrupt flag
RA4 = seconds;              // flip RA4 each second to flash LED at 1 Hz

temp1 = ADRESL;              //store low byte of ADC conversion in temp1
temp1 =  temp1 + (ADRESH <<8);//shift high byte of ADC conversion 8 bits left
//and add to temp1 to give 10 bit ADC result.
temp = (int)(temp1 /0.2046);//cast expression as an integer to avoid floating
//point arithmetic.
// 102.3 = 5V (Vref)so 10mV = 1deg C = 102.3/500 = 0.2046
ADIF = 0;                    // clear the ADC interrupt flag ready for next conversion
}
}

void clock()
{
E = 1;                                  // creates a 1ms pulse to clock commands and data
__delay_ms(1);                          // into the LCD module
E = 0;
}

void lcd_initialisation()
{
__delay_ms(100);                // 100ms delay after ‘power on’
RS = 0;
PORTC = 0x30;                   //Function set RS RW D7 D6 D5 D4 D3 D2 D1 D0
__delay_ms(5);                 //               0 0  0  0  1  1  0  0  0  0 = 0x30
clock();
RS = 0;
PORTC = 0x30;                      //Function set RS RW D7 D6 D5 D4 D3 D2 D1 D0
__delay_us(100);                 //               0 0 0  0  1  1  0  0  0  0 = 0x30
clock();
RS = 0;

PIC Microcontroller project – 24 hour clock and thermometer displayed via 16f690 microcontroller and LCD programmed in C SchematicPORTC = 0x30;                     //Function set RS RW D7 D6 D5 D4 D3 D2 D1 D0
__delay_us(100);                 //               0 0  0  0  1  1  0  0  0  0 = 0x30
clock();
RS = 0;
PORTC = 0x38;                   //Function set RS RW D7 D6 D5 D4 D3 D2 D1 D0
clock();                        //              0 0  0  0  1  1  1  0  0  0 = 0x38
__delay_us(200);
RS = 0;
PORTC = 0x08;                   //Display off
clock();
__delay_ms(1);
RS = 0;
PORTC = 0x01;                   // clear display
clock();
__delay_ms(10);
RS = 0;
PORTC = 0x06;                   // entry mode set
clock();
__delay_ms(1);
RS = 0;
PORTC = 0x0C;                   // LCD display ON, cursor off, cursor blinking off
clock();
__delay_ms(1);}
void clear_lcd()
{RS=0;
PORTC = 0x0F;
clock();
__delay_ms(1);}

void config_ports(void)

{

 

For more detail: PIC Microcontroller project – 24 hour clock and thermometer displayed via 16f690 microcontroller and LCD programmed in C

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter