Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Temperature monitoring with LM35 sensor

Status
Not open for further replies.

electronicnoob

Junior Member level 1
Joined
Jul 4, 2019
Messages
19
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
142
Hi, I am currently working on a temperature monitoring system using a PIC16f887, this is the code I've written but It takes too much space on my program space. The code is already taking 91.2% of my 2000H words.

Code:
#pragma config CONFIG1 = 0x2CD2
#pragma config CONFIG2 = 0x0700
#include <stdio.h>
#include <stdlib.h>

//LCD module connections
#define LCD_RS       RD0
#define LCD_EN       RD1
#define LCD_D4       RD2
#define LCD_D5       RD3
#define LCD_D6       RD4
#define LCD_D7       RD5
#define LCD_RS_DIR   TRISD0
#define LCD_EN_DIR   TRISD1
#define LCD_D4_DIR   TRISD2
#define LCD_D5_DIR   TRISD3
#define LCD_D6_DIR   TRISD4
#define LCD_D7_DIR   TRISD5
//End LCD module connections

#include <xc.h>
#define _XTAL_FREQ 20000000
#include <stdint.h>        // include stdint header
#include "LCD_Lib.c"       // include LCD driver source file

uint16_t AN0RES=0;
float Temperature, Voltage;
char* TempSTR[16];
char* ADCN[16];

void InitADC(void);
uint16_t ADC_Read(uint8_t ANC);

void InitADC(void)
{
    ADCON0 = 0x91;
    ADCON1 = 0x80;
    PORTA  = 0x00;
    TRISA  = 0x20;
    ANSEL  = 0x10;
}

uint16_t ADC_Read(uint8_t ANC)
{
    /*if(ANC<0 || ANC>7) // Check Channel Number Validity
    { return 0;}*/
    ADCON0 = 0x91;
    __delay_us(30); 
    GO_DONE = 1;               // Start A/D Conversion
    while(ADCON0bits.GO_DONE); // Polling GO_DONE Bit
    return ((ADRESH<<8)+ADRESL);
}

void main(void)
{
    LCD_Begin();
    InitADC();
  
    LCD_Cmd(LCD_CLEAR);
    LCD_Goto(1, 1);
    LCD_Print("Temperature");
  

    while(1)
    { 
        AN0RES = ADC_Read(4);               // Read Analog Channel 4
        Voltage = AN0RES * 0.0048828;
        Temperature = Voltage / 0.01;   // Calculate The Temperature     
        sprintf(TempSTR, " %.2f", Temperature); // Convert The Temperature From Float To String
      
        LCD_Goto(1, 2);
        LCD_Print(TempSTR);
        __delay_ms(500);
    }
}

I checked that this part of the code here
Code:
while(1)
    { 
        /*AN0RES = ADC_Read(4);               // Read Analog Channel 4
        Voltage = AN0RES * 0.0048828;
        Temperature = Voltage / 0.01;   // Calculate The Temperature     
        sprintf(TempSTR, " %.2f", Temperature); // Convert The Temperature From Float To String
      
        LCD_Goto(1, 2);
        LCD_Print(TempSTR);
        __delay_ms(500);*/
    }
takes 84.9%.
Is there any way to make the size of the code smaller? I need it to be around 30% or smaller as I still have to add more codes to it.

Thank you very much in advance!
--- Updated ---

I think the major problem is this line.
Code:
sprintf(TempSTR, " %.2f", Temperature);
It takes 63.5% of my FLASH, how do I make it more efficient.
 
Last edited:

Hi,

I assume most of your space is used by the included libraries.
Like sprintf. If not used it will not be included and thus it takes much less code space.
As soon as you use it once in your code it needs to be included.
But if you use sprintf multiple times it won't cause multiple code space, only once.

Thus my recommendation:
* either use a microcontroller with more code space, or
* try to avoid large standard libraries and/or
* adjust compiler setup to optimize on code space

Hints:
"divide by 0.01" should be replaced by "multiply with 100"
Even faster:
Temperature = AN0RES * 0.48828;

Instead of float use integer calculations. If you want temperature with 0.01 resolution you could use integers where 1 LSB represents 0.01.
Example 1234 represents 1234 x 0.01 = 12.34.
An integer division by 100 gives "12" and a remainder of "34"
Just combine "12" with a dot followed by "34" to get "12.34"

Klaus
 
hello,

more simple


Code:
 void Value_converter(unsigned int adc_value, char *T)
{
    long vout ;
    unsigned int value;
    vout= (long)adc_value * 5000 >>10;
    value = (unsigned int) vout;
       T[0] =  value/1000+48;   //Add 48 to get the ASCII character
       T[1]='.' ;
       T[2] = ( value/100)%10+48;
       T[3] =  (value/10)%10 +48;
       T[4] = ( value %10) +48;
       T[5]=0;
}


while(1)
    {
        AN0RES = ADC_Read(4);
        Value_converter( AN0RES ,TempSTR);
        LCD_Goto(1, 2);
        LCD_Print(TempSTR);
        __delay_ms(500);*/
    }
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top