Experiment #17. Clock-thermometer.

So, I have experiment with thermometer based on DS18b20 and experiment with real time clock IC DS1307, and I took decision to combine it in one single device. Other reason why I did it is that I have broken china clock with good enclosure (:

Result looks something like this:

clock

I didn’t use shift register because I have some IC’s IO port expander PCA9539 from free samples NXP, I have some experience with it at experiment #13.

I’m going to start from indication system, which realized on two 7-segment displays (red for clock and blue for thermometer). Blue display was too bright and I place current limiting resistor, I was too lazy to make PWM for this purpose.

Here is schematic of indication system:

ind

PCB:

Front panel view of PCB you can see at the first picture.

The next step was main pcb with rtc clock and thermometer.

Schematic:

sch_main_board

And the pcb:

Code:


#include <stdio.h>
#include <htc.h>
#define _XTAL_FREQ 4000000
#include "usart.h"               //uart functions
#include "softi2c.h"             //i2c functions

#define timeh1 RB7  //3
#define timeh2 RB6  //4
#define timem1 RB4
#define timem2 RB5

#define tempd1 RB3
#define tempd2 RB2
#define tempd3 RB1

#define STATE TRISA2
#define PIN RA2

#define set_min RA3
#define set_hr RA4
#define setup RB0

__CONFIG(LVPDIS & WDTDIS & MCLREN & UNPROTECT & HS);

 unsigned char temphour = 0;         //hours
 unsigned char tempmin = 0;          //minutes

 char temperature;                  //temperature
 unsigned char temp_drob = 0;       //fractional part of temperature
 unsigned char sign;                //temperature sign

 volatile unsigned char button = 0;
 volatile unsigned char flag = 0;

const unsigned char tempdigit[11]={    //digits for display, temperature
 0b10110111,   //zero
 0b10000001,   //one
 0b00111101,   //two
 0b10101101,   //three
 0b10001011,   //four
 0b10101110,   //five
 0b10111110,   //six
 0b10000101,   //seven
 0b10111111,   //eight
 0b10101111,    //nine
 0b00001000
};

const unsigned char tempdigitvspoint[10]={  //temperature with a point
 0b11110111,   //zero
 0b11000001,   //one
 0b01111101,   //two
 0b11101101,   //three
 0b11001011,   //four
 0b11101110,   //five
 0b11111110,   //six
 0b11000101,   //seven
 0b11111111,   //eight
 0b11101111    //nine
};

const unsigned char timedigit[10]={            //time values
 0b11110101,   //zero
 0b00100100,   //one
 0b10111001,   //two
 0b10101101,   //three
 0b01101100,   //four
 0b11001101,   //five
 0b11011101,  //six
 0b10100100,   //seven
 0b11111101,   //eight
 0b11101101    //nine
};

const unsigned char timedigitvspoint[10]={       //time with the point
 0b11110111,   //zero
 0b00100110,   //one
 0b10111011,   //two
 0b10101111,   //three
 0b01101110,   //four
 0b11001111,   //five
 0b11011111,  //six
 0b10100110,   //seven
 0b11111111,   //eight
 0b11101111    //nine
};

/* Functions declaration */
static bit INIT(void);
void TX(unsigned char cmd);
unsigned char RX();
void get_temp();
unsigned char BCDconv (unsigned char source);
unsigned char DCBconv (unsigned char source);
void SetMin(unsigned char minutes);
unsigned char ReadMin();
void SetHour(unsigned char hours);
unsigned char ReadHour();
void SetSeconds(unsigned char seconds);
unsigned char ReadSeconds();
void ShowTime();
void SetupTime();
void InitIO(void);
void Display(unsigned char time, unsigned char temperaturet);
void Displaypoint(unsigned char time, unsigned char temperaturet);
void Displaypointminus(unsigned char time, unsigned char temperaturet);
void DispAll(unsigned char hour, unsigned char min, unsigned char temperaturet);

void main(void){
 unsigned char input;
 unsigned char i=0;

 CMCON = 0x07;

 TRISB = 0x00;
 TRISB0 = 1;
 TRISA3 = 1;
 TRISA4 = 1;
 get_temp();                 //Get temperature values for start
 /* For test purposes */
 /*
 init_comms();
 SetHour(15);
 SetMin(38);
 SetSeconds(23);
 get_temp();
 ShowTime();

 */

 InitIO();              //IO expander initialization

 /* Timer setup for refresh operation */

 T1CKPS1 = 1;
 T1CKPS0 = 1; // prescaler = 8

 T1OSCEN = 0; 
 TMR1CS = 0; // Fosc/4
 GIE = 1;   
 PEIE = 1;  
 TMR1IE = 1; 
 TMR1ON = 1; 
 TMR1H = 0b10110000; TMR1L = 0x00;  //timer starts from 65024
 INTE = 0;

 temphour = ReadHour();
 tempmin = ReadMin();
 //get_temp();

 for(;;){

 DispAll(temphour, tempmin , temperature);         //all info on the display
 /* Info update setup */
 if (flag == 20) {
 temphour = ReadHour();
 tempmin = ReadMin();
 i++;
 flag = 0;
 }
 if (i == 100) { TMR1IE = 0;
 get_temp();
 i = 0;
 TMR1IE = 1; }

 /* Button event handler */

 if (!set_hr) {
 TMR1IE = 0;
 __delay_ms(100);
 if (!set_hr) {

 if (temphour<24) {
 temphour++;
 SetHour(temphour);
 } else {
 temphour = 1;
 SetHour(temphour);
 }

 }
 TMR1IE = 1;
 }
 if (!set_min) {
 TMR1IE = 0;
 __delay_ms(100);
 if (!set_min) {
 if (tempmin<60) {
 tempmin++;
 SetMin(tempmin);
 } else {
 tempmin = 1;
 SetMin(tempmin);
 }

 }
 TMR1IE = 1;
 }

 if (!setup) {
 TMR1IE = 0;
 __delay_ms(100);
 if (!setup) {
 SetSeconds(0);

 }
 TMR1IE = 1;
 }

/*
 /* menu for uart */

 input = getch();

 switch (input) {
 case 49 : ShowTime();
 break;
 case 50 : SetupTime();
 break;
 case 51 : get_temp();
 ShowTime();
 break;
 }
 if (input == 49) {     SetupTime();}
*/

 }

}

interrupt isr() {               //interrupt handler

if (TMR1IF) {
flag++;
TMR1H = 0b10110000; TMR1L = 0x00;
TMR1IF = 0;  
}

}

/* 1-wire functions */
static bit INIT(void){
static bit b;
STATE = 1;
STATE = 0;
__delay_us(500);
STATE = 1;
__delay_us(65);
b = PIN;
__delay_us(450);

return b;

}

void TX(unsigned char cmd){
unsigned char temp = 0;
unsigned char i = 0;
temp = cmd;
for (i=0;i<8;i++) {
 if (temp&0x01) {
 STATE = 0;
 __delay_us(5);
 STATE = 1;
 __delay_us(70);
 } else {
 STATE = 0;
 __delay_us(70);
 STATE = 1;
 __delay_us(5);

 }
 temp >>= 1;
 }

}

unsigned char RX() {
unsigned char d = 0;
unsigned char i = 0;
for (i=0;i<8;i++){
 STATE = 0;
 __delay_us(6);
 STATE = 1;
 __delay_us(4);
 d>>=1;
 if (PIN == 1) d |= 0x80;
 //printf("\r\n %d", d);
 __delay_us(60);

 }

return d;

}

/* temperature value receiving */
void get_temp() {
static bit init;
unsigned char temp1;
unsigned char temp2;
init = INIT();
if (!init) {
TX(0xCC);
TX(0x44);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
} else printf("bug");
init = INIT();
if (!init) {
TX(0xCC);
TX(0xBE);

temp1 = RX();
temp2 = RX();

}
temp_drob = temp1 & 0b00001111;    
temp_drob = ((temp_drob*6)+2)/10;              
temp1 >>= 4;
sign = temp2 & 0x80;
temp2 <<= 4;
temp2 &= 0b01110000;
temp2 |= temp1;

if (sign) { temperature = 127-temp2;
 temp_drob = 10 - temp_drob;
 }   else temperature = temp2;

}

/* clock functions */

unsigned char BCDconv (unsigned char source) {
 unsigned char temp_min=0;
 unsigned char temp_maj=0;
 temp_min = source&15;
 temp_maj = source >> 4;
 //printf("\r\n minor - %x", temp_min);
 //printf("\r\n major - %x", temp_maj);
 temp_maj *= 10;
 //printf("\r\n major - %x", temp_maj);

 return temp_maj+temp_min;
}

unsigned char DCBconv (unsigned char source) {
 unsigned char temp_min=0;
 unsigned char temp_maj=0;
 temp_maj = source/10 ;
 temp_min = source - temp_maj*10;
 temp_maj <<= 4;

 return temp_maj+temp_min;

}

void SetMin(unsigned char minutes) {        
 i2c_start();
 i2c_tx(0b11010000);
 i2c_tx(0x01);
 i2c_tx(DCBconv(minutes));
 i2c_stop();
}

unsigned char ReadMin() {
 unsigned char temp = 0;
 i2c_start();            
 i2c_tx(0b11010000);
 i2c_tx(0x01);
 i2c_start();
 i2c_tx(0b11010001);
 temp = i2c_rx(0);
 i2c_stop();

 return BCDconv(temp);
}

void SetHour(unsigned char hours) {        
 i2c_start();
 i2c_tx(0b11010000);
 i2c_tx(0x02);
 i2c_tx(DCBconv(hours));
 i2c_stop();
}

unsigned char ReadHour() {
 unsigned char temp = 0;
 unsigned char temp2 = 0;
 i2c_start();            
 i2c_tx(0b11010000);
 i2c_tx(0x02);
 i2c_start();
 i2c_tx(0b11010001);
 temp = i2c_rx(0);
 i2c_stop();


 return BCDconv(temp);
}

void SetSeconds(unsigned char seconds) {        
 i2c_start();
 i2c_tx(0b11010000);
 i2c_tx(0x00);
 i2c_tx(DCBconv(seconds));
 i2c_stop();
}

unsigned char ReadSeconds() {
 unsigned char temp = 0;
 i2c_start();            
 i2c_tx(0b11010000);
 i2c_tx(0x00);
 i2c_start();
 i2c_tx(0b11010001);
 temp = i2c_rx(0);
 i2c_stop();

 return BCDconv(temp);
}

/* USART functions */
void ShowTime() {
 printf("\fTime - %d :", ReadHour());
 printf(" %d :", ReadMin());
 printf(" %d ", ReadSeconds());

 printf("\r\ntemperatura -- ");
 if (sign) printf("-"); else printf("+");
 printf("%d", temperature);
 printf(".%d", temp_drob);

 printf("\r\n*********************");

 printf("\r\n Menu");
 printf("\r\n 1 - Reload time");
 printf("\r\n 2 - Setup time");
 printf("\r\n 3 - Reload temp");

}

void SetupTime() {
 unsigned char state = 1;
 unsigned char temp_min = 0;
 unsigned char temp_maj = 0;
 unsigned char temp = 0;

 while(state){
 printf("\fEnter hours - ");
 temp_maj = getch();
 printf(" %c", temp_maj);
 temp_min = getch();
 printf("%c", temp_min);
 temp = getch();
 if (temp == 13) {
 temp_maj -= 48;
 temp_min -= 48;
 temp = temp_maj*10 + temp_min;
 if (temp < 24) {
 SetHour(temp);
 state = 0;
 }

 }
 }
 state = 1;
 while(state){
 printf("\fEnter minutes - ");
 temp_maj = getch();
 printf(" %c", temp_maj);
 temp_min = getch();
 printf("%c", temp_min);
 temp = getch();
 if (temp == 13) {
 temp_maj -= 48;
 temp_min -= 48;
 temp = temp_maj*10 + temp_min;
 if (temp < 61) {
 SetMin(temp);
 state = 0;
 }
 }
 }
 state = 1;
 while(state){
 printf("\fEnter seconds - ");
 temp_maj = getch();
 printf(" %c", temp_maj);
 temp_min = getch();
 printf("%c", temp_min);
 temp = getch();
 if (temp == 13) {
 temp_maj -= 48;
 temp_min -= 48;
 temp = temp_maj*10 + temp_min;
 if (temp < 61) {
 SetSeconds(temp);
 state = 0;
 }
 }
 }

 ShowTime();

}

/* IO expander functions */
void InitIO(void) {
 i2c_start();
 i2c_tx(0b11101000);
 i2c_tx(0b00000110);
 i2c_tx(0x00);
 i2c_tx(0x00);
 i2c_stop();
}

void Display(unsigned char time, unsigned char temperaturet) {
 unsigned char timetemp = 0;
 unsigned char temptemp = 0;
 timetemp = time;
 temptemp = temperaturet;
 i2c_start();
 i2c_tx(0b11101000);
 i2c_tx(0b00000010);
 i2c_tx(timedigit[timetemp]);
 i2c_tx(tempdigit[temptemp]);
 i2c_stop();

}

void Displaypoint(unsigned char time, unsigned char temperaturet) {
 unsigned char timetemp = 0;
 unsigned char temptemp = 0;
 timetemp = time;
 temptemp = temperaturet;
 i2c_start();
 i2c_tx(0b11101000);
 i2c_tx(0b00000010);
 i2c_tx(timedigitvspoint[timetemp]);
 i2c_tx(tempdigitvspoint[temptemp]);
 i2c_stop();

}

void Displaypointminus(unsigned char time, unsigned char temperaturet) {
 unsigned char timetemp = 0;
 unsigned char temptemp = 0;
 timetemp = time;
 temptemp = temperaturet;
 i2c_start();
 i2c_tx(0b11101000);
 i2c_tx(0b00000010);
 i2c_tx(timedigitvspoint[timetemp]);
 i2c_tx(tempdigit[temptemp]);
 i2c_stop();

}

void DispAll(unsigned char hour, unsigned char min, unsigned char temperaturet) {
 unsigned char tim = 0;
 unsigned char tem = 0;
 unsigned char buf = 0;

 if (!sign) {
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 tim = hour/10; tem = temperaturet/10;
 Display(tim, tem);
 timeh1 = 1; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 1; tempd2 = 0; tempd3 = 0;
 __delay_us(500);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 buf = tim*10;
 tim = hour - buf;
 tem = temperaturet - tem*10;
 Displaypoint(tim, tem);
 timeh1 = 0; timeh2 = 1; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 1; tempd3 = 0;
 __delay_us(500);

 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 tim = min/10; tem = temp_drob;
 Display(tim, tem);
 timeh1 = 0; timeh2 = 0; timem1 = 1; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 1;
 __delay_us(500);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 buf = tim*10;
 tim = min-buf;
 Display(tim, tem);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 1; tempd1 = 0; tempd2 = 0; tempd3 = 1;
 __delay_us(500);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 __delay_us(500);
 }  else
 {
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 tim = hour/10; tem = 10;
 Display(tim, tem);
 timeh1 = 1; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 1; tempd2 = 0; tempd3 = 0;
 __delay_ms(1);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 buf = tim*10;
 tim = hour - buf;
 tem = temperaturet/10;
 Displaypointminus(tim, tem);
 timeh1 = 0; timeh2 = 1; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 1; tempd3 = 0;
 __delay_ms(1);

 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 tim = min/10; tem = temperaturet - tem*10;
 Display(tim, tem);
 timeh1 = 0; timeh2 = 0; timem1 = 1; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 1;
 __delay_ms(1);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 buf = tim*10;
 tim = min-buf;
 Display(tim, tem);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 1; tempd1 = 0; tempd2 = 0; tempd3 = 1;
 __delay_ms(1);
 timeh1 = 0; timeh2 = 0; timem1 = 0; timem2 = 0; tempd1 = 0; tempd2 = 0; tempd3 = 0;
 __delay_ms(1);
 }
}

Work example video:

Sources

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.