PIC18F4550 interface with lm355 temperature sensor

Discussion in 'Embedded Systems and Microcontrollers' started by surfon, Feb 2, 2013.

  1. surfon

    Thread Starter New Member

    Nov 26, 2011
    4
    0
    As this is the first time i am programming such micro controller .
    I have problem displaying the actual values of the temperature as it is fluctuating every now and then .My input for the temperature sensor is AN3
    ,PORTD is the output of the LCD.:(

    I did left justified ..

    help needed ...


    Here is part of my code :

    lcd_init(); // Initialise LCD module

    LCD_RS = 1; // Select LCD for character data mode
    Delay1KTCYx(1); // 1 ms delay

    /* Initialise analog to digital conversion setting */

    ADCON0 = 0b00001011; // bit5-2 0011 select channel AN3 conversion
    // bit1 A/D conversion status bit
    // 1- GO to starts the conversion
    // 0 - DONE when A/D is completed
    // bit0 Set to 1 to power up A/D

    ADCON1 = 0b00001100; // bit5 reference is VSS
    // bit4 reference is VDD
    // bit3-0 AN3 to AN0 Analog, the rest Digital

    ADCON2 = 0b00010110; // bit7 : A/D Result Format. 1 Left, / 0 Right justified ( Set it to 1, Left Justified)
    // bit5-3 : 010 acquisition time = 4 TAD
    // bit2-0 : 110 conversion clock = Tosc / 16

    for(;;)
    {

    while(1)
    {



    lcd_write_cmd(0x80); // Move cursor to line 1 position 1

    lcd_write_data('T');
    lcd_write_data('E');
    lcd_write_data('M');
    lcd_write_data('P');
    lcd_write_data('E');
    lcd_write_data('R');
    lcd_write_data('A');
    lcd_write_data('T');
    lcd_write_data('U');
    lcd_write_data('R');
    lcd_write_data('E');
    lcd_write_data(':');
    while(1)
    {
    unsigned int t;
    ADCON0bits.GO = 1; // This is bit2 of ADCON0, START CONVERSION NOW
    while(ADCON0bits.GO == 1); // Waiting for DONE
    t=(ADRESH / 255)*50;

    lcd_write_cmd(0xC0); // Move cursor to line 2 position 1



    lcd_write_data(t);
    lcd_write_data(0xDF);
    lcd_write_data('C');
    Delay10KTCYx(200); // Delay a total of 1 s
    Delay10KTCYx(200); //
    Delay10KTCYx(200); //
    Delay10KTCYx(200);


    }
    while(1);
    }
    }
    }
     
    Last edited: Feb 2, 2013
  2. surfon

    Thread Starter New Member

    Nov 26, 2011
    4
    0
    Code ( (Unknown Language)):
    1.  
    2.  
    3.     lcd_init();                    // Initialise LCD module
    4.  
    5.     LCD_RS = 1;                    // Select LCD for character data mode
    6.     Delay1KTCYx(1);                // 1 ms delay
    7.  
    8. /* Initialise analog to digital conversion setting */
    9.  
    10.     ADCON0 = 0b00001011;    // bit5-2 0011 select channel AN3 conversion
    11.                             // bit1      A/D conversion status bit
    12.                             //          1- GO to starts the conversion
    13.                             //          0 - DONE when A/D is completed
    14.                             // bit0   Set to 1 to power up A/D
    15.  
    16.     ADCON1 = 0b00001100;    // bit5   reference is VSS
    17.                             // bit4   reference is VDD
    18.                             // bit3-0 AN3 to AN0 Analog, the rest Digital
    19.  
    20.     ADCON2 = 0b00010110;    // bit7   : A/D Result Format. 1 Left, / 0 Right justified ( Set it to 1, Left Justified)
    21.                             // bit5-3 : 010 acquisition time = 4 TAD
    22.                             // bit2-0 : 110 conversion clock = Tosc / 16
    23.  
    24.     for(;;)
    25.     {
    26.        
    27.  while(1)
    28.     {
    29.          
    30.        
    31.  
    32.         lcd_write_cmd(0x80);        // Move cursor to line 1 position 1
    33.  
    34.         lcd_write_data('T');
    35.         lcd_write_data('E');
    36.         lcd_write_data('M');
    37.         lcd_write_data('P');
    38.         lcd_write_data('E');
    39.         lcd_write_data('R');
    40.         lcd_write_data('A');
    41.         lcd_write_data('T');
    42.         lcd_write_data('U');
    43.         lcd_write_data('R');
    44.         lcd_write_data('E');
    45.         lcd_write_data(':');
    46.         while(1)
    47.         {
    48.             unsigned int t;
    49.             ADCON0bits.GO = 1;        // This is bit2 of ADCON0, START CONVERSION NOW
    50.             while(ADCON0bits.GO == 1);     // Waiting for DONE
    51.               t=(ADRESH / 255)*50;
    52.    
    53.         lcd_write_cmd(0xC0);        // Move cursor to line 2 position 1
    54.    
    55.  
    56.        
    57.         lcd_write_data(t);
    58.         lcd_write_data(0xDF);
    59.         lcd_write_data('C');
    60.         Delay10KTCYx(200);            // Delay a total of 1 s
    61.         Delay10KTCYx(200);            //
    62.         Delay10KTCYx(200);            //
    63.         Delay10KTCYx(200);            
    64.  
    65.  
    66.     }
    67.     while(1);
    68. }
    69. }
    70. }[/QUOTE]
    71.  
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Thanks for using the code tags... once you make a few most posts (10?) you'll get to edit your posts.

    The problem is down here:

    Code ( (Unknown Language)):
    1.         t=(ADRESH / 255)*50;
    2.         lcd_write_cmd(0xC0);        // Move cursor to line 2 position 1
    3.         lcd_write_data(t);
    The variable t is an integer number, but lcd_write_data() is sending a character. To display the value of t you need to convert the number to an ASCII character string.

    I'm guessing from you using the Delay1KTCYx() function you're using the C18 compiler. C18 comes with the itoa() function in stdlib.h. "itoa" means Integer to ASCII and converts a number to a string, and the LCD presents strings.

    Here's the prototype:
    Code ( (Unknown Language)):
    1. char * itoa( int value, char * string );
    Now that is a C string, an array of characters with zero as an ending marker. Your code doesn't seem equipped to print an entire string (and to complicate things C18 has two different incompatible types (ram & rom) of strings).

    Where did you get the LCD functions? Does it have something to print strings?

    You'll need them... and you will appreciate them, as you can then write lines like this:

    Code ( (Unknown Language)):
    1.     lcd_write_string("TEMPERATURE:");
     
  4. surfon

    Thread Starter New Member

    Nov 26, 2011
    4
    0

    Appreciate your help ErnieM .

    The LCD function is a template from the school to use.

    I do not have the LCD string function , we are focusing more on the main function now .Is it due to the LCD string function that we are unable to display the values?

    I have edited part of the programm, is it correct ?

    Code ( (Unknown Language)):
    1.  while(1)
    2.     {
    3.          
    4.        
    5.  
    6.         lcd_write_cmd(0x80);        // Move cursor to line 1 position 1
    7.  
    8.         lcd_write_data('T');
    9.         lcd_write_data('E');
    10.         lcd_write_data('M');
    11.         lcd_write_data('P');
    12.         lcd_write_data('E');
    13.         lcd_write_data('R');
    14.         lcd_write_data('A');
    15.         lcd_write_data('T');
    16.         lcd_write_data('U');
    17.         lcd_write_data('R');
    18.         lcd_write_data('E');
    19.         lcd_write_data(':');
    20.         while(1)
    21.         {
    22.            char * itoa( int t, char * string );
    23.    
    24.             ADCON0bits.GO = 1;        // This is bit2 of ADCON0, START CONVERSION NOW
    25.             while(ADCON0bits.GO == 1);     // Waiting for DONE
    26.               t=(ADRESH / 255)*50;
    27.          
    28.    
    29.         lcd_write_cmd(0xC0);        // Move cursor to line 2 position 1
    30.    
    31.  
    32.    
    33.         lcd_write_data(t);
    34.         lcd_write_data(0xDF);
    35.         lcd_write_data('C');
    36.         Delay10KTCYx(200);            // Delay a total of 1 s
    37.         Delay10KTCYx(200);            //
    38.         Delay10KTCYx(200);            //
    39.         Delay10KTCYx(200);            
    40.            
    41.  
    with regards to the
    Code ( (Unknown Language)):
    1.  char * itoa( int t, char * string )
    what is the char * string and char * itoa for?
     
    Last edited: Feb 2, 2013
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Also a tip. I do not know which version of the Hi-Tech C or XC8 you use. But I think you will find that the full 10 bit ADC result is defined as a unsigned short in the header file
     
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    No, not correct yet. But we'll get you there.

    The code fragment:
    Code ( (Unknown Language)):
    1. char * itoa( int t, char * string )
    is the prototype of the function, what is defined by stdlib, and you get it free in your code once you add to the top of your code:
    Code ( (Unknown Language)):
    1. #include "stdlib.h"
    To make it work you also need a buffer, or a section of RAM to hold the character string. You can make a buffer with:
    Code ( (Unknown Language)):
    1. char buffer[21]
    and that will hold 20 characters for a 20 character wide display... I make my buffer large enough to hold an entire line as it can be reused for many things. If your display is smaller then you can make buffer smaller, but always make it one extra char as that is needed for a zero to mark the end of the string.

    You will also need a routine to print a RAM buffer such as this:

    Code ( (Unknown Language)):
    1. void print_buffer(char* pBuffer)
    2. {
    3.     while (pBuffer)
    4.         lcd_write_data(*pBuffer++);
    5. }
    6.  
    Let me know if you need an explanation of how that code works (if I got it correct!).
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Almost forgot to show you how this gets used:

    Code ( (Unknown Language)):
    1.   t=(ADRESH / 255)*50;
    2.   itoa(t, buffer);            // convert  number in t to a string in buffer
    3.   lcd_write_cmd(0xC0);        // Move cursor to line 2 position 1
    4.   print_buffer(buffer);
     
  8. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Given that this is Hi-Tech C/XC8 should not the call to itoa() also contain a third argument named radix. Radix is the number format used. That will say 2,8,10 or 16. Use 10 for decimal and 16 for hexadecimal output. I can not check this on my current location
     
  9. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    Just be sure that anything written to a buffer actually stays within the declared size of the array. Going beyond it can have mystifying results, where seemingly unrelated variables get changed.
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Where was this made a given? OP has not stated a compiler.

    Neither Hi-Tech C nor XC8 come with the Delay1KTCYx() function in their library.

    C18 does, and the given prototype for the itoa function is from the C18 help file chm. It's copy and paste so I doubt there is a typo.

    As far as overflowing the buffer, even in PIC32 an integer has a maximum value of 4,294,967,295, which can be express in a string of 11 bytes, and I've suggested 21.

    (And when surfon actually gets this to work he's going to come back and ask why it always just prints zero anyway... so stay tuned.)
     
  11. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    I'm not sure if someone saw this;

    unsigned int t;
    t=(ADRESH / 255)*50;

    That is a big problem! You are only reading an 8bit ADC which will be from 0-255 range.

    The /255 operation will destroy all your data, as 255/255 =1 and <255/255 =0, so almost every adc value will be squashed to zero.

    If you want to scale ADC of 256 counts to 5.0v that is a scale ratio of 256 units : 50 units, so the correct math is;

    unisgned int t;
    t = ADRESH;
    t = (t * 50) / 256;

    Doing the *50 first means your data is not squashed to death, and doing /256 not /255 gives you correctly scaled data.
     
  12. surfon

    Thread Starter New Member

    Nov 26, 2011
    4
    0
    I will try it on monday as my friend is holding the board ,Thanks for the valuable inputs.Will update soon
     
Loading...