Author Topic: PIC18 interfacing with LM35  (Read 4072 times)

0 Members and 1 Guest are viewing this topic.

Offline Udayan SinhaTopic starter

  • Regular Contributor
  • *
  • Posts: 71
PIC18 interfacing with LM35
« on: December 28, 2013, 04:14:52 am »
I am trying to interface an LM35 with a PIC18F4550 & get it to transmit the temperature (floating values) via UART. Since I am using a float data type to calculate & store the temperature value, how do I send it byte by byte to the TXREG (as TXREG is only a byte wide & float data type is 4 bytes wide)?

P.S. I have not written the serial() function in the code (that is where I am getting the problem  :-// ). Let me know if you need the configuration bit settings &  a schematic of the circuit I used.

Code I used -

void interrupt isr(void);
void adc_isr(void);
void serial(void);
void delay(unsigned int x);
float adc_output;
void main()
{
    SPBRG=0x0C;                   //9600bps, 8-bit BRG
    SPEN=1;                       //enable serial port
    IPEN=1;                       //enable interrupt priority
    INTCON=0xC0;                  //GIEL=1, GIEH=1
    ADIE=1;                       //enable ADC interrupt
    ADIP=1;                       //ADC interrupt is of high priority
    ADON=1;                       //enable ADC module
    TRISA=0xFF;                   //PORTA is input
    ADCS0=1;                      //clock=F/8
    ACQT0=1;                      //acquisition time=t*2
    ADFM=1;                       //right justified
    while(1)
    {
        GO=1;                     //start A/D conversion
        delay(1000);
    }
}
void interrupt isr(void)
{
    asm("CALL _adc_isr");
}
void adc_isr(void)
{
    ADIF=0;
    adc_output=ADRES;
    adc_output=adc_output*50;
    adc_output=adc_output/1023;
    adc_output=adc_output*10;
    serial();               //used to transmit temp value via serial
}
void delay(unsigned int x)
{
    unsigned char y;
    unsigned int i;
    for(i=0; i<x; i++)
    {
        for(y=0; y<255; y++);
    }
}
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7799
  • Country: us
  • adieu
Re: PIC18 interfacing with LM35
« Reply #1 on: December 28, 2013, 04:23:30 am »
Well.... you really shouldn't be using a float in the first place. Huge waste of memory... you can just use an integer value in units of "tenths of a degree" or whatever suits your application.

But if you really want to transmit a float byte for byte, that's easy. Make a union of a float and four bytes, and transmit the bytes:

Code: [Select]
union {float f; unsigned char bytes[4];} adc_output;

// Set or read ADC output:
adc_output.f = 2.3;

// Transmit:
serial(adc_output.bytes[0]);
serial(adc_output.bytes[1]);
serial(adc_output.bytes[2]);
serial(adc_output.bytes[3]);
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline RoadRunner

  • Frequent Contributor
  • **
  • Posts: 398
  • Country: de
Re: PIC18 interfacing with LM35
« Reply #2 on: December 28, 2013, 04:42:51 am »
where is the code for PIC18F458 with LM35 , although it use LCD instead off serial port , all you have to do is send the same char to serial port instead of LCD 
http://www.circuitvalley.com/2011/11/nokia-3315-lcd-based-temperature-meter.html
« Last Edit: December 28, 2013, 04:59:37 am by Gaurav »
 

Offline Udayan SinhaTopic starter

  • Regular Contributor
  • *
  • Posts: 71
Re: PIC18 interfacing with LM35
« Reply #3 on: December 29, 2013, 02:39:28 am »
Well.... you really shouldn't be using a float in the first place. Huge waste of memory... you can just use an integer value in units of "tenths of a degree" or whatever suits your application.

But if you really want to transmit a float byte for byte, that's easy. Make a union of a float and four bytes, and transmit the bytes:

Code: [Select]
union {float f; unsigned char bytes[4];} adc_output;

// Set or read ADC output:
adc_output.f = 2.3;

// Transmit:
serial(adc_output.bytes[0]);
serial(adc_output.bytes[1]);
serial(adc_output.bytes[2]);
serial(adc_output.bytes[3]);

Yeah I know I can make do with integers but the problem would have remained (I actually didn't know how to use structures & unions  :palm:). Used integers finally. Thanks a lot.
So here's the final code (tested and working) :-+ -

void interrupt isr(void);
void adc_isr(void);
void serial(void);
void delay(unsigned int x);
unsigned int l;
union temperature
{
    unsigned int z;         //calculated output
    unsigned char y[2];     //for sending via serial
}adc_output;
void main()
{
    SPBRG=0x0C;                   //9600bps, 8-bit BRG
    SPEN=1;                       //enable serial port
    IPEN=1;                       //enable interrupt priority
    INTCON=0xC0;                  //GIEL=1, GIEH=1
    ADIE=1;                       //enable ADC interrupt
    ADIP=1;                       //ADC interrupt is of high priority
    ADON=1;                       //enable ADC module
    TRISA=0xFF;                   //PORTA is input
    ADCS0=1;                      //clock=F/8
    ACQT0=1;                      //acquisition time=t*2
    ADFM=1;                       //right justified
    while(1)
    {
        GO=1;                     //start A/D conversion
        delay(1000);
    }
}
//isr
void interrupt isr(void)
{
    asm("CALL _adc_isr");
}
//isr for adc
void adc_isr(void)
{
    ADIF=0;
    l=ADRES;
    l=l*50;
    l=l/1023;
    l=l*10;
    adc_output.z=l;
    serial();
}
//function to send ADC output via serial
void serial(void)
{
    TXREG=adc_output.y[1];
    TXEN=1;
    while(TRMT==0);
    TXREG=adc_output.y[0];
    while(TRMT==0);
    TXREG='\n';
    while(TRMT==0);
}
//delay function
void delay(unsigned int x)
{
    unsigned char y;
    unsigned int i;
    for(i=0; i<x; i++)
    {
        for(y=0; y<255; y++);
    }
}

P.S. - yeah i know the serial() would have looked a lot better if I had allowed input arguments to the TXREG but for now i guess this will do  ;D
« Last Edit: December 29, 2013, 05:49:13 am by Udayan Sinha »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf