LM35 Temperature Sensor and 18f4520

Discussion in 'Programmer's Corner' started by starday, Feb 6, 2013.

  1. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Hi all,

    Im new to C++ prog and i have a project which requires me using a 18f4520 with MPLAB IDE 8.80 and C18 compiler.

    I have a LM35 which i will need to output the temperature value onto a 2x16 LCD.
    Im using 18f4520 and making use of its ADC to do the conversion but im stucked with the compiling of the codes.

    I hope someone can enlighten me with this.

    Below is my coding.

    Code ( (Unknown Language)):
    1.  
    2. #include <p18f4520.h>
    3. #include <delays.h>
    4. #include <stdlib.h>
    5.  
    6. void Init_LCD(void);                // Initialize the LCD
    7. void W_ctr_4bit(char);                // 4-bit Control word for LCD
    8. void W_data_4bit(char);            // 4-bit Text Data for LCD
    9. void Delay_1kcyc(void);            // 1000 cycles delay
    10.  
    11. #define LCD_DATA    PORTD
    12. #define LCD_RW       PORTAbits.RA2       // RW signal for LCD
    13. #define LCD_RS       PORTAbits.RA3       // RS signal for LCD
    14. #define LCD_E         PORTAbits.RA1       // E signal for LCD
    15.  
    16. unsigned char     LCD_TEMP, i;
    17. char Buffer[20];           // Buffer to hold temperature character string
    18. unsigned int i;             // Index variable
    19. unsigned int t;            // Variable for temperature
    20.  
    21. void main(void)
    22. {
    23. /* Declaration of variables */
    24.  
    25.     TRISA = 0b11110001;        // Set Pin RA0, RA4~RA7 as Input, RA1~RA3 as Output
    26.  
    27.     TRISB = 0b00000000;        // Set Port B as Output port (LEDs)
    28.     PORTB = 0b00000000;        // Port B initialize as OFF (LEDs not lighted)
    29.  
    30.     TRISC = 0b00000000;        // Set PORT C as Output port (Buzzer)
    31.  
    32.     ADCON2 = 0b10000100;    // Result Right justified, Manual acquisition time, Fosc/4
    33.  
    34.  
    35. /* Main program starts */
    36.  
    37.     Init_LCD();             // Init LCD 4-bit interface, multiple line
    38.  
    39.     while(1)
    40.     {
    41.         /* Measure Temperature */
    42.  
    43.         ADCON0 = 0b00000001;        // Select AN0 (channel 0) for Temp sensor, turn on ADC
    44.         ADCON1 = 0b00001110;        // Select AN0 as ANALOG input, internal voltage
    45.         Delay10TCYx(1);                // Acquisition time 10us (>=5us)
    46.  
    47.         ADCON0bits.GO = 1;            // Start A/D Conversion
    48.  
    49.         while(ADCON0bits.DONE);        // ADC completed?
    50.         {
    51.             t= (ADRES*500) / 255;     // ADRES (16bit) is the output of ADC, Convert to Degree Celsius in 8 bits format.
    52.             W_ctr_4bit(0xC0)        // Move cursor to line 2 position 1
    53.             itoa(t, Buffer);    // Convert number in variable t to a  string and store in variable Buffer
    54.             i = 0;
    55.             while (Buffer[i] != 0) W_data_4bit (Buffer[i++]);
    56.         }
    57.     }
    58.  
    59. }
    60.  
    61. /* LCD display initialization */
    62. void Init_LCD()        
    63. {            
    64.     // Special Sequence a) to d) required for 4-bit interface
    65.  
    66.     Delay1KTCYx(15);            //   a) 15ms LCD power-up delay
    67.     W_ctr_4bit(0x03);            //   b) Function Set (DB4-DB7: 8-bit interface)
    68.     Delay1KTCYx(5);              //   c) 5ms delay
    69.     W_ctr_4bit(0x02);            //   d) Function Set (DB4-DB7: 4-bit interface)
    70.     W_ctr_4bit(0b00101000);        // Function Set - 4-bit, 2 lines, 5X7
    71.     W_ctr_4bit(0b00001100);        // Display on, cursor off
    72.     W_ctr_4bit(0b00000110);        // Entry mode - inc addr, no shift
    73.     W_ctr_4bit(0b00000001);        // Clear display & home position
    74. }
    75.    
    76. /* Write control word in term of 4-bit at a time to LCD */
    77. void W_ctr_4bit (char x)
    78. {
    79.     LCD_RW    = 0;               // Logic ‘0’
    80.     LCD_RS    = 0;                // Logic ‘0’
    81.     LCD_TEMP     = x;           // Store control word
    82. LCD_TEMP    >>= 4;            // send upper nibble of control word
    83. LCD_E    = 1;                     // Logic ‘1’
    84. LCD_DATA     = LCD_TEMP;
    85. Delay1KTCYx(1);                // 1ms delay
    86. LCD_E    = 0;                    // Logic ‘0’
    87. Delay1KTCYx(1);                // 1ms delay
    88. LCD_TEMP    = x;              // Store control word
    89. LCD_TEMP    &= 0x0f;        // Send lower nibble of control word
    90. LCD_E    = 1;                    // Logic ‘1’
    91. LCD_DATA     = LCD_TEMP;
    92. Delay1KTCYx(1);               // 1ms delay
    93. LCD_E    = 0;                   // Logic 0’
    94. Delay1KTCYx(1);              // 1ms delay
    95. }
    96.  
    97. /* Write text data in term of 4-bit at a time to LCD */
    98. void W_data_4bit (char x)
    99. {
    100.     LCD_RW     = 0;              // Logic ‘0’
    101.     LCD_RS     = 1;               // Logic ‘1’
    102.     LCD_TEMP     = x;           // Store text data
    103.     LCD_TEMP  >>= 4;          // Send upper nibble of text data
    104.     LCD_E     = 1;                // Logic ‘1’
    105.     LCD_DATA = LCD_TEMP;
    106.     Delay1KTCYx(1);             // 1ms delay
    107.     LCD_E     = 0;                 // Logic ‘0’
    108.     Delay1KTCYx(1);             // 1ms delay
    109.     LCD_TEMP     = x;           // Store text data
    110.     LCD_TEMP &= 0x0f;         // Send lower nibble of text data
    111.     LCD_E     = 1;                // Logic ‘1’
    112.     LCD_DATA = LCD_TEMP;
    113.     Delay1KTCYx(1);            // 1ms delay
    114.     LCD_E     = 0;                // Logic ‘0’
    115.     Delay1KTCYx(1);            // 1ms delay
    116. }
    117. [/i]



    Im having a syntax error at the line indicated with >>>>itoa(t, Buffer)

    Thanks for help
     
    Last edited by a moderator: Feb 7, 2013
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
    1. Use code tags and formatted code when posting your code.

    2. Don't you notice something missing on the line above the itoa line?
     
  3. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Hi spinnaker,

    What do you mean by code tags and formatted code ?

    Sorry for my ignorance, because im not good in programming, i dont really get the meaning.

    And you mention something else is missing, can i ask what is that ?

    Thanks for the help..
     
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    "Code tags" are the way to put your code in nice scrolling boxes like yours now is. It preserves the "white space" (tabs and spaces) that indent your code to make it readable to humans.

    You get that by hitting the # button above the reply window where you type your questions.

    Next, always compile your code to get a "clean" build, meaning no errors and no warnings. If you get errors, start by looking at only the very first error, as very often a simple error in one line (like a forgotten ; ) will cascade into many errors later.

    If you cannot get a build without errors, post the error message and the offending line (and the lines before and after it too) and identify that line!

    A warning means C had to guess what you meant, and usually that means you made some mistake. I don't allow any warnings in my code.
     
  5. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,360
    To be clear, code tags have nothing to do with programming. They are used to put your program listing in a box to be displayed on this forum, as shown on your post edited by bertus.

    [code=rich]
    ... your program goes here ...
    [/code]
     
    Last edited: Feb 7, 2013
  6. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Thanks ErnieM and MrChips for the explanations and bertus for the edit.
    I will take note on them..
     
  7. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Code ( (Unknown Language)):
    1.  
    2. #include <p18f4520.h>
    3. #include <delays.h>
    4. #include <stdlib.h>
    5.  
    6. void Init_LCD(void);                // Initialize the LCD
    7. void W_ctr_4bit(char);                // 4-bit Control word for LCD
    8. void W_data_4bit(char);            // 4-bit Text Data for LCD
    9. void Delay_1kcyc(void);            // 1000 cycles delay
    10.  
    11. #define LCD_DATA    PORTD
    12. #define LCD_RW       PORTAbits.RA2       // RW signal for LCD
    13. #define LCD_RS       PORTAbits.RA3       // RS signal for LCD
    14. #define LCD_E        PORTAbits.RA1       // E signal for LCD
    15.  
    16. unsigned char     LCD_TEMP, i;
    17.  
    18. void main(void)
    19. {
    20. /* Declaration of variables */
    21.  
    22.     char Buffer[20];         // Buffer to hold temperature character string
    23.     unsigned int i;         // Index variable
    24.     unsigned int t;         // Variable for temperature
    25.  
    26.     TRISA = 0b11110001;        // Set Pin RA0, RA4~RA7 as Input, RA1~RA3 as Output
    27.  
    28.     TRISB = 0b00000000;        // Set Port B as Output port (LEDs)
    29.     PORTB = 0b00000000;        // Port B initialize as OFF (LEDs not lighted)
    30.  
    31.     TRISC = 0b00000000;        // Set PORT C as Output port (Buzzer)
    32.  
    33.     ADCON2 = 0b10000100;    // Result Right justified, Manual acquisition time, Fosc/4
    34.  
    35.  
    36.  
    37. /* Main program starts */
    38.  
    39.     Init_LCD();             // Init LCD 4-bit interface, multiple line
    40.  
    41.     while(1)
    42.     {
    43.         /* Measure Temperature */
    44.  
    45.         ADCON0 = 0b00000001;        // Select AN0 (channel 0) for Temp sensor, turn on ADC
    46.         ADCON1 = 0b00001110;        // Select AN0 as ANALOG input, internal voltage
    47.         Delay10TCYx(1);               // Acquisition time 10us (>=5us)
    48.  
    49.         ADCON0bits.GO = 1;            // Start A/D Conversion
    50.  
    51.         while(ADCON0bits.DONE);        // ADC completed?
    52.         {
    53.             t= (ADRES*500) / 255;     // ADRES (16bit) is the output of ADC, Convert to Degree Celsius in 8 bits format.
    54.             W_ctr_4bit(0xC0);        // Move cursor to line 2 position 1
    55.             itoa(t,Buffer);            // Convert number in variable t to a string and store in variable Buffer
    56.             i = 0;
    57.            
    58.             while (Buffer[i] != 0)
    59.             {
    60.                 W_data_4bit (Buffer[i++]);
    61.             }
    62.         }
    63.     }
    64.  
    65. }
    66.  
    67.  
    68. /* LCD display initialization */
    69. void Init_LCD()        
    70. {            
    71.     // Special Sequence a) to d) required for 4-bit interface
    72.  
    73.     Delay1KTCYx(15);            //   a) 15ms LCD power-up delay
    74.     W_ctr_4bit(0x03);            //   b) Function Set (DB4-DB7: 8-bit interface)
    75.     Delay1KTCYx(5);                //   c) 5ms delay
    76.     W_ctr_4bit(0x02);            //   d) Function Set (DB4-DB7: 4-bit interface)
    77.     W_ctr_4bit(0b00101000);        // Function Set - 4-bit, 2 lines, 5X7
    78.     W_ctr_4bit(0b00001100);        // Display on, cursor off
    79.     W_ctr_4bit(0b00000110);        // Entry mode - inc addr, no shift
    80.     W_ctr_4bit(0b00000001);        // Clear display & home position
    81. }
    82.    
    83. /* Write control word in term of 4-bit at a time to LCD */
    84. void W_ctr_4bit (char x)
    85. {
    86.     LCD_RW    = 0;                // Logic ‘0’
    87.     LCD_RS    = 0;                // Logic ‘0’
    88.     LCD_TEMP     = x;            // Store control word
    89.     LCD_TEMP    >>= 4;            // send upper nibble of control word
    90.     LCD_E    = 1;                // Logic ‘1’
    91.     LCD_DATA     = LCD_TEMP;
    92.     Delay1KTCYx(1);                // 1ms delay
    93.     LCD_E    = 0;                // Logic ‘0’
    94.     Delay1KTCYx(1);                // 1ms delay
    95.     LCD_TEMP    = x;            // Store control word
    96.     LCD_TEMP    &= 0x0f;        // Send lower nibble of control word
    97.     LCD_E    = 1;                // Logic ‘1’
    98.     LCD_DATA     = LCD_TEMP;
    99.     Delay1KTCYx(1);                // 1ms delay
    100.     LCD_E    = 0;                // Logic 0’
    101.     Delay1KTCYx(1);                // 1ms delay
    102. }
    103.  
    104. /* Write text data in term of 4-bit at a time to LCD */
    105. void W_data_4bit (char x)
    106. {
    107.     LCD_RW     = 0;                // Logic ‘0’
    108.     LCD_RS     = 1;                // Logic ‘1’
    109.     LCD_TEMP     = x;            // Store text data
    110.     LCD_TEMP  >>= 4;            // Send upper nibble of text data
    111.     LCD_E     = 1;                // Logic ‘1’
    112.     LCD_DATA = LCD_TEMP;
    113.     Delay1KTCYx(1);                // 1ms delay
    114.     LCD_E     = 0;                // Logic ‘0’
    115.     Delay1KTCYx(1);                // 1ms delay
    116.     LCD_TEMP     = x;            // Store text data
    117.     LCD_TEMP &= 0x0f;            // Send lower nibble of text data
    118.     LCD_E     = 1;                // Logic ‘1’
    119.     LCD_DATA = LCD_TEMP;
    120.     Delay1KTCYx(1);                // 1ms delay
    121.     LCD_E     = 0;                // Logic ‘0’
    122.     Delay1KTCYx(1);                // 1ms delay
    123. }
    124.  
    125. [/i]


    I corrected my previous error and i manage to compile and build it this time..
    The problem is that i cant display it on my LCD as theres nothing on display.

    Appreciate if anyone can tell me where have i gone wrong with this code ?
    Im kinda reaching the deadline for project as i have to implement a web page for this as well so i really hope for your help on this..

    Thanks
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
    Unless it is something really obvious, no one is going to go through your code to try to figure out what is wrong. It would be a difficult task anyway.


    Why are you trying to use your own code to write to the LCD? Most compilers have a library to do this.


    My suggestion is to use a canned library and write some simple code to display something like Hello World.

    If that still does not work then you need to step through your code and verify that pins are changing on the LCD. For that you will need a scope, logic analyzer, logic probe (you can make you own with an LED and resistor. You could also use a voltmeter.
     
  9. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Hi Spinnaker,

    I have tried a simple program to output "Hello World" prior to this and im able to see that on the LCD so i can safely assume that my hardware is up and running well.
    But the current one involves taking in a sensor input and do some manipulations before outputting on LCD. Some tweaking to the codes are necessary and unfortunately im not well adept in that.

    Actually i would just need some affirmative from some of the experts here to verify that the manipulations i have done so far are on the right track.

    In particularly this portion,

    Code ( (Unknown Language)):
    1.  
    2.  
    3. while(1)
    4.     {
    5.         /* Measure Temperature */
    6.  
    7.         ADCON0 = 0b00000001;        // Select AN0 (channel 0) for Temp sensor, turn on ADC
    8.         ADCON1 = 0b00001110;        // Select AN0 as ANALOG input, internal voltage
    9.         Delay10TCYx(1);                 // Acquisition time 10us (>=5us)
    10.  
    11.         ADCON0bits.GO = 1;            // Start A/D Conversion
    12.  
    13.         while(ADCON0bits.DONE);     // ADC completed?
    14.         {
    15.             t= (ADRES*500) / 255;     // ADRES (16bit) is the output of ADC, Convert to                     Degree Celsius in 8 bits format.
    16.             W_ctr_4bit(0xC0);           // Move cursor to line 2 position 1
    17.             itoa(t,Buffer);                 // Convert number in variable t to a string and store                     in variable Buffer
    18.             i = 0;
    19.            
    20.             while (Buffer[i] != 0)
    21.             {
    22.                 W_data_4bit (Buffer[i++]);
    23.             }
    24.         }
    25.     }
    26.  
    27. [/i]


    I have googled but found no ready available library for the C18 compiler, most of them uses self coding to output similar result.

    Thanks
     
  10. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
  11. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Thanks spinnaker.

    But for now, i hope to at least get the result showing on the LCD before moving on to using USART for serial comm connection.

    But i guess nobody is really willing to guide me to the coding i have attempted nor getting to the point of correcting it.

    Thanks anyway.
     
  12. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Good lord, doesn't anyone at Microchip proofread their own manuals????

    The XLCD library requires a function "DelayFor18TCY" that they kindly define as "Delay for 18 cycles." Makes sense from the name, but what is really needed is the minimum pulse width for the "E" pin, which is 450 nS for the device I use.

    18 cycles comes from the particular device and the particular frequency used in the original sample program for this code. Some how MC never caught on to this.

    Mind you, I like the XLCD library, as the faults are extremely plain, and most easily fixable.

    Which is why I use my own (heavily) edited version of this library for my LCD code.

    I did not see in the manual how to use this library... the C files get added to your source files, as they need to be built along with your program. The dot H file is best copied to your project file, as you need edit it to point to the pins you are using and define the delays (I use TimeDelay.c from the Microchip Applications Library).
     
  13. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    As far as the temperature reading goes (it seems you got the LCD to work?) do you have a debugger to see what is being passed back and fourth?
     
  14. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Hi ErnieM

    I will post the result when i get back today after work (im a part time student)..

    Actually i followed your other post regarding this topic some times back.

    http://forum.allaboutcircuits.com/showthread.php?t=59885

    I used some of the codes you had written inside but i could not repeat it in my work here.

    Thanks
     
  15. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    Hi ErnieM


    Code ( (Unknown Language)):
    1.  
    2. while(ADCON0bits.DONE);        // ADC completed?
    3.         {
    4.             t= (ADRESL*500) / 255;     // ADRES (16bit) is the output of ADC, Convert to Degree Celsius in 8 bits format.
    5.             W_ctr_4bit(0xC0);        // Move cursor to line 2 position 1
    6.             itoa(t,Buffer);            // Convert number in variable t to a string and store in variable Buffer
    7.             i = 0;
    8.            
    9.             while (Buffer[i] != 0)
    10.             {
    11.                 W_data_4bit (Buffer[i++]);
    12.             }
    13.         }
    14. [/i]


    For ADRES, my watch window shows 0x0045 or decimal 69
    for t, it shows "Out of Scope"
     
  16. starday

    Thread Starter New Member

    Feb 6, 2013
    9
    0
    This is the screenshot taken
     
  17. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
    I'll post some lcd code I have been using. Hopefully this weekend. Sorry but I have been feeling under the weather for about 1.5 months now. I simply just don't have the energy to package it up and post it. :)
     
  18. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Perhaps making t a global variable (defined before main() ) will bring it back into the scope of the A2D code.

    Also, you don't access ADRES but ADRESL, which is only the 8 lower bits of the result (which is perfect for 8 bit conversions but not good for 10 bits).
     
  19. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
    I have seen this happen with the debugger before. Ifr you set a watch then run your code to the breakpoint this seems to happen.


    Better to sett the watch after the breakpoint occurs.
     
  20. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,001
    If you are looking at ADRES then you should use your register window and not watch.
     
Loading...