# How to display potentiometer value from dspic33 microcontroller

I am new to the microcontroller world and am using a dsPIC33EP256MC506 controller and dsPICDEM -2 MCLV development board for a project. I am trying to read the value of the potentiometer that is on the dev board, but am having trouble. I just want to be able to run the program and move turn the potentiometer and see the program output the value. I know that I have to use ADC ports somehow to do this, but I'm not exactly sure how to use it. Documentation has not been very helpful on how to do this in the program either. If anyone can direct me to documentation that uses ADC to control the potentiometer or help me get started with this that would be great.

Also, does anyone know where this value will be displayed? It makes sense to me that it would be displayed in the Variables output tab, but no values seem to be populating for any variable.

Microcontroller: dsPIC33EP256MC506

Development Board: dsPICDEM -2 MCLV

Programmer/Debugger: REAL ICE

Compiler: MPLAB X - XC16

Thanks again!

#include <p33Exxxx.h>
/****************************CONFIGURATION****************************/

_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & POSCMD_XT & OSCIOFNC_OFF & IOL1WAY_OFF);
_FWDT(FWDTEN_OFF);
_FPOR(ALTI2C1_ON & ALTI2C2_ON);
_FICD(ICS_PGD1 & JTAGEN_OFF);

void Delay_us(unsigned int);
int  main(void)
{
// Configure the device PLL to obtain 40 MIPS operation. The crystal frequency is 8 MHz.
// Divide 8 MHz by 2, multiply by 40 and divide by 2. This results in Fosc of 80 MHz.
// The CPU clock frequency is Fcy = Fosc/2 = 40 MHz.
PLLFBD = 38;                    /* M  = 40 */
CLKDIVbits.PLLPOST = 0;         /* N1 = 2  */
CLKDIVbits.PLLPRE = 0;          /* N2 = 2  */
OSCTUN = 0;
/* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0x3);
while (_LOCK == 0);             /* Wait for PLL lock at 40 MIPS */
while(1)
{
AD1CON1bits.SAMP = 1;         // Start sampling
Delay_us(10);                 // Wait for sampling time (10 us)
AD1CON1bits.SAMP = 0;         // Start the conversion
while (!AD1CON1bits.DONE);    // Wait for the conversion to complete
}
}
/* Set port configuration */
ANSELA = ANSELB = ANSELC  = ANSELE = 0x0000;
//ANSELBbits.ANSB5 = 1;           // Ensure AN5/RB5 is analog
ANSELBbits.ANSB0 = 1;
ANSELAbits.ANSA0 = 1;

// A0 and B0 are inputs
TRISAbits.TRISA0 = 1;
TRISBbits.TRISB0 = 1;

/* Initialize and enable ADC module */

// 0000 0000 0000 0101
Delay_us(20);
}
void Delay_us(unsigned int delay)
{
for (i = 0; i < delay; i++)
{
__asm__ volatile ("repeat #39");
__asm__ volatile ("nop");
}
}

• The dsPIC documentation breaks down into 3 categories. The data sheet which has all the specifics of the chip. The reference manual which covers the family of processor giving how things function but lacking the specific detail that the data sheet has. There is a reference manual that covers every different module inside. The final is example code that is provided on Microchips website. – vini_i Oct 30 '16 at 2:13

You are not waiting for conversion to complete.

Algorithm for ADC operations is as follows:

1. Initialize ADC and Pin for Analog channel
2. Start the conversion
3. Wait for conversion to complete
4. Read the result buffer when conversion is complete
5. Go to step 3

In your case, you are not waiting or reading the result buffer. Datasheet is helpful enough to understand the registers.

First, you need to sit down and read the documentation. For someone new, the documentation for the A/D may take a couple hours to go over and digest. Realize up front it's going to take some investment of time. Shortcuts just cause you to waste much more time later, as you are seeing.

For the 16 bit chips (dsPIC and PIC 24), there are two parts to the documentation. The details of any peripheral are described in depth in the Family Reference Manual chapter for that peripheral. Go to the product page for the particular part you are using to get the FRM chapter that applies to the particular version of the A/D your chip has. Read that. Completely. No shortcuts.

The datasheet for the part then gives the particular parameters for the A/D that was described generally in the FRM. This includes how many A/Ds the part has, what the minimum time for TAD is, how many and which analog channels are implemented, etc.

Now that you understand the A/D hardware, you think about how to use it within your application. These peripherals are very flexible, so any one implementation will only use a subset of the possible capabilities or modes.

Since you just want to get A/D readings from foreground code on request (not a good long term strategy, but acceptable for a quick demo), set up the A/D to auto-sample after conversion completed. That way you only need to set one bit to get the next reading. To get each reading:

1. Make sure enough time has elapsed since the previous conversion for a sufficiently long sample time.

2. Set the bit to start a new conversion.

3. Wait for the conversion to finish.

4. Read the A/D result.

Don't ever do this:

AD1CON1 = 0x0000;
// 0000 0000 0000 0101