Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

how to display -ve temp reading on LCD??

Status
Not open for further replies.

hhhsssmmm

New Member
Hello

Im using PIC18F4220, 20MHz ceramic, C18 compiler.

I have a running project where im taking temperature readings after every 300ms intervals and display on 16x2 LCD.

Im using thermistor MCP9701A. I have 8bit ADC enabled on my PIC and im only reading the high byte ADRESH.

My V+ref == Vdd and V-ref == Vss.

All seems to work fine and im getting good temp read outs going up to room temperature. This i compared with a
precision digital thermometer. The only problem is when the temperature drops below zero, i get only two fixed
numbers showing on LCD.... -55C and -35C.

Please can anyone explain why im getting some crazing -ve reading where in fact my -ve temperature reading
should not be dropping more than -2C....and this should show up on LCD as " -02C ".

Below is my code...plz see it and kindly let me know where the mistake might be.

Thanks
Haseeb

Code:
#include <p18f4220.h>    
#include <delays.h>
        
#pragma config OSC = HS
#pragma config WDT = OFF  
#pragma config LVP = OFF 
 
void SendLCD(unsigned char Byte, unsigned char type); //LCD display function
 
#define LCD LATD //LCD Latch PORT
#define LCD_RS LATEbits.LATE0 //Register Select (0: Instruction/ 1: Data)
#define LCD_E LATEbits.LATE2 //Enable (Starts data read/write)
#define LED LATCbits.LATC3  //power up LED

unsigned char minus = 0, //-ve flag...for -ve sign activation             

              bin = 0, //temp buffer variable for ADC value for BCD conversion process                     

             //BCD coversion variables
             d0 = 0,       
             d1 = 0,
              d2 = 0;   
      
void main(void)
{     

  //Configure ADC
  ADCON1 = 0b00001110 ; //VREF- = VSS,
                         //VREF+ = VDD,
                        //Enable AN0 only...rest all Digital
   
  ADCON0 = 0b00000000;  //Select channel 0 (AN0),
                         //ADC Idle,
                        //ADC Dissabled
              
  ADCON2 = 0b00001100;    //Left Justified for 8bit ADC scaling
                         //ADC Acquisition Time 2TAD,
                        //ADC Conversion Clock FOSC/4         

  PORTA = 0; //initiallize PORTA
  TRISAbits.TRISA0 = 1; // Analog Channel 0 (AN0 input) 
 
  PORTB = 0; //intialize PORTB 
  TRISBbits.TRISB3 = 1;    //swtich 1 input
  TRISBbits.TRISB4 = 1;    //switch 2 input
  TRISBbits.TRISB5 = 1;    //switch 3 input   

  PORTC = 0; //intialize PORTC
  TRISCbits.TRISC3 = 0;  //LED      
 
  PORTD = 0; //initiallize PORTD 
  TRISD = 0x00; //LCD output   

  PORTE = 0; //initiallize PORTE   
  TRISEbits.TRISE0 = 0;  //LCD Register Select (to LCD Pin 4)
  TRISEbits.TRISE2 = 0;  //LCD Enable (to LCD Pin 6)
 

    INTCON = 0; //dissable all interrupts


    Delay10KTCYx(10); //20ms wait for LCD power up


    //Initialize the LCD
    LCD = 0x00; //clear LCD PORTD pins
    Delay1KTCYx(25); //delay 5mS
    SendLCD(0x03,0); //Initialization command
    Delay1KTCYx(25); //delay 5mS
    SendLCD(0x03,0); //Initialization command
    Delay100TCYx(8); //delay 160uS
    SendLCD(0x03,0); //Initialization command
    Delay100TCYx(8); //delay 160uS
    SendLCD(0x3C,0); //Interface lenght is 8 bits long, 2-lines, 5x10 dots
    Delay100TCYx(8); //delay 160uS
    SendLCD(0x10,0); //Turn off LCD
    Delay100TCYx(8); //delay 160uS
    SendLCD(0x01,0); //Clear LCD   
    Delay1KTCYx(25); //delay 5mS
    SendLCD(0x06,0); //Increment the cursor after each byte written
    Delay100TCYx(8); //delay 160uS
    SendLCD(0x0C,0); //Turn on LCD, cursor off, cursor blinking off
    Delay100TCYx(8); //delay 160uS


    //Power up flashing LED
    LED = 1;   
    Delay10KTCYx(125); //250ms delay            
    LED = 0;
    Delay10KTCYx(125); //250ms delay
    LED = 1;
    Delay10KTCYx(125); //250ms delay
    LED = 0;


    ADCON0bits.ADON = 1; //Enable ADC


    while(1) //loop forever
    {         
   
        ADCON0bits.GO_DONE = 1; //Start ADC Conversion
                                           
        while (ADCON0bits.GO_DONE == 1);  //Wait until Conversion finishes
 
        bin = ADRESH;  // reading ADC High byte only for 8bit ADC scale

        if(bin < 20) //below 0 deg C ... (0 deg C @ 400mV)                   

            minus = 1;    //activate -ve sign   

        bin = bin - 20; //offset adjustment ... (0 deg C @ 400mV)               

        //convert ADC value to BCD
        d1 = bin % 10;                   
        d0 = (bin / 10) % 10;                  
       
        //convert BCD digit numbers to ASCII text characters for LCD           
        d0 += '0';
        d1 += '0';           

        SendLCD(0x80,0); //activate LCD line 1
           
        //if temperature is in -ve ... then print -ve sign on LCD
        if(minus == 1)
        {

            SendLCD('-',1);    

            minus = 0; //reset minus sign flag

        }   

        else //temperature is in +ve so erase minus sign (blank space print)
       
            SendLCD(' ',1);

        //print the temperature on LCD
        SendLCD(d0,1);    
        SendLCD(d1,1);    
        SendLCD('C',1);                            
       
        Delay10KTCYx(150); //300ms delay            

    }// end of main while loop




} //end of main()



void SendLCD(unsigned char Byte, unsigned char type)
{
   
    LCD_RS = type; //Set whether it is a Command (0) or Data/Char (1)   

    Delay100TCYx(8); //delay 160uS

    LCD = Byte; //assign the new data to the LCD PORTD
   
    Delay100TCYx(8); //delay 160uS

    LCD_E = 1; //Set Enable High   
   
    Delay100TCYx(8); //delay 160uS
   
    LCD_E = 0; //Set Enable Low

}
 
Well the problem I would think is here:
Code:
        if(bin < 20) //below 0 deg C ... (0 deg C @ 400mV)                   

            minus = 1;    //activate -ve sign   

        bin = bin - 20; //offset adjustment ... (0 deg C @ 400mV)

if the temperature is < 0C, bin <20, but bin is an unsigned char so bin - 20 is 255 for -1C, which would explain why you get -55 displayed.

I would suggest declaring bin as a signed char, and replacing the above code with:
Code:
bin = bin - 20; //offset adjustment ... (0 deg C @ 400mV)
if(bin < 0) //below 0 deg C
{
    minus = 1;    //activate -ve sign   
    bin = -bin;    // make bin printable
}

Or even more simply, just replace those above lines with (keep the unsigned char decl):
Code:
if(bin < 20) //below 0 deg C @ 400mV offset
{
    minus = 1;    //activate -ve sign   
    bin = 20-bin;    // make bin printable
}
else
    bin = bin - 20;
 
You're of course most welcome. Glad to be of assistance.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top