2 pins ADC conversion pic18f4550

Discussion in 'General Electronics Chat' started by AnnePriscilla, Apr 11, 2016.

  1. AnnePriscilla

    Thread Starter New Member

    Apr 11, 2016
    4
    0
    Hey guys!

    I've an assignment that requires me to connect 2 sensors on the same PORT A. So I was thinking of using bit0 and bit1 for the ADC conversion. I looked through all the sample codes and my school's textbook, however, can't find a way to configure 2 pins at the same time. Currently I am using Mplabv8.63 compiler.

    So far, I have only managed to get my temperature sensor(Lm35) working and to display the output reading. However, I can't seem to integrate another sensor onto the same codes. This codes were taken from http://forum.allaboutcircuits.com/threads/lm35-temperature-sensor.59885/


    1. //Temperature Sensor - Convert the Analog signal to Digital and Display it to the LCD Display Board

    2. #include <p18F4550.h>
    3. #include <delays.h>
    4. #include "lcd.h"
    5. // ************** ErnieM Addition Start ****************
    6. #include <stdlib.h> // added to get itoa() function to convert t into a string
    7. // ************** ErnieM Addition End ****************



    8. // Include this when using Bootloader Program ================================
    9. #pragma udata

    10. extern void _startup (void); // See c018i.c in your C18 compiler dir
    11. #pragma code _RESET_INTERRUPT_VECTOR = 0x000800
    12. void _reset (void)
    13. {
    14. _asm goto _startup _endasm
    15. }
    16. #pragma code

    17. #pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
    18. void _high_ISR (void)
    19. {
    20. ;
    21. }

    22. #pragma code _LOW_INTERRUPT_VECTOR = 0x000818
    23. void _low_ISR (void)
    24. {
    25. ;
    26. }
    27. #pragma code

    28. #pragma code

    29. // additional codes ends here ===============================================================

    30. // Your program declarations start here:====


    31. #define LCD_RS PORTDbits.RD6 // Register Select on LCD
    32. #define LCD_EN PORTDbits.RD4 // Enable on LCD controller
    33. #define LCD_WR PORTDbits.RD5 // Write on LCD controller


    34. //--- Function for writing a command byte to the LCD in 4 bit mode -------------

    35. void lcd_write_cmd(signed char cmd)
    36. {
    37. unsigned char temp2;
    38. LCD_RS = 0; // Select LCD for command mode
    39. Delay10TCYx(4); // 40us delay for LCD to settle down
    40. temp2 = cmd;
    41. temp2 = temp2 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
    42. PORTD = temp2 & 0x0F; // Output to PORTD which is connected to LCD

    43. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing
    44. lcd_strobe();
    45. Delay1KTCYx(10); // 10ms - Delay at least 1 ms after strobing

    46. temp2 = cmd; // Re-initialise temp2
    47. PORTD = temp2 & 0x0F; // Mask out upper 4 bits

    48. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing
    49. lcd_strobe();
    50. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing

    51. }

    52. //---- Function to write a character data to the LCD ---------------------------

    53. void lcd_write_data(char data)
    54. {
    55. char temp1;

    56. LCD_RS = 1; // Select LCD for data mode
    57. Delay10TCYx(4); // 40us delay for LCD to settle down

    58. temp1 = data;
    59. temp1 = temp1 >> 4;
    60. PORTD = temp1 & 0x0F;
    61. Delay1KTCYx(10);
    62. LCD_RS = 1;
    63. Delay1KTCYx(10); //_-_ strobe data in

    64. lcd_strobe();
    65. Delay1KTCYx(10);

    66. temp1 = data;
    67. PORTD = temp1 & 0x0F;
    68. Delay1KTCYx(10);
    69. LCD_RS = 1;
    70. Delay1KTCYx(10); //_-_ strobe data in

    71. lcd_strobe();
    72. Delay1KTCYx(10);
    73. }

    74. //-- Function to generate the strobe signal for command and character----------

    75. void lcd_strobe(void) // Generate the E pulse
    76. {
    77. LCD_EN = 1; // E = 0
    78. Delay1KTCYx(100); // 10ms delay for LCD_EN to settle
    79. LCD_EN = 0; // E = 1
    80. Delay1KTCYx(100); // 10ms delay for LCD_EN to settle
    81. }


    82. //---- Function to initialise LCD module ----------------------------------------
    83. void lcd_init(void)
    84. {
    85. TRISD = 0x00;
    86. PORTD = 0x00; // PORTD is connected to LCD data pin
    87. LCD_EN = 0;
    88. LCD_RS = 0; // Select LCD for command mode
    89. LCD_WR = 0; // Select LCD for write mode

    90. Delay10KTCYx(250); // Delay a total of 1 s for LCD module to
    91. Delay10KTCYx(250); //
    92. Delay10KTCYx(250); //
    93. Delay10KTCYx(250); // finish its own internal initialisation

    94. /* The data sheets warn that the LCD module may fail to initialise properly when
    95. power is first applied. This is particularly likely if the Vdd
    96. supply does not rise to its correct operating voltage quickly enough.

    97. It is recommended that after power is applied, a command sequence of
    98. 3 bytes of 30h be sent to the module. This will ensure that the module is in
    99. 8-bit mode and is properly initialised. Following this, the LCD module can be
    100. switched to 4-bit mode.
    101. */

    102. lcd_write_cmd(0x33);
    103. lcd_write_cmd(0x32);
    104. lcd_write_cmd(0x28); // 001010xx – Function Set instruction
    105. // DL=0 :4-bit interface,N=1 :2 lines,F=0 :5x7 dots

    106. lcd_write_cmd(0x0E); // 00001110 – Display On/Off Control instruction
    107. // D=1 :Display on,C=1 :Cursor on,B=0 :Cursor Blink on

    108. lcd_write_cmd(0x06); // 00000110 – Entry Mode Set instruction
    109. // I/D=1 :Increment Cursor position
    110. // S=0 : No display shift

    111. lcd_write_cmd(0x01); // 00000001 Clear Display instruction

    112. Delay1KTCYx(20); // 20 ms delay

    113. }

    114. void main(void)
    115. {
    116. // ************** ErnieM Addition Start ****************
    117. // add these variables
    118. char Buffer[10]; // buffer to hold your temperature character string
    119. unsigned int i; // index variable
    120. // moved your "t" variable up here, C18 wants to see variables defined at the
    121. // very start of a block. Other compilers let you make a definition anywhere,
    122. // this C28 compiler seems to want them up top like this
    123. unsigned int t; // variable for temperature
    124. // ************** ErnieM Addition End ****************

    125. // Do not remove these as well=============
    126. ADCON1 = 0x0F; // Configure PORTA to be digital I/O
    127. CMCON = 0x07;
    128. // ========================================
    129. // Your MAIN program Starts here: =========
    130. lcd_init(); // Initialise LCD module

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

    133. /* Initialise analog to digital conversion setting */

    134. ADCON0 = 0b00000001; // bit5-2 0000 select channel 0 conversion
    135. // bit1 A/D conversion status bit
    136. // 1- GO to starts the conversion
    137. // 0 - DONE when A/D is completed
    138. // bit0 Set to 1 to power up A/D

    139. ADCON1 = 0b00001100; // bit5 reference is VSS
    140. // bit4 reference is VDD
    141. // bit3-0 AN2 to AN0 Analog, the rest Digital

    142. ADCON2 = 0b10010110; // bit7 : A/D Result Format. 0 Left, 1 Right justified ( Set it to 1, Right Justified)
    143. // bit5-3 : 010 acquisition time = 4 TAD
    144. // bit2-0 : 110 conversion clock = Tosc / 16
    145. // ************** ErnieM Addition Start ****************
    146. // I'm going to change your loops so it measures the temperature every second
    147. // then displays it.
    148. // for(;;)
    149. // {
    150. // ************** ErnieM Addition End ****************

    151. // ************** ErnieM Addition Start ****************
    152. // this code moved down below into the once a second loop
    153. // ADCON0bits.GO = 1; // This is bit2 of ADCON0, START CONVERSION NOW
    154. // while(ADCON0bits.GO == 1); // Waiting for DONE

    155. // t = (ADRES * 500) / 255; //Convert to Degree Celcius - ADRES (16bit) is the output of ADC
    156. // ************** ErnieM Addition End ****************
    157. // ************** ErnieM Addition Start ****************
    158. // removed this loop
    159. // while(1)
    160. // {
    161. // ************** ErnieM Addition End ****************
    162. lcd_write_cmd(0x80); // Move cursor to line 1 position 1

    163. lcd_write_data('T');
    164. lcd_write_data('E');
    165. lcd_write_data('M');
    166. lcd_write_data('P');
    167. lcd_write_data('E');
    168. lcd_write_data('R');
    169. lcd_write_data('A');
    170. lcd_write_data('T');
    171. lcd_write_data('U');
    172. lcd_write_data('R');
    173. lcd_write_data('E');
    174. lcd_write_data(':');
    175. // ************** ErnieM Addition Start ****************
    176. // HERE is where we'll loop
    177. while(1)
    178. {
    179. // measure temperature
    180. ADCON0bits.GO = 1; // This is bit2 of ADCON0, START CONVERSION NOW
    181. while(ADCON0bits.GO == 1); // Waiting for DONE
    182. t = (ADRES * 500) / 255; //Convert to Degree Celcius - ADRES (16bit) is the output of ADC
    183. lcd_write_cmd(0xC0); // Move cursor to line 2 position 1

    184. // lcd_write_data(t); // Display the temperature

    185. // we can't just drint the integer, need to first convert the number into a character string
    186. // convert t to a string
    187. itoa(t,Buffer);
    188. // print that string!
    189. i = 0;
    190. while (Buffer != 0) lcd_write_data(Buffer[i++]);
      [*]

      [*]

      [*] lcd_write_data(0xDF);
      [*] lcd_write_data('C');
      [*]

      [*] Delay10KTCYx(250); // Delay a total of 1 s
      [*] Delay10KTCYx(250); //
      [*] Delay10KTCYx(250); //
      [*] Delay10KTCYx(250); // so the screen doesn't "flash" too much on updates
      [*]// for the future: Save the old value of t, and only update the screen
      [*]// when a new temperature is measured. That way you don't need that 1 sec delay
      [*]
      [*]

      [*] }
      [*]// ************** ErnieM Addition End ****************
      [*]

      [*]
      [*]

      [*]
      [*]// ************** ErnieM Addition Start ****************
      [*]// removed infinite "stop here" loop
      [*]// while(1); //stop here for now
      [*]

      [*]

      [*]// }
      [*]// }
      [*]

      [*]// ************** ErnieM Addition End ****************
      [*]} // end of main()


    Can somebody please advise me on how to configure another pin so I can add another sensor on the same port.(If it's even possible)

    Thankyou!
     
  2. Dodgydave

    Distinguished Member

    Jun 22, 2012
    4,980
    744
    You select the channel in ADCON0,

    Your programme line 181...
     
    Last edited: Apr 12, 2016
  3. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,648
    762
    Is it necessary to post the whole code?

    Coul you edit and suppres what is not relevant?

    Use the "code" tags
     
    djsfantasi likes this.
  4. AnnePriscilla

    Thread Starter New Member

    Apr 11, 2016
    4
    0
    Sorry im new to this
     
  5. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,648
    762
    OK. Go an edit the OP then.
     
  6. AnnePriscilla

    Thread Starter New Member

    Apr 11, 2016
    4
    0
    Hey!
    Thanks for the response. I wanna make use of pin0 and pin1. So far I've got this:

    int value1, value2; //to store value 1 and 2
    ADCON1 = 0x0D; // to select AN0(RA0) and AN1(RA1) as analog input
    ADCON2 = 0x__; // i dunno the value but set as FOSC/4 and right justified
    ADCON0 = 0x01; //select AN0
    ADCON0bits.GO = 1; //start conversion
    while(ADCON0bits.GO == 1); //wait for conversion to finish
    value1 = (ADRESH*256)+ADRESL;
    ADCON0 = 0x05; //select AN1(RA1)
    ADCON0bits.GO = 1; //start conversion
    while(ADCON0bits.GO == 1); //wait for conversion to finish
    value2 = (ADRESH*256)+ADRESL;

    This way value 1 and 2 contain the ADC values for AN0 and AN1 respectively.
     
Loading...