Handheld Pt100 Thermometer

Wichit Sirichote, wichit.sirichote@gmail.com

Build a handheld thermometer with PIC LCD interface and Pt100 sensor.


Platinum thermometer is one of the high accuracy thermometer for lab use. This handheld thermometer page shows how to use PIC chip with glass LCD interface and analog front-end for reading the resistance of Pt100 sensor. The software performs interpolation for converting the resistance of Pt100 sensor to temperature using ITS-90 scale. In addition, data logging also provided with USB interface. User can log the temperature every one minute and upload the record to PC with USB interface.

Figure 1: Prototype of Handheld Pt100 thermometer.

Figure 2 shows block diagram of the thermoemeter. V1 provides 1mA DC current source. R2 is Pt100 sensor. The voltage developed across R2 is measured with the LTC2420, 20-bit sigma-delta A/D converter. The readings are fed to the microcontroller using SPI interface. The microcontroller, PIC18F87J93 is LCD microcontroller. It can drive the glass LCD with internal LCD driver port. The software performs interpolation that converts resistance to temperature using ITS-90 scale. The FT232 converts UART to USB for interfacing with PC.

Figure 2: Block diagram.

The complete schematic is shown in Figure 3. The 1mA DC current source is generated by LM334, U4. This current source is supplied to the Pt100 sensor through the DIN-7 connector pin 1 and pin 3. Pin 2 is used to measured the developed voltage across the Pt100 sensor. This voltage is fed to the 20-bit sigma-delta A/D converter at pin 3 with low pass filter front end circuit directly. No need additional amplification. Reference voltage is provided by LM385 reference diode. PIC Microcontroller, PIC18F87J93 has LCD driver ports. It can drive the glass LCD directly. Internal LCD ports will generate the AC pulse for driving the segment and common plan directly. The glass LCD is varitronix 41/2 digits.

Figure 3: Hardware schematic.

Varitronix glass LCD

The display is 4 1/2 digits glass LCD made by Varitronix. It has 40 pins. Pin 1 and pin 40 are COMMON plane. The segment pins are pin 2 to pin 39.
Figure 4: Varitronix glass LCD pin diagram.

Location of each digit is shown in Figure 5. From lefthand is 5,4,3,2,1 for digit.
Figure 5: Segment locations.

Location of each segemnt and symbols are shown in Figure 6.

Figure 6: Pin and its function. For example segment 5BC is pin 3. If it was activated, the left-hand digit will show '1'.

The listings of source code is shown in Figure 7.

// Pt100 Thermometer V1.0
// Processesor: PIC18F87J93
// Clock: 4MHz internal RC
// USB interface: FT232RL, 9600 8n1
// Probe: Pt100 three wires
// Measuring range: -200.0C to +200.0C
// ADC: LTC2420 20-bit sigma delta converter
// Interpolation method: Newton Raphson
// LCD: Glass LCD 4 1-2 digit Varitronic
// Sensor connector: DIN 5 pins
// SysTick: 0.5s
// Power: +9V battery, ~7mA consumption
//
#include "lcd.h"
char buffer[64];
unsigned int count=0;
unsigned long x1,x2,x3,x4,x5;
float ADC1,k;
           float Temperature;
           float probe_resistance;
float Tem,TemX,OHM,OHM1,Tem0,FT,F1T,correct;
short mode=0;
           short key1_press=0;
           short cold_boot=0;
           short boot_count=0;
float Tmin=0,Tmax=0,Tcurrent=0;
           short fill_data=0;
           short fill_counter=0;
short key3_press=0,degree=0;
short key2_press=0;
           int set_interval=60; // interval for recording, default is 60s = 300 ticks, 1 tick = 0.5s
         
float TemF=0;
           // display temperaure in Fahrenheit
float Temp;
           float BATT_volt;
float memory[800];
#define max_record 800
int memory_counter=0;
           float Vraw;
int y1,y2,y3,y4,y5;
char menu[] = "\r\nSP print readings\
   \r\nt Temperature upload\
   \r\nv voltages upload\
   \r\n? help";
         
#define R0 100.0
         
#define gain 1.2395/1048576 // Vref LM385 / ADC resolution
           #define calibrate 113.1/112.4 // calibrate for 1mA current source
#define mode_max 6
         
#define key1 PORTB.B0
           #define key2 PORTB.B1
           #define key3 PORTB.B2
// function prototype declaration
           void write_temp_LCD_degreeF();
         
/* read 32-bit data from LTC2420 */
unsigned long read_ADC1(void)
           {
   char k;
   long n;
 n= 0;
   //ADC_CS1 = 0;
   PORTB &= ~8; // RB3
   for(k=0; k<32; k++)
   {
   n<<= 1;
   //ADC_SCK = 1;
   PORTB |= 0x20;
   if(PORTB&0x10) n |= 1;
   //ADC_SCK = 0;
   PORTB &= ~0x20;
   }
   //ADC_CS1 = 1;
   PORTB |= 8;
   if(n&0x10000000) return 0; // return 0 if Vin is out of range
   n&=0x1fffffff; // maskout sign bit if Vin is positive
   n>>=8; // get 20-bit conversion result
   return n;
   }
#define ADC_CS1 PORTB.B3 // output bit
           #define ADC_SDO PORTB.B4 // input bit
           #define ADC_SCK PORTB.B5 // output bit
         
/* 5-point moving average */
           // return data that scaled with reference voltage in uV unit
           unsigned long filter_ADC(void)
           {
   if(++boot_count>6) {
   boot_count=6;
   cold_boot=1;
   }
   x5 = x4;
   x4 = x3;
   x3 = x2;
   x2 = x1;
   x1 = read_ADC1();
   return ((x1+x2+x3+x4+x5)/5);
   }
void Delay_mS(unsigned long a) { 
   a *= 370;
   while (--a!=0); 
   }
// simple delay ~100us
           void Delay_100uS(unsigned long a) { 
   a *= 37;
   while (--a!=0); 
   }
void digit_clear()
           {
   all_1_off
   all_2_off
   all_3_off
   all_4_off
   all_5_off
   all_dot_off
   }
         
void Newton_Raphson(void){
 Tem0 = 0;
 Tem = 0;
   // enter resistance to test the interpolation
   // commented it when running
   // OHM1 = 96.4778; // for testing
 
 if(OHM1 >= 99.761655){
 do{
 Tem0 = Tem;
 FT = ((-0.58020*pow(10,-6)*pow(Tem0,2))+(3.90802*pow(10,-3)*Tem0)+(1-OHM1/99.761655));
 F1T = (-1.1604*pow(10,-6)*Tem0)+3.90802*pow(10,-3);
 Tem = Tem0 -(FT/F1T);
             
   // sprintf(buffer,"\r\nTem = %f ,Tem0=%f",Tem,Tem0);
   // UART1_Write_Text(buffer);
 }while(abs(Tem-Tem0)>1*pow(10,-2));
 correct = 6*pow(10,-6)*pow(Tem,2)+0.0006*Tem-0.6996;
 TemX = Tem+correct;
 // sprintf(buffer,"correct %f,Tem = %f ,TemX=%f \n",correct,Tem,TemX);
   // UART1_Write_Text(buffer);
   // sprintf(buffer,",%0.2f Tmin=%0.2f Tmax=%0.2f",TemX,Tmin,Tmax);
   // UART1_Write_Text(buffer);
   
   // sprintf(buffer," %02X %02X %02X",ADCON0, ADCON1, ADCON2);
   // UART1_Write_Text(buffer);
         
 
 }
 
else{ do{
 Tem0 = Tem;
FT = ((3.90802)*pow(10,-3)*Tem0)+((-0.58020)*pow(10,-6)*pow(Tem0,2))+((0.42735)*pow(10,-9)*pow(Tem0,3))+((-4.27350)*pow(10,-12)*pow(Tem0,4))+(1-OHM1/99.761655);
F1T = ((3.90802)*pow(10,-3))+((-1.1604)*pow(10,-6)*Tem0)+((1.28205)*pow(10,-9)*pow(Tem0,2))+((-17.094)*pow(10,-12)*pow(Tem0,3));
Tem = Tem0 -(FT/F1T);
 }while(abs(Tem-Tem0)>1*pow(10,-2));
 correct = 6*pow(10,-6)*pow(Tem,2)+0.0006*Tem-0.6996;
 TemX = Tem+correct;
 // printf("\n correct %f,Tem = %f ,TemX=%f \n",correct,Tem,TemX);
   // sprintf(buffer,",%f",TemX);
   // UART1_Write_Text(buffer);
 
 }
 
}
// write string in buffer to LCD
           // 1 8 8 8 8
           // digit5 digit4 digit3 digit2 digit1
           // buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]
           void write_temp_LCD()
           {
   if(mode==0 && degree==0)
   {
   if(TemX <0) 
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(TemX*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((TemX >99.9) || (TemX < -99.9)) FormatChar_4(buffer[0]);
 all_3_off
   if((TemX >9.9) || (TemX <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
   
   // if mode=1 and degree=1 display in F
   }
   
   if(mode==0 && degree==1)
   {
   write_temp_LCD_degreeF();
   }
   }
         
void write_temp_LCD_degreeF()
           {
   //if(mode==1)
   {
   
   TemF = TemX *9/5 +32; // convert Celsius to Fahrenheit
   
   
   if(TemF <0)
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(TemF*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((TemF >99.9) || (TemF < -99.9))FormatChar_4(buffer[0]);
 all_3_off
   if((TemF >9.9) || (TemF <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
         
 }
           }
 
void read_key1()
           {
   if(key1==0 && key1_press==0)
   {
   key1_press=1;
   
   mode++;
   if(mode>mode_max) mode=0; //display^=1;
   
   
   }
}
void release_key1()
           {
   if(key1) key1_press=0;
   }
         
// degree=0 for degree C and degree=1 for F
void read_key3()
           {
   if((PORTB&4)==0 && key3_press==0)
   {
   key3_press=1;
 //UART1_Write_Text("*");
   // mode++;
   degree^=1;
   //if(degree)low_batt
   //else off_low_batt
   }
}
void release_key3()
           {
   if(PORTB&4) key3_press=0;
   }
void read_key2()
           {
   if((PORTB&2)==0 && mode==6)
   {
   //key2_press=1;
 //UART1_Write_Text("*");
   // mode++;
   if(++set_interval>60) set_interval=1;
   }
   }
void release_key2()
           {
   if(PORTB&2) key2_press=0;
   }
void write_resistance_lcd()
           {
   if(mode==3)
   {
   //current_reading=TemX;
   all_dot_off
   dot3
   sprintf(buffer,"%05d",abs(k*1E5));
   off_plus
   
   all_5_off
   FormatChar_5(buffer[0]);
 all_4_off
   FormatChar_4(buffer[1]);
 all_3_off
   FormatChar_3(buffer[2]);
 all_2_off
   FormatChar_2(buffer[3]);
 all_1_off
   FormatChar_1(buffer[4]);
   }
         
}
short tick=0;
void interrupt()
           {
   if(PIR1.TMR1IF)
   {
   PIR1.TMR1IF=0; // must be cleared by software
   tick=1;
   }
   }
void wait_tick()
           {
   while(tick==0)
   asm SLEEP; // enter idle mode continue;
   tick=0;
   }
void min_value()
           {
   if(mode==1 && degree==0)
   {
   // digit_clear();
   // FormatChar_3('L');
   // all_dot_off
   // FormatChar_2('L');
   // FormatChar_1('O');
   // Delay_ms(300);
   low_batt
   
   if(Tmin <0)
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(Tmin*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((Tmin >99.9) || (Tmin < -99.9)) FormatChar_4(buffer[0]);
 all_3_off
   if((Tmin >9.9) || (Tmin <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
   
   }
   
   if(mode==1 && degree==1)
   {
   low_batt
   Temp = Tmin *9/5 +32; // convert Celsius to Fahrenheit
   if(Temp <0)
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(Temp*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((Temp >99.9) || (Temp < -99.9)) FormatChar_4(buffer[0]);
 all_3_off
   if((Temp >9.9) || (Temp <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
   
   
   }
   
   }
void max_value()
           {
   if(mode==2 && degree==0)
   {
   off_low_batt
   //digit_clear();
   //FormatChar_3('L');
   //all_dot_off
   //FormatChar_2('H');
   //FormatChar_1('I');
   //Delay_ms(300);
   
   if(Tmax <0)
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(Tmax*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((Tmax >99.9) || (Tmax < -99.9)) FormatChar_4(buffer[0]);
 all_3_off
   if((Tmax >9.9) || (Tmax <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
   }
   if(mode==2 && degree==1)
   {
   off_low_batt
   Temp = Tmax *9/5 +32; // convert Celsius to Fahrenheit
   
   if(Temp <0)
   { off_plus
   minus
   } else plus
   sprintf(buffer,"%05d",abs(Temp*1E2));
 all_dot_off
   dot2
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   if((Temp >99.9) || (Temp < -99.9)) FormatChar_4(buffer[0]);
 all_3_off
   if((Temp >9.9) || (Temp <-9.9)) FormatChar_3(buffer[1]);
 all_2_off
   FormatChar_2(buffer[2]);
 all_1_off
   FormatChar_1(buffer[3]);
   
   }
   
   
   }
#define conversion_batt 69.4/194
           unsigned int Vbatt;
int timer6=0;
void read_battery()
           {
   if(++timer6>10)
   {
   timer6=0;
   y5=y4;
   y4=y3;
   y3=y2;
   y2=y1;
   y1= ADC_Read(3);
   Vbatt = (y1+y2+y3+y4+y5)/5;
   }
   }
void fill_temp()
           {
   if(++fill_counter>3)
   {
   fill_counter=3;
   fill_data=1;
   }
   else
   {
   Tmin=Tmax=Tcurrent=TemX;
   }
}
void check_hi_lo()
           {
   if(fill_data)
   {
   if(TemX < Tmin) Tmin =TemX;
   if(TemX> Tmax) Tmax=TemX;
   }
   }
void print_batt()
           {
   if(mode==4)
   {
   //current_reading=TemX;
   all_dot_off
   dot3
   sprintf(buffer,"%05d",abs(BATT_volt*100));
   off_plus
 all_5_off
   //FormatChar_5(buffer[0]);
 all_4_off
   FormatChar_4(buffer[1]);
 all_3_off
   FormatChar_3(buffer[2]);
 all_2_off
   FormatChar_2(buffer[3]);
 all_1_off
   FormatChar_1(buffer[4]);
   }
         
}
void show_low_batt()
           {
   if(mode==0 || mode==4)
   {
   if(BATT_volt < 5.0) low_batt
   if(BATT_volt > 6.0) off_low_batt
   }
   }
int timer5=0;
           // one tick = 0.5s
           // 120 tick = 60s
           // save data every one minute
           void save_data()
           {
   if(++timer5>set_interval*2) //
   {
   timer5=0;
   if(memory_counter>max_record) memory_counter=max_record;
   {
   //memory[memory_counter++]=TemX;
   memory[memory_counter++]=Vraw; // save data as the RAW voltages, to enable varities of sensors
   }
   
   }
   }
void print_record_number()
           {
   if(mode==5)
   {
   all_dot_off
   //dot3
   sprintf(buffer,"%05d",memory_counter);
   off_plus
 all_5_off
   // FormatChar_5(buffer[0]);
 all_4_off
   // FormatChar_4(buffer[1]);
 all_3_off
   FormatChar_3(buffer[2]);
 all_2_off
   FormatChar_2(buffer[3]);
 all_1_off
   FormatChar_1(buffer[4]);
   
   
   }
         
}
void set_recoring_interval()
           {
   if(mode==6)
   {
   all_dot_off
   //dot3
   sprintf(buffer,"%05d",set_interval);
   off_plus
 all_5_off
   //FormatChar_5(buffer[0]);
 all_4_off
   //FormatChar_4(buffer[1]);
 all_3_off
   if(set_interval>99)FormatChar_3(buffer[2]);
 all_2_off
   if(set_interval>9) FormatChar_2(buffer[3]);
 all_1_off
   FormatChar_1(buffer[4]);
         
 }
         
}
short command;
void get_command()
           {
   if(UART1_Data_Ready())command= UART1_Read();
   else command=0;
   }
void send_prompt()
           {
   UART1_Write_Text("\r\n>");
   }
void enter_command()
           {
   if(command==0x0d)
   {UART1_Write_Text("\r\nPlatinum Resistance Thermometer V1.0");
   send_prompt();
   }
   }
         
void print_menu()
           {
   if(command=='?')
   {
   UART1_Write_Text(menu);
   send_prompt();
 }
 
}
void print_temp()
           {
   if(command==' ')
   {
   sprintf(buffer,"%f,%0.3f,%0.3f,%0.3f,%0.2f,%d",Vraw,TemX,Tmin,Tmax,BATT_volt,memory_counter);
   UART1_Write_Text(buffer);
   send_prompt();
   
   
   }
 
}
int i;
float g;
void upload_data()
           {
   if(command=='t')
   {
   for(i=0; i<memory_counter; i++)
   {
   g=memory[i];
   g*= calibrate; // calibrate for 1mA current source
   OHM1=g*1E3; // convert to Ohms
   if(OHM1>18.0 && OHM1<180.0) Newton_Raphson();
   sprintf(buffer,"\r\n%d,%f,%0.3f",i,memory[i],TemX);
   UART1_Write_Text(buffer);
   }
   
   }
   }
void upload_raw_voltage()
           {
   if(command=='v')
   {
   for(i=0; i<memory_counter; i++)
   {
   sprintf(buffer,"\r\n%d,%f",i,memory[i]);
   UART1_Write_Text(buffer);
   }
 }
           }
         
 
 
// main function
           void main( void ) {
 Delay_mS(100);
   OSCCON |= 0x83; // enter idle mode when sleep instruction has been executed
 INTCON = 0x0; // disable interupt
   //ADCON1 = 0x0f; // all pins as IO
   //ADCON2 = 0xAF;
   
   // CMCON = 0x07; // comparators off
   
   TRISB = 0xd7;
   INTCON2 &= ~0x80; // enable pullup at PORTB
   TRISC = 0xa0; // use TX1,RX1
   
   TRISA = 0xFF;
   
   
   UART1_Init(9600); // Initialize UART1 module at 9600 bps
   Delay_ms(100); // Wait for UART 1module to stabilize
   
   UART1_Write_Text("\r\nPlatinum Resistance Thermometer V1.0");
         
 InitLCD();
   LCD_light_all();
   Delay_mS(1000);
   digit_clear();
   Delay_mS(1000);
   
   ADC_Init();
   ADCON1 = 0x0f;
 
   T1CON = 0xB1; // overflow every 500ms, 2Hz
   PIR1.TMR1IF = 1; // clear TMR1IF
   PIE1.TMR1IE = 1; // enable timer1 overflow interrupt
   INTCON = 0xC0; // global enable and timer1
   off_low_batt
         
 while(1)
   {
   wait_tick();
 //minus
   //plus
   // dot3
   
   // dot2
   // dot3
   // dot4
   // dot5
         
 // sprinti(buffer,"%05d",count++);
   // if(count>20000) count=0;
   
   // UART1_Write_Text("\r\n");
   // UART1_Write_Text(buffer);
   /*
   all_5_off
   FormatChar_5(buffer[0]);
   
   all_4_off
   FormatChar_4(buffer[1]);
 all_3_off
   FormatChar_3(buffer[2]);
   
   all_2_off
   FormatChar_2(buffer[3]);
   
   all_1_off
   FormatChar_1(buffer[4]);
   */
   
   ADC1=filter_ADC();
   k=ADC1*gain; //7.331371E-8;
   
   Vraw=k; // raw voltage in Volt
   
   k*= calibrate; // calibrate for 1mA current source
   
   read_battery();
   BATT_volt = ((Vbatt*8.875759E-3) - 4.838133E-2)+0.3;
   
   // sprintf(buffer,"%\r\n%0.3f %.2f",k*1E3,BATT_volt);
   // UART1_Write_Text(buffer);
   
   OHM1=k*1E3; // convert to Ohms
   
   //OHM1 = 99.6; // for testing
   
   if(OHM1>18.0 && OHM1<180.0) Newton_Raphson(); // interpolate only readings are in range -200 to 200C
 if(cold_boot)
   {
   write_temp_LCD();
   write_resistance_LCD();
   min_value();
   max_value();
   fill_temp();
   check_hi_lo();
   
   save_data();
 
   read_key1();
   release_key1();
   read_key3();
   release_key3();
   
   read_key2();
   //release_key2();
   
   print_batt();
   show_low_batt();
   print_record_number();
   set_recoring_interval();
   
   get_command();
   enter_command();
   print_menu();
   print_temp();
   upload_data();
   upload_raw_voltage();
 }
 }
           }
Figure 7: Listings of the source program.

The LCD.C is hardware driver for varitronix display, initialization for PIC LCD port and format for number display.

#include "lcd.h"
 
// LCD ----------------------------------------------
           // Init LCD
           void InitLCD(void) {
           
           // LCDCON -> 1/4 COM3-COM1, LCD Driver Enable, Enable Sleep Mode 
   //LCDCON = 0x83;
   LCDCON = 0x80; // static control with COM0, system clock
   // LCDPS -> Prescaler 1/1, Active mode, Write to LCD data
   //LCDPS = 0x20;
   //LCDREG = 0x3b;
           
 // LCD Segment select function
   // all bits for LCD driving are '1', '0' are for digital I/O
   LCDSE0 = 0xFF;
   LCDSE1 = ~0x0F; // use RB1, RB2, RB3 and RB4 as digital I/O
   LCDSE2 = 0xFF;
   LCDSE3 = ~0x78; // use RB0 & RB5 , RC6 & RC7 as digital I/O
   LCDSE4 = 0xFF;
   LCDSE5 = 0xFF;
}
// turn on All segment
           void LCD_light_all(void) {
 LCDDATA0 = 0xFF; LCDDATA1 = 0xFF; LCDDATA2 = 0xFF; LCDDATA3 = 0xFF;
   LCDDATA4 = 0xFF; LCDDATA5 = 0xFF; LCDDATA6 = 0xFF; LCDDATA7 = 0xFF;
   LCDDATA8 = 0xFF; LCDDATA9 = 0xFF; LCDDATA10 = 0xFF; LCDDATA11 = 0xFF;
   LCDDATA12 = 0xFF; LCDDATA13 = 0xFF; LCDDATA14 = 0xFF; LCDDATA15 = 0xFF;
   LCDDATA16 = 0xFF; LCDDATA17 = 0xFF; LCDDATA18 = 0xFF; LCDDATA19 = 0xFF;
   LCDDATA20 = 0xFF; LCDDATA21 = 0xFF; LCDDATA22 = 0xFF; LCDDATA23 = 0xFF;
   }
// turn off All segment
           void LCD_clear_all(void) {
 LCDDATA0 = 0x0; LCDDATA1 = 0x0; LCDDATA2 = 0x0; LCDDATA3 = 0x0;
   LCDDATA4 = 0x0; LCDDATA5 = 0x0; LCDDATA6 = 0x0; LCDDATA7 = 0x0;
   LCDDATA8 = 0x0; LCDDATA9 = 0x0; LCDDATA10 = 0x0; LCDDATA11 = 0x0;
   LCDDATA12 = 0x0; LCDDATA13 = 0x0; LCDDATA14 = 0x0; LCDDATA15 = 0x0;
   LCDDATA16 = 0x0; LCDDATA17 = 0x0; LCDDATA18 = 0x0; LCDDATA19 = 0x0;
   LCDDATA20 = 0x0; LCDDATA21 = 0x0; LCDDATA22 = 0x0; LCDDATA23 = 0x0;
   }
           
void FormatChar_7(unsigned char ch)
           {
 switch(ch)
   {
   case '0': A7; B7; C7; D7; F7; E7; break;
   case '1': B7; C7; break;
   case '2': A7; B7; M7; D7; G7; E7; break;
   case '3': A7; B7; C7; M7; D7; G7; break;
   case '4': B7; C7; M7; G7; F7; break;
   case '5': A7; M7; C7; D7; G7; F7; break;
   case '6': A7; M7; C7; D7; G7; F7; E7; break;
   case '7': A7; B7; C7; break;
   case '8': A7; B7; C7; M7; D7; G7; F7; E7; break;
   case '9': A7; B7; C7; M7; D7; G7; F7; break;
   case 'A': A7; B7; C7; M7; E7; F7; G7; break;
   case 'B': A7; K7; M7; C7; D7; F7; G7; E7; break;
   case 'C': A7; D7; F7; E7; break;
   case 'D': D7; N7; F7; E7; H7; break;
   case 'E': A7; D7; F7; G7; E7; break;
   case 'F': A7; F7; G7; E7; break;
   case 'G': A7; M7; C7; D7; F7; E7; break;
   case 'H': B7; M7; C7; F7; G7; E7; break;
   case 'I': A7; J7; D7; P7; break;
   case 'J': B7; C7; D7; E7; break;
   case 'K': K7; N7; F7; G7; E7; break;
   case 'L': D7; F7; E7; break;
   case 'M': K7; B7; C7; F7; E7; H7; break;
   case 'N': N7; B7; C7; F7; E7; H7; break;
   case 'O': A7; B7; C7; D7; F7; E7; break;
   case 'P': A7; B7; M7; F7; G7; E7; break;
   case 'Q': A7; B7; C7; D7; N7; F7; E7; break;
   case 'R': A7; B7; M7; N7; F7; G7; E7; break;
   case 'S': A7; M7; C7; D7; F7 G7; break;
   case 'T': A7; J7; P7; break;
   case 'U': B7; C7; D7; F7; E7; break;
   case 'V': B7; C7; N7; H7; break;
   case 'W': B7; C7; D7; Q7; F7; E7; break;
   case 'X': K7; N7; H7; Q7; break;
   case 'Y': B7; M7; C7; D7; F7; G7; break;
   case 'Z': A7; K7; D7; Q7; break;
   case '-': G7; M7; break;
   }
   }
void FormatChar_6(unsigned char ch)
           {
 switch(ch)
   {
   case '0': A6; B6; C6; D6; F6; E6; break;
   case '1': B6; C6; break;
   case '2': A6; B6; M6; D6; G6; E6; break;
   case '3': A6; B6; C6; M6; D6; G6; break;
   case '4': B6; C6; M6; G6; F6; break;
   case '5': A6; M6; C6; D6; G6; F6; break;
   case '6': A6; M6; C6; D6; G6; F6; E6; break;
   case '7': A6; B6; C6; break;
   case '8': A6; B6; C6; M6; D6; G6; F6; E6; break;
   case '9': A6; B6; C6; M6; D6; G6; F6; break;
   case 'A': A6; B6; C6; M6; E6; F6; G6; break;
   case 'B': A6; K6; M6; C6; D6; F6; G6; E6; break;
   case 'C': A6; D6; F6; E6; break;
   case 'D': D6; N6; F6; E6; H6; break;
   case 'E': A6; D6; F6; G6; E6; break;
   case 'F': A6; F6; G6; E6; break;
   case 'G': A6; M6; C6; D6; F6; E6; break;
   case 'H': B6; M6; C6; F6; G6; E6; break;
   case 'I': A6; J6; D6; P6; break;
   case 'J': B6; C6; D6; E6; break;
   case 'K': K6; N6; F6; G6; E6; break;
   case 'L': D6; F6; E6; break;
   case 'M': K6; B6; C6; F6; E6; H6; break;
   case 'N': N6; B6; C6; F6; E6; H6; break;
   case 'O': A6; B6; C6; D6; F6; E6; break;
   case 'P': A6; B6; M6; F6; G6; E6; break;
   case 'Q': A6; B6; C6; D6; N6; F6; E6; break;
   case 'R': A6; B6; M6; N6; F6; G6; E6; break;
   case 'S': A6; M6; C6; D6; F6 G6; break;
   case 'T': A6; J6; P6; break;
   case 'U': B6; C6; D6; F6; E6; break;
   case 'V': B6; C6; N6; H6; break;
   case 'W': B6; C6; D6; Q6; F6; E6; break;
   case 'X': K6; N6; H6; Q6; break;
   case 'Y': B6; M6; C6; D6; F6; G6; break;
   case 'Z': A6; K6; D6; Q6; break;
   case '-': G6; M6; break;
   }
   }
void FormatChar_5(unsigned char ch)
           {
 switch(ch)
   {
   case '0': break; // A5; B5; C5; D5; F5; E5; break;
   case '1': B5; C5; break;
   case '2': A5; B5; M5; D5; G5; E5; break;
   case '3': A5; B5; C5; M5; D5; G5; break;
   case '4': B5; C5; M5; G5; F5; break;
   case '5': A5; M5; C5; D5; G5; F5; break;
   case '6': A5; M5; C5; D5; G5; F5; E5; break;
   case '7': A5; B5; C5; break;
   case '8': A5; B5; C5; M5; D5; G5; F5; E5; break;
   case '9': A5; B5; C5; M5; D5; G5; F5; break;
   case 'A': A5; B5; C5; M5; E5; F5; G5; break;
   case 'B': A5; K5; M5; C5; D5; F5; G5; E5; break;
   case 'C': A5; D5; F5; E5; break;
   case 'D': D5; N5; F5; E5; H5; break;
   case 'E': A5; D5; F5; G5; E5; break;
   case 'F': A5; F5; G5; E5; break;
   case 'G': A5; M5; C5; D5; F5; E5; break;
   case 'H': B5; M5; C5; F5; G5; E5; break;
   case 'I': A5; J5; D5; P5; break;
   case 'J': B5; C5; D5; E5; break;
   case 'K': K5; N5; F5; G5; E5; break;
   case 'L': D5; F5; E5; break;
   case 'M': K5; B5; C5; F5; E5; H5; break;
   case 'N': N5; B5; C5; F5; E5; H5; break;
   case 'O': A5; B5; C5; D5; F5; E5; break;
   case 'P': A5; B5; M5; F5; G5; E5; break;
   case 'Q': A5; B5; C5; D5; N5; F5; E5; break;
   case 'R': A5; B5; M5; N5; F5; G5; E5; break;
   case 'S': A5; M5; C5; D5; F5 G5; break;
   case 'T': A5; J5; P5; break;
   case 'U': B5; C5; D5; F5; E5; break;
   case 'V': B5; C5; N5; H5; break;
   case 'W': B5; C5; D5; Q5; F5; E5; break;
   case 'X': K5; N5; H5; Q5; break;
   case 'Y': B5; M5; C5; D5; F5; G5; break;
   case 'Z': A5; K5; D5; Q5; break;
   case '-': G5; M5; break;
   }
   }
void FormatChar_4(unsigned char ch)
           {
 switch(ch)
   {
   case '0': A4; B4; C4; D4; F4; E4; break;
   case '1': B4; C4; break;
   case '2': A4; B4; D4; G4; E4; break;
   case '3': A4; B4; C4; D4; G4; break;
   case '4': B4; C4; G4; F4; break;
   case '5': A4; C4; D4; G4; F4; break;
   case '6': A4; C4; D4; G4; F4; E4; break;
   case '7': A4; B4; C4; break;
   case '8': A4; B4; C4; D4; G4; F4; E4; break;
   case '9': A4; B4; C4; D4; G4; F4; break;
   
   case 'A': A4; B4; C4; M4; E4; F4; G4; break;
   case 'B': A4; K4; M4; C4; D4; F4; G4; E4; break;
   case 'C': A4; D4; F4; E4; break;
   case 'D': D4; N4; F4; E4; H4; break;
   case 'E': A4; D4; F4; G4; E4; break;
   case 'F': A4; F4; G4; E4; break;
   case 'G': A4; M4; C4; D4; F4; E4; break;
   case 'H': B4; M4; C4; F4; G4; E4; break;
   case 'I': A4; J4; D4; P4; break;
   case 'J': B4; C4; D4; E4; break;
   case 'K': K4; N4; F4; G4; E4; break;
   case 'L': D4; F4; E4; break;
   case 'M': K4; B4; C4; F4; E4; H4; break;
   case 'N': N4; B4; C4; F4; E4; H4; break;
   case 'O': A4; B4; C4; D4; F4; E4; break;
   case 'P': A4; B4; M4; F4; G4; E4; break;
   case 'Q': A4; B4; C4; D4; N4; F4; E4; break;
   case 'R': A4; B4; M4; N4; F4; G4; E4; break;
   case 'S': A4; M4; C4; D4; F4 G4; break;
   case 'T': A4; J4; P4; break;
   case 'U': B4; C4; D4; F4; E4; break;
   case 'V': B4; C4; N4; H4; break;
   case 'W': B4; C4; D4; Q4; F4; E4; break;
   case 'X': K4; N4; H4; Q4; break;
   case 'Y': B4; M4; C4; D4; F4; G4; break;
   case 'Z': A4; K4; D4; Q4; break;
   case '-': G4; M4; break;
   }
   }
void FormatChar_3(unsigned char ch)
           {
 switch(ch)
   {
   case '0': A3; B3; C3; D3; F3; E3; break;
   case '1': B3; C3; break;
   case '2': A3; B3; D3; G3; E3; break;
   case '3': A3; B3; C3; D3; G3; break;
   case '4': B3; C3; G3; F3; break;
   case '5': A3; C3; D3; G3; F3; break;
   case '6': A3; C3; D3; G3; F3; E3; break;
   case '7': A3; B3; C3; break;
   case '8': A3; B3; C3; D3; G3; F3; E3; break;
   case '9': A3; B3; C3; D3; G3; F3; break;
   
   case 'A': A3; B3; C3; M3; E3; F3; G3; break;
   case 'B': A3; K3; M3; C3; D3; F3; G3; E3; break;
   case 'C': A3; D3; F3; E3; break;
   case 'D': D3; N3; F3; E3; H3; break;
   case 'E': A3; D3; F3; G3; E3; break;
   case 'F': A3; F3; G3; E3; break;
   case 'G': A3; M3; C3; D3; F3; E3; break;
   case 'H': B3; M3; C3; F3; G3; E3; break;
   case 'I': A3; J3; D3; P3; break;
   case 'J': B3; C3; D3; E3; break;
   case 'K': K3; N3; F3; G3; E3; break;
   case 'L': D3; F3; E3; break;
   case 'M': K3; B3; C3; F3; E3; H3; break;
   case 'N': N3; B3; C3; F3; E3; H3; break;
   case 'O': A3; B3; C3; D3; F3; E3; break;
   case 'P': A3; B3; M3; F3; G3; E3; break;
   case 'Q': A3; B3; C3; D3; N3; F3; E3; break;
   case 'R': A3; B3; M3; N3; F3; G3; E3; break;
   case 'S': A3; M3; C3; D3; F3 G3; break;
   case 'T': A3; J3; P3; break;
   case 'U': B3; C3; D3; F3; E3; break;
   case 'V': B3; C3; N3; H3; break;
   case 'W': B3; C3; D3; Q3; F3; E3; break;
   case 'X': K3; N3; H3; Q3; break;
   case 'Y': B3; M3; C3; D3; F3; G3; break;
   case 'Z': A3; K3; D3; Q3; break;
   case '-': G3; M3; break;
   }
   }
   void FormatChar_2(unsigned char ch)
   {
 switch(ch)
   {
   case '0': A2; B2; C2; D2; F2; E2; break;
   case '1': B2; C2; break;
   case '2': A2; B2; D2; G2; E2; break;
   case '3': A2; B2; C2; D2; G2; break;
   case '4': B2; C2; G2; F2; break;
   case '5': A2; C2; D2; G2; F2; break;
   case '6': A2; C2; D2; G2; F2; E2; break;
   case '7': A2; B2; C2; break;
   case '8': A2; B2; C2; D2; G2; F2; E2; break;
   case '9': A2; B2; C2; D2; G2; F2; break;
   
   case 'A': A2; B2; C2; M2; E2; F2; G2; break;
   case 'B': A2; K2; M2; C2; D2; F2; G2; E2; break;
   case 'C': A2; D2; F2; E2; break;
   case 'D': D2; N2; F2; E2; H2; break;
   case 'E': A2; D2; F2; G2; E2; break;
   case 'F': A2; F2; G2; E2; break;
   case 'G': A2; M2; C2; D2; F2; E2; break;
   case 'H': B2; M2; C2; F2; G2; E2; break;
   case 'I': A2; J2; D2; P2; break;
   case 'J': B2; C2; D2; E2; break;
   case 'K': K2; N2; F2; G2; E2; break;
   case 'L': D2; F2; E2; break;
   case 'M': K2; B2; C2; F2; E2; H2; break;
   case 'N': N2; B2; C2; F2; E2; H2; break;
   case 'O': A2; B2; C2; D2; F2; E2; break;
   case 'P': A2; B2; M2; F2; G2; E2; break;
   case 'Q': A2; B2; C2; D2; N2; F2; E2; break;
   case 'R': A2; B2; M2; N2; F2; G2; E2; break;
   case 'S': A2; M2; C2; D2; F2 G2; break;
   case 'T': A2; J2; P2; break;
   case 'U': B2; C2; D2; F2; E2; break;
   case 'V': B2; C2; N2; H2; break;
   case 'W': B2; C2; D2; Q2; F2; E2; break;
   case 'X': K2; N2; H2; Q2; break;
   case 'Y': B2; M2; C2; D2; F2; G2; break;
   case 'Z': A2; K2; D2; Q2; break;
   case '-': G2; M2; break;
   }
   }
void FormatChar_1(unsigned char ch)
           {
 switch(ch)
   {
   case '0': A1; B1; C1; D1; F1; E1; break;
   case '1': B1; C1; break;
   case '2': A1; B1; D1; G1; E1; break;
   case '3': A1; B1; C1; D1; G1; break;
   case '4': B1; C1; G1; F1; break;
   case '5': A1; C1; D1; G1; F1; break;
   case '6': A1; C1; D1; G1; F1; E1; break;
   case '7': A1; B1; C1; break;
   case '8': A1; B1; C1; D1; G1; F1; E1; break;
   case '9': A1; B1; C1; D1; G1; F1; break;
   
   
   case 'A': A1; B1; C1; M1; E1; F1; G1; break;
   case 'B': A1; K1; M1; C1; D1; F1; G1; E1; break;
   case 'C': A1; D1; F1; E1; break;
   case 'D': D1; N1; F1; E1; H1; break;
   case 'E': A1; D1; F1; G1; E1; break;
   case 'F': A1; F1; G1; E1; break;
   case 'G': A1; M1; C1; D1; F1; E1; break;
   case 'H': B1; M1; C1; F1; G1; E1; break;
   case 'I': E1; F1; break;
   case 'J': B1; C1; D1; E1; break;
   case 'K': K1; N1; F1; G1; E1; break;
   case 'L': D1; F1; E1; break;
   case 'M': K1; B1; C1; F1; E1; H1; break;
   case 'N': N1; B1; C1; F1; E1; H1; break;
   case 'O': C1; D1; G1; E1; break;
   case 'P': A1; B1; M1; F1; G1; E1; break;
   case 'Q': A1; B1; C1; D1; N1; F1; E1; break;
   case 'R': A1; B1; M1; N1; F1; G1; E1; break;
   case 'S': A1; M1; C1; D1; F1 G1; break;
   case 'T': A1; J1; P1; break;
   case 'U': B1; C1; D1; F1; E1; break;
   case 'V': B1; C1; N1; H1; break;
   case 'W': B1; C1; D1; Q1; F1; E1; break;
   case 'X': K1; N1; H1; Q1; break;
   case 'Y': B1; M1; C1; D1; F1; G1; break;
   case 'Z': A1; K1; D1; Q1; break;
   case '-': G1; M1; break;
   }
   }
void FormatClk_1(unsigned char n) {
           
   switch(n)
   {
   case 0: a1; b1; c1; d1; e1; f1; break;
   case 1: b1; c1; break;
   case 2: a1; b1; g1; e1; d1; break;
   case 3: a1; b1; c1; d1; g1; break;
   case 4: b1; c1; f1; g1; break;
   case 5: a1; c1; d1; f1; g1; break;
   case 6: a1; c1; d1; f1; g1; e1; break;
   case 7: a1; b1; c1; break;
   case 8: a1; b1; c1; d1; e1; f1; g1; break;
   case 9: a1; b1; c1; d1; f1; g1; break;
   }
   }
void FormatClk_2(unsigned char n) {
           
   switch(n)
   {
   case 0: a2; b2; c2; d2; e2; f2; break;
   case 1: b2; c2; break;
   case 2: a2; b2; g2; e2; d2; break;
   case 3: a2; b2; c2; d2; g2; break;
   case 4: b2; c2; f2; g2; break;
   case 5: a2; c2; d2; f2; g2; break;
   case 6: a2; c2; d2; f2; g2; e2; break;
   case 7: a2; b2; c2; break;
   case 8: a2; b2; c2; d2; e2; f2; g2; break;
   case 9: a2; b2; c2; d2; f2; g2; break;
   }
   }
void FormatClk_3(unsigned char n) {
           
   switch(n)
   {
   case 0: a3; b3; c3; d3; e3; f3; break;
   case 1: b3; c3; break;
   case 2: a3; b3; g3; e3; d3; break;
   case 3: a3; b3; c3; d3; g3; break;
   case 4: b3; c3; f3; g3; break;
   case 5: a3; c3; d3; f3; g3; break;
   case 6: a3; c3; d3; f3; g3; e3; break;
   case 7: a3; b3; c3; break;
   case 8: a3; b3; c3; d3; e3; f3; g3; break;
   case 9: a3; b3; c3; d3; f3; g3; break;
   }
   }
void FormatClk_4(unsigned char n) {
           
   switch(n)
   {
   case 0: a4; b4; c4; d4; e4; f4; break;
   case 1: b4; c4; break;
   case 2: a4; b4; g4; e4; d4; break;
   case 3: a4; b4; c4; d4; g4; break;
   case 4: b4; c4; f4; g4; break;
   case 5: a4; c4; d4; f4; g4; break;
   case 6: a4; c4; d4; f4; g4; e4; break;
   case 7: a4; b4; c4; break;
   case 8: a4; b4; c4; d4; e4; f4; g4; break;
   case 9: a4; b4; c4; d4; f4; g4; break;
   }
   }
           
void LCDWriteClck(unsigned int number)
           {
   int edi, des, sto, hil;
   
   edi = (number%10);
   des = (number%100 - edi)/10;
   sto = (number%1000 - des)/100;
   hil = (number%10000 - sto)/1000;
   
   FormatClk_1(edi); 
   FormatClk_2(des);
   FormatClk_3(sto);
   FormatClk_4(hil);
   }
// Print current clock
           void LCDPrintClck(char hour, char min)
           {
   all_clk_off; 
 FormatClk_1((unsigned char)(min%10)); 
   FormatClk_2((unsigned char)(min/10));
   FormatClk_3((unsigned char)(hour%10));
   FormatClk_4((unsigned char)(hour/10));
   }
void LCDWriteTxt(unsigned char* txt)
           {
           /*
   FormatChar_1(*txt++); 
   FormatChar_2(*txt++); 
   FormatChar_3(*txt++);
   FormatChar_4(*txt++);
   FormatChar_5(*txt++);
   FormatChar_6(*txt++);
   FormatChar_7(*txt++);
   */
   }
Figure 7: Listings of hardware driver for LCD.

The LCD.H is the header file that defines segment with the LCD bit map locations.

// Glass LCD Varitronic 40-pin 4-1/2 digit minus/plus lowbatt
/**** LCD PARTS ****/
           // 7 CHAR
           #define A7 LCDDATA20 |= 0x20; 
           #define B7 LCDDATA14 |= 0x20; 
           #define C7 LCDDATA8 |= 0x20; 
           #define D7 LCDDATA2 |= 0x20; 
           #define E7 LCDDATA8 |= 0x80; 
           #define F7 LCDDATA14 |= 0x80; 
           #define G7 LCDDATA14 |= 0x40; 
           #define M7 LCDDATA8 |= 0x10; 
           #define H7 LCDDATA20 |= 0x40; 
           #define J7 LCDDATA20 |= 0x10; 
           #define K7 LCDDATA14 |= 0x10; 
           #define N7 LCDDATA2 |= 0x10; 
           #define P7 LCDDATA2 |= 0x40; 
           #define Q7 LCDDATA8 |= 0x40; 
#define all_7_off LCDDATA8 &= ~0xF0; LCDDATA2 &= ~0xF0; LCDDATA14 &= ~0xF0; LCDDATA20 &= ~0xF0;
           
// 6 CHAR
           #define A6 LCDDATA21 |= 0x02; 
           #define B6 LCDDATA15 |= 0x02; 
           #define C6 LCDDATA9 |= 0x02; 
           #define D6 LCDDATA3 |= 0x02; 
           #define E6 LCDDATA9 |= 0x08; 
           #define F6 LCDDATA15 |= 0x08; 
           #define G6 LCDDATA15 |= 0x04; 
           #define M6 LCDDATA9 |= 0x01; 
           #define H6 LCDDATA21 |= 0x04; 
           #define J6 LCDDATA21 |= 0x01; 
           #define K6 LCDDATA15 |= 0x01; 
           #define N6 LCDDATA3 |= 0x01; 
           #define P6 LCDDATA3 |= 0x04; 
           #define Q6 LCDDATA9 |= 0x04; 
#define all_6_off LCDDATA3 &= ~0x0F; LCDDATA9 &= ~0x0F; LCDDATA15 &= ~0x0F; LCDDATA21 &= ~0x0F;
// 5 CHAR
           #define A5 LCDDATA21 |= 0x02;
           #define B5 LCDDATA0 |= 0x02;
           #define C5 LCDDATA0 |= 0x20;
           #define D5 LCDDATA3 |= 0x20; 
           #define E5 LCDDATA9 |= 0x80; 
           #define F5 LCDDATA15 |= 0x80; 
           #define G5 LCDDATA15 |= 0x40; 
           #define M5 LCDDATA9 |= 0x10; 
           #define H5 LCDDATA21 |= 0x40; 
           #define J5 LCDDATA21 |= 0x10; 
           #define K5 LCDDATA15 |= 0x10; 
           #define N5 LCDDATA3 |= 0x10; 
           #define P5 LCDDATA3 |= 0x40; 
           #define Q5 LCDDATA9 |= 0x40; 
#define all_5_off LCDDATA0 &= ~0x02;
           
// 4 CHAR
           #define A4 LCDDATA4 |= 0x08;
           #define B4 LCDDATA4 |= 0x04;
           #define C4 LCDDATA0 |= 0x20;
           #define D4 LCDDATA0 |= 0x10;
           #define E4 LCDDATA0 |= 0x08;
           #define F4 LCDDATA4 |= 0x10;
           #define G4 LCDDATA4 |= 0x20;
#define M4 LCDDATA10 |= 0x01; 
           #define H4 LCDDATA22 |= 0x04; 
           #define J4 LCDDATA22 |= 0x01; 
           #define K4 LCDDATA16 |= 0x01; 
           #define N4 LCDDATA4 |= 0x01; 
           #define P4 LCDDATA4 |= 0x04; 
           #define Q4 LCDDATA10 |= 0x04; 
#define all_4_off LCDDATA4 &= ~0x3c; LCDDATA0 &= ~0x38;
// 3 CHAR
           #define A3 LCDDATA1 |= 0x20;
           #define B3 LCDDATA1 |= 0x80;
           #define C3 LCDDATA2 |= 0x08;
           #define D3 LCDDATA2 |= 0x04;
           #define E3 LCDDATA0 |= 0x80;
           #define F3 LCDDATA3 |= 0x80;
           #define G3 LCDDATA4 |= 0x02;
#define M3 LCDDATA10 |= 0x10; 
           #define H3 LCDDATA22 |= 0x40; 
           #define J3 LCDDATA22 |= 0x10; 
           #define K3 LCDDATA16 |= 0x10; 
           #define N3 LCDDATA4 |= 0x10; 
           #define P3 LCDDATA4 |= 0x40; 
           #define Q3 LCDDATA10 |= 0x40; 
#define all_3_off LCDDATA1 &= ~0xa0; LCDDATA2 &= ~0x0c; LCDDATA0 &= ~0x80; LCDDATA3 &= ~0x80; LCDDATA4 &= ~0x02;
           
// 2 CHAR
           #define A2 LCDDATA5 |= 0x80;
           #define B2 LCDDATA5 |= 0x40;
           #define C2 LCDDATA2 |= 0x80;
           #define D2 LCDDATA2 |= 0x40;
           #define E2 LCDDATA2 |= 0x20;
           #define F2 LCDDATA3 |= 0x04;
           #define G2 LCDDATA1 |= 0x40;
#define M2 LCDDATA11 |= 0x01; 
           #define H2 LCDDATA23 |= 0x04; 
           #define J2 LCDDATA23 |= 0x01; 
           #define K2 LCDDATA17 |= 0x01; 
           #define N2 LCDDATA5 |= 0x01; 
           #define P2 LCDDATA5 |= 0x04; 
           #define Q2 LCDDATA11 |= 0x04; 
#define all_2_off LCDDATA5 &= ~0xc0; LCDDATA2 &= ~0xe0; LCDDATA3 &= ~0x04; LCDDATA1 &= ~0x40;
           
// 1 CHAR
           #define A1 LCDDATA5 |= 0x08;
           #define B1 LCDDATA5 |= 0x04;
           #define C1 LCDDATA5 |= 0x02;
           #define D1 LCDDATA5 |= 0x01;
           #define E1 LCDDATA3 |= 0x02;
           #define F1 LCDDATA5 |= 0x10;
           #define G1 LCDDATA5 |= 0x20;
           
           #define M1 LCDDATA11 |= 0x10; 
           #define H1 LCDDATA23 |= 0x40; 
           #define J1 LCDDATA23 |= 0x10; 
           #define K1 LCDDATA17 |= 0x10; 
           #define N1 LCDDATA5 |= 0x10; 
           #define P1 LCDDATA5 |= 0x40; 
           #define Q1 LCDDATA11 |= 0x40; 
#define all_1_off LCDDATA5 &= ~0x3f; LCDDATA3 &= ~0x02;
#define DOT1 LCDDATA2 |= 0x80; 
           #define DOT2 LCDDATA3 |= 0x08; 
           #define DOT3 LCDDATA3 |= 0x80;
           #define DOT4 LCDDATA4 |= 0x08; 
           #define DOT5 LCDDATA4 |= 0x80; 
           #define DOT6 LCDDATA5 |= 0x08; 
#define DDOT1 LCDDATA21 |= 0x10; 
           #define DDOT2 LCDDATA21 |= 0x80;
           #define DDOT3 LCDDATA22 |= 0x10; 
           #define DDOT4 LCDDATA22 |= 0x80;
           #define DDOT5 LCDDATA23 |= 0x08; 
//#define OLIMEX LCDDATA20 |= 0x80;
           //#define MINUS LCDDATA5 |= 0x80;
           //#define PLUS LCDDATA23 |= 0x80;
#define low_batt LCDDATA4 |= 0x40;
           #define minus LCDDATA0 |= 0x01;
           #define plus LCDDATA4 |= 0x80;LCDDATA0 |= 0x01;
#define off_low_batt LCDDATA4 &= ~0x40;
   #define off_plus LCDDATA4 &= ~0x80;LCDDATA0 &= ~0x01;
   #define off_minus LCDDATA0 &= ~0x01;
#define dot2 LCDDATA3 |= 0x01;
           #define dot3 LCDDATA2 |= 0x10;
           #define dot4 LCDDATA0 |= 0x40;
           #define dot5 LCDDATA0 |= 0x04;
#define all_dot_off LCDDATA3 &= ~1; LCDDATA2 &= ~0x10; LCDDATA0 &= ~0x44;
 
 
/**** CLK segments ****/
           //lcd small 1
           #define a1 LCDDATA0 |= 0x02;
           #define b1 LCDDATA0 |= 0x01; 
           #define c1 LCDDATA12 |= 0x01;
           #define d1 LCDDATA18 |= 0x01;
           #define e1 LCDDATA12 |= 0x02; 
           #define f1 LCDDATA6 |= 0x02; 
           #define g1 LCDDATA6 |= 0x01; 
//lcd small 2
           #define a2 LCDDATA0 |= 0x08; 
           #define b2 LCDDATA0 |= 0x04; 
           #define c2 LCDDATA12 |= 0x04;
           #define d2 LCDDATA18 |= 0x04; 
           #define e2 LCDDATA12 |= 0x08;
           #define f2 LCDDATA6 |= 0x08;
           #define g2 LCDDATA6 |= 0x04;
           
//lcd small 3
           #define a3 LCDDATA0 |= 0x10; 
           #define b3 LCDDATA6 |= 0x10; 
           #define c3 LCDDATA12 |= 0x10; 
           #define d3 LCDDATA18 |= 0x20; 
           #define e3 LCDDATA12 |= 0x20;
           #define f3 LCDDATA0 |= 0x20;
           #define g3 LCDDATA6 |= 0x20;
           
//lcd small 4
           #define a4 LCDDATA0 |= 0x40;
           #define b4 LCDDATA6 |= 0x40; 
           #define c4 LCDDATA12 |= 0x40;
           #define d4 LCDDATA18 |= 0x80;
           #define e4 LCDDATA12 |= 0x80;
           #define f4 LCDDATA0 |= 0x80;
           #define g4 LCDDATA6 |= 0x80;
//#define dot1 LCDDATA18 |= 0x02;
           //#define dot2 LCDDATA18 |= 0x10;
           //#define dot3 LCDDATA18 |= 0x40;
           //#define ddot LCDDATA18 |= 0x08;
           #define dot_off LCDDATA18 &= ~0x5A;
#define all_clk_off LCDDATA0 = 0; LCDDATA6 = 0; LCDDATA12 = 0; LCDDATA18 &= ~0xA5; 
           
/**** arrow segments ****/
           #define arr_l LCDDATA1 |= 0x01;
           #define arr_r LCDDATA13 |= 0x01;
           #define arr_d LCDDATA19 |= 0x01;
           #define arr_u LCDDATA7 |= 0x01;
           #define arr_off LCDDATA1 &= ~0x01; LCDDATA13 &= ~0x01; LCDDATA19 &= ~0x01; LCDDATA7 &= ~0x01;
#define lbat_start_end LCDDATA1 |= 0x02;
           #define lbat_1 LCDDATA19 |= 0x02;
           #define lbat_2 LCDDATA13 |= 0x02;
           #define lbat_3 LCDDATA7 |= 0x02;
#define progress_end LCDDATA2 |= 0x01;
           #define progress_1 LCDDATA14 |= 0x04;
           #define progress_2 LCDDATA8 |= 0x04;
           #define progress_3 LCDDATA2 |= 0x04;
           #define progress_4 LCDDATA2 |= 0x02;
           #define progress_5 LCDDATA8 |= 0x02;
           #define progress_6 LCDDATA14 |= 0x02;
           #define progress_7 LCDDATA20 |= 0x02;
           #define progress_8 LCDDATA20 |= 0x01;
           #define progress_9 LCDDATA14 |= 0x01;
           #define progress_10 LCDDATA8 |= 0x01;
           #define progress_start LCDDATA20 |= 0x04;
           #define progres_off LCDDATA2 &= ~0x07; LCDDATA8 &= ~0x07; LCDDATA14 &= ~0x07; LCDDATA20 &= ~0x07; 
           
#define F LCDDATA2 |= 0x08;
           #define H LCDDATA8 |= 0x08;
           #define m LCDDATA14 |= 0x08;
           #define u LCDDATA20 |= 0x08;
           
// LCD Functions //
           // Init LCD
           void InitLCD(void);
// turn on All segment
           void LCD_light_all(void);
// turn off All segment
           void LCD_clear_all(void);
// write char to Xth position
           void FormatChar_7(unsigned char ch);
           void FormatChar_6(unsigned char ch);
           void FormatChar_5(unsigned char ch);
           void FormatChar_4(unsigned char ch);
           void FormatChar_3(unsigned char ch);
           void FormatChar_2(unsigned char ch);
           void FormatChar_1(unsigned char ch);
// write char to Xth clock position
           void FormatClk_1(unsigned char n);
           void FormatClk_2(unsigned char n);
           void FormatClk_3(unsigned char n);
           void FormatClk_4(unsigned char n);
// Write number at clock position
           void LCDWriteClck(unsigned int number);
// Write 7charakter text
           void LCDWriteTxt(unsigned char* txt);
// Print current clock
           void LCDPrintClck(char hour, char min);
Figure 8: Header file, LCD.H listing.

The sensor is Platinum Pt100 having 3-wire output. We can use DIN connector for connecting the sensor easily.

The meter can be connected to PC via UAB port. The FT232 driver is available from FTDI.

The record can be uploaded to PC using Tera terminal. The USB port will be assigned to a given COM port. Shown COM5.

Press ENTER, the prompt will be popup. SP key will print the current readings begin with

Raw voltage, temperature in Celsius, minimum temp, max temp, battery voltage and memory counter.

To upload recorded temperature, press t.

Download Schematic, Source code, Varitronix glass LCD datasheet, ITS-90 guideline


<
29 December 2015