Bukit Mertajam, Penang

Project 4 – Analog Sensor: Potentiometer & BB-PSJ



Back to Project 3                                                                                                         Go to Project 5

In this part, we are going to discuss about how to write the Analog to Digital Converter code which has become the most popular question among the students. We are going to use PIC16F887 with have contain of 10-bits binary result and a potential-meter to adjust the voltage different and display it in the LCD display.




16 x 2 LCD Display


Analog Joystick Breakout Board





The connection for the potential-meter are very easy. Just connect one end to VDD and the other end to GND while the middle pin is connected to RA0. By referring to the PIC16F887, there are total 14 analog pins that we can choose. In here we use RA0 as out ADC input pin. For thumb joystick, connect VDD as 5V and GND. X-A connected to RA1, Y-A connected to RA5 and SW connected to RA2.



ADC enable the microcontroller to recognize, not only whether a pin is driven to logic zero or one (0 or +5V), but to precisely measure its voltage and convert it into a numerical value, i.e. digital format. The whole procedure takes place in the A/D converter module which has the following features:

  1. The converter generates a 10-bit binary result using the method of successive approximation and stores the conversion results into the ADC registers (ADRESL and ADRESH).
  2. There are 14 separate analog inputs.
  3. The A/D converter allows conversion of an analog input signal to a 10-bit binary representation of that signal.
  4. By selecting voltage references Vref- and Vref+, the minimal resolution or quality of conversion may be adjusted to various needs.

For detail information, please refer to the PIC16F887 datasheet and also this webpage.




ADCS1 = 1;
ADCS0 = 0;
ADCS is the A/D Conversion Clock select bits. In here we have selected the conversion clock as Fosc/32. Which the Fosc using are 20MHz.

ANS0 = 1;
Refer to the PORTA Analog select register. We already configure the RA0 which is ANS0 as an analog I/O. While the rest of PORTA pins as an digital I/O.

ADFM = 1;

ADFM is the conversion result format select bit. In here, we give a value 1 to configure it as an Right Justified. While if the value 0 is given, the format are in Left justified.

VCFG1 = 0;
VCFG0 = 0;
VCFG is the voltage reference bit. Which if VCFG1 is 0, the GND pin will be configure as an VSS pin. On the other hand, VCFG0 is 0, is mean that the voltage supply pin is configure as VDD.

ADON = 0;
ADON is the ADC enable bit. If the ADON is 0, the ADC is OFF. While if the ADON is 1, the ADC is ON.


unsigned int pot = 0;
Initialize and make the “pot” as a 0 value at the every time the code jump into this subroutine.

The purpose of the 1ms delay in here is to wait the holding capacitor in ADC module to fully charge.

After the A/D Conversion started, set this register and wait it to become LOW(0) which mean that it’s has done the conversion.

pot = (unsigned int) ADRESH << 8;
After done conversion, the value of ADRESH memory of ADRESH is change to 2 Bytes and shifted LEFT by 8.
E.g.: ADRESH = 0000 0011
(unsigned int)ADRESH = 0000 0000 0000 0011
(unsigned int)ADRESH = 0000 0011 0000 0000 (<< 8 )

pot = pot + ADRESL;
After the value ADRESH is shifted. The value are keep in pot. After that, the value in pot will be added with ADRESL.
E.g: pot = 11 0000 0000
ADRESL = 1111 1111
Final pot result = 11 1111 1111 (10 bits)


Before the main code is start running, we initialize the LCD and also the ADC.


CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
Analog channel select bit which is use to select the analog port we are using. In this case we are using the RA0. By referring to the datasheet, RA0 is on the CHS<2:0> = 000;.

for(i=0 ; i<10 ; i++)
adc_value = adc_value + ui_adc_read();
In this case, the value of ADC have been taken and add together for 10 times.

adc_value = adc_value/10;
After the adc_value is been added by 10 times. It must be divided by 10 to get the average value. The purpose of this is to get more accurate value.

Convert the ADC output value in BCD and display it in LCD. In here, we have limit it to display maximum 4 digit only.

volt_value = (adc_value*50)/102.4;
To display the voltage of the analog. We have to convert the digital value in the output of the ADC by applying the formula.
E.g. : If adc_value is 1022 (decimal)
1022*50 = 51100.
51100/102.4 = 499(volt_value)


Display the joystick X-axis adc value which is from 0 to 1022.

Display the joystick Y-axis adc value which is from 0 to 1022.

Check if the push button on joystick is press. If press then display (“0”). If not press then display (“1”).

Back to Project 3                                                                                                          Go to Project 5



1.P4 User Manual.pdf


Related Posts

Leave a comment