PIC16F1619 connecting LM35 temperature-sensor to LCD

Thread Starter

Cliff Karlsson

Joined May 16, 2017
4
I am really new to PIC microcontrollers and have purchased a Microship curiosity board http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=DM164137 which uses a PIC16F1619 microcontroller. I managed to get the value of a potentiometer displayed in a LCD using the code below. But I want to connect a LM35 temperature-sensor http://www.ti.com/lit/ds/symlink/lm35.pdf to the board and show the temperature instead of the potentiometer.

I have changed this part:

TRISCbits.TRISC3 = 1; //Sensor is connected to RC3...set as input
ANSELCbits.ANSC3 = 1; //analog
ADCON0 = 0b00011101; //select RC3 as source of ADC and enable the module (AN7)

But I guess that I need to alter the sketch some more. Can anyone help me with the code for adding the sensor and showing it in the lcd?

Code:
#include <stdio.h>
#include <stdlib.h>
#include <htc.h>
#define _XTAL_FREQ 500000

#define E_bit PORTAbits.RA0
#define RS_bit PORTAbits.RA2
#define CLEAR 0x01
#define ADDRESS 0x80

void init (void);
void init_display(void);
void print_char(char data);
void print_instr(char instr);
void print_text(const char *data);
void EE(void);
void E(void);


void main(void)
    {
    unsigned char digits[5];
    unsigned int adcval;
 
    init();
    print_instr(CLEAR);
 
    TRISCbits.TRISC0 = 1;         //Potentiometer is connected to RC0...set as input
    ANSELCbits.ANSC0 = 1;         //analog
    ADCON0 = 0b00010001;          //select RC0 as source of ADC and enable the module (AN4)
    ADCON1 = 0b00010000;          //left justified - FOSC/8 speed - Vref is Vdd

 
    for(;;)
        {
    adcval = adc();             //grab the top 8 MSbs
        __delay_ms(5);             //delay for AT LEAST 5ms
        digits[0] = adcval / 1000 + 48;
        digits[1] = (adcval / 100) % 10 + 48;
        digits[2] = (adcval / 10) % 10 + 48;
        digits[3] = adcval % 10 + 48;
        digits[4] = '\0';

        print_text(digits);

     
        }
    }
 
    int adc(void) {
    __delay_us(5);                //wait for ADC charging cap to settle
    GO = 1;
    while (GO) continue;          //wait for conversion to be finished

    return (ADRESH << 8) | ADRESL;              
}


void init (void)
    {
    LATA=0;
    LATB=0;
    PORTA=0;
    PORTB=0;
    ANSELA=0;
    ANSELB=0;
    TRISA=0;
    TRISB=0;
    init_display();
    }


void init_display(void)
    {
        // See the datasheet flow chart for the procedure below
        // This part initiates the LCD in 4-bit mode...
                __delay_ms(25);
        PORTB=0x30;
        EE();
        PORTB=0x30;
        EE();
        PORTB=0x30;
        EE();
        PORTB=0x20;
        EE();
 
        // Set LCD properties...
        print_instr(0x28);    // 2: Dual line (even though it is single line)
        print_instr(0x0C);    // 3: Display on, cursor, blink
        print_instr(CLEAR);    // 4: Clear
        print_instr(0x06);    // 5: Entry mode set

// LCD is now initialized...
    }

/*******************************************/
// Print chars to LCD with 4-bit method
/*******************************************/
void print_char(char data)
    {
        //PORTC = (data >> 4) & 0x0F;
                PORTB = data & 0xF0;
        RS_bit=1; // RS
        E();

        //PORTC = data & 0x0F;
                PORTB = (data << 4) & 0xF0;
        RS_bit=1; // RS
        E();
                PORTB=0;
                PORTA=0;
    }

/*******************************************/
// Print instruction to LCD with 4-bit method
/*******************************************/
void print_instr(char instr)
    {
        //PORTC = (instr >> 4) & 0x0F;
                PORTB = instr & 0xF0;
        E();

        //PORTC = instr & 0x0F;
                PORTB = (instr << 4) & 0xF0;
        E();
                PORTB=0;
                PORTA=0;
    }

/*******************************************/
// Toggle E to execute command/instruction
// With a litle bit longer delay than std.
/*******************************************/
void EE(void)
    {
        __delay_ms(5);
        E_bit=0;
        __delay_ms(5);
        E_bit=1;
        __delay_ms(5);
        E_bit=0;
        __delay_ms(5);
    }

/*******************************************/
// Toggle E to execute command/instruction
/*******************************************/
void E(void)
    {
        __delay_us(25);
        E_bit=0;
        __delay_us(25);
        E_bit=1;
        __delay_us(25);
        E_bit=0;
        __delay_us(25);
    }

void print_text(const char *data)
    {
    char i=0;
    while(data[i])
        {
        print_char(data[i++]);
        }
    print_instr(ADDRESS+0x60);
    i=0;
    while(data[i]&&(i<8))
        {
        print_char(data[i++]);
        }
    if (i==8)
        {
        print_instr(ADDRESS+0x40);
        while(data[i])
            {
            print_char(data[i++]);
            }
        }

    }
 

paulfjujo

Joined Mar 6, 2014
23
  • Hello,
  • to separate pending problems
  • did you allready test the display function like this ?
you want to use a LM35 0mV at 0°C then 10mV/°C
so you will get only 200mV at 20°C

with LM335 you will get 2730mV at 0°C ( because calibrated in °Kelvin)
and 2930mV at 20°C

Wich one sensor ?
Can this PIC use a internal +Vref for ADC ?

  • Code:
    [*]
    for( adcval=0; adcval<1023; adcval++)
            {
       // adcval = adc();             //grab the top 8 MSbs
            __delay_ms(5);             //delay for AT LEAST 5ms
            digits[0] = adcval / 1000 + 48;
            digits[1] = (adcval / 100) % 10 + 48;
            digits[2] = (adcval / 10) % 10 + 48;
            digits[3] = adcval % 10 + 48;
            digits[4] = '\0';
    
            print_text(digits);
    
         
            }
    
    
    [*]
 
Top