Log in

View Full Version : Potentiometer with ADC


DustinB_3
10-01-2007, 19:44
I've searched chiefdelphi and didn't come up with anything. But, how would I go about coding a potentiometer with the ADC. I am quite new to using both the potentiometer and the encoder. Help is much appreciated.

Bongle
10-01-2007, 19:56
It's pretty simple. Wire the potentiometer to a PWM cable (I forget how to do this since I didn't do it), and plug it into one of the appropriate RC inputs. I'm fairly sure that the white cable of the PWM cable is the signal line, while the red and black ones are positive and ground. Once it is set up, it should simply be the potentiometer with the PWM cable hanging off it. There is no need for additional wires or power.

Once you've done that, you can access whatever values it is reading with the function Get_Analog_Value(int whichInput).

For example, our potentiometer in the 2006 robot, we did:

curPotentReading = Get_Analog_Value(rc_ana_in03)


If I remember correctly, the returned value will be between 0 and 1024, since it is a 10-bit ADC.

DustinB_3
10-01-2007, 22:33
Thanks for the reply but I am not sure that that would work because you have to comment out Set_Number_of_Analog_Channels(SIXTEEN_ANALOG); in order to get the adc to work correctly

Bongle
10-01-2007, 22:38
Thanks for the reply but I am not sure that that would work because you have to comment out Set_Number_of_Analog_Channels(SIXTEEN_ANALOG); in order to get the adc to work correctly

I just checked our 2006 code which had a flawlessly working potentiometer, and we still had that line of code.

Here's our whole User_Init. Aside from the commented-out line for the shooter switch, I think it is unmodified from the given code.
void User_Initialization (void)
{
Set_Number_of_Analog_Channels(SIXTEEN_ANALOG); /* DO NOT CHANGE! */
// shooter_switch=1;
/* FIRST: Set up the I/O pins you want to use as digital INPUTS. */
digital_io_01 = digital_io_02 = digital_io_03 = digital_io_04 = INPUT;
digital_io_05 = digital_io_06 = digital_io_07 = digital_io_08 = INPUT;
digital_io_09 = digital_io_10 = digital_io_11 = digital_io_12 = INPUT;
digital_io_13 = digital_io_14 = digital_io_15 = digital_io_16 = INPUT;
digital_io_18 = INPUT; /* Used for pneumatic pressure switch. */
/*
Note: digital_io_01 = digital_io_02 = ... digital_io_04 = INPUT;
is the same as the following:

digital_io_01 = INPUT;
digital_io_02 = INPUT;
...
digital_io_04 = INPUT;
*/

/* SECOND: Set up the I/O pins you want to use as digital OUTPUTS. */
digital_io_17 = OUTPUT; /* Example - Not used in Default Code. */

/* THIRD: Initialize the values on the digital outputs. */
rc_dig_out17 = 0;

/* FOURTH: Set your initial PWM values. Neutral is 127. */
pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;

/* FIFTH: Set your PWM output types for PWM OUTPUTS 13-16.
/* Choose from these parameters for PWM 13-16 respectively: */
/* IFI_PWM - Standard IFI PWM output generated with Generate_Pwms(...) */
/* USER_CCP - User can use PWM pin as digital I/O or CCP pin. */
Setup_PWM_Output_Type(IFI_PWM,IFI_PWM,IFI_PWM,IFI_ PWM);

/*
Example: The following would generate a 40KHz PWM with a 50% duty cycle on the CCP2 pin:

CCP2CON = 0x3C;
PR2 = 0xF9;
CCPR2L = 0x7F;
T2CON = 0;
T2CONbits.TMR2ON = 1;

Setup_PWM_Output_Type(USER_CCP,IFI_PWM,IFI_PWM,IFI _PWM);
*/

/* Add any other initialization code here. */

Init_Serial_Port_One();
Init_Serial_Port_Two();

#ifdef TERMINAL_SERIAL_PORT_1
stdout_serial_port = SERIAL_PORT_ONE;
#endif

#ifdef TERMINAL_SERIAL_PORT_2
stdout_serial_port = SERIAL_PORT_TWO;
#endif

Putdata(&txdata); /* DO NOT CHANGE! */

// *** IFI Code Starts Here***
//
// Serial_Driver_Initialize();
//
// printf("IFI 2006 User Processor Initialized ...\r"); /* Optional - Print initialization message. */

User_Proc_Is_Ready(); /* DO NOT CHANGE! - last line of User_Initialization */
}

EHaskins
11-01-2007, 00:04
DustinB_3 you must be using Kevin's code. If you are you just follow the instructions to integrate his code into yours, or use his complete project.

Then to get the value you call Get_ADC_Result(unsigned char port#).

The following code would get the value from analog input 1.

int position = Get_ADC_Result(1);


Hope this helps.

DustinB_3
11-01-2007, 08:21
Thanks for the help. That was exactly what I was looking for.

stevethetinker
30-01-2007, 12:41
Does anyone know what resistance potentiometer to use?

Alan Anderson
30-01-2007, 12:56
Anything from 2k to 100k ought to work. Higher resistances will be slightly more susceptible to noise. We've used 10k with good results.

Danny Diaz
30-01-2007, 13:26
Does anyone know what resistance potentiometer to use?

This year we're using 5k ohm pots with great success.

-Danny

Shinigami2057
03-02-2007, 17:10
I have a dumb question - I Just hooked up a 100K pot to analog input 01, but Get_Analog_Value(rc_ana_in01) is only returning values from 0-9, and it definitely is not linear. This is the (very simple) code we're using just to test:


printf("%u\n", Get_Analog_Value(rc_ana_in01));


Am I missing something important here? Is there something wrong with the pot? (It's wired correctly)

Thanks

Ken Streeter
04-02-2007, 08:05
I have a dumb question - I Just hooked up a 100K pot to analog input 01, but Get_Analog_Value(rc_ana_in01) is only returning values from 0-9, and it definitely is not linear. This is the (very simple) code we're using just to test:


printf("%u\n", Get_Analog_Value(rc_ana_in01));


Am I missing something important here? Is there something wrong with the pot? (It's wired correctly)

Thanks

The problem is that Get_Analog_Value returns a 10-bit value, rather than an 8-bit value. In general, we discarded the lowest 2 bits of the potentiometer value as "noise" and just used the top 8 bits via the following code:


int Get_Robot_Pot(void) {
unsigned char robot_pot_8bits;

// analog inputs on the robot are returned as 10 bit values, the line below
// drops off the bottom two bits to give a one-byte value for the elevation
robot_pot_8bits = (unsigned char) (Get_Analog_Value( rc_ana_in01 ) >> 2);
printf("Pot Value: %3d\r\n", (int) robot_pot_8bits);
return ((int) robot_pot_8bits);
}

Shinigami2057
04-02-2007, 13:39
How is that a problem when analog inputs return an unsigned int (16-bits on the PIC18, more than enough for the 10-bit ADC conversion)? I'm assuming %d is expecting an int, so it should be fine. Even if the compiler was lopping of the 2 MSbs of the result, it should still return a value from 0-255.

Thanks for the help, though. We're going to try some new linear taper 10k/50k pots tomorrow. We really weren't sure exactly what kind of pots the old ones were, only that they were 100k ohm.

Alan Anderson
04-02-2007, 13:54
Is there something wrong with the pot? (It's wired correctly)

Define "correctly".

Use a voltmeter to look at the signal (white) wire. It should vary from 0 volts to 5 volts as you turn the pot. If it only gets up to a few millivolts, it's possible that you have the ground and wiper connections swapped.

Shinigami2057
04-02-2007, 14:19
I'll definitely check that, thank you. We currently have the pot wired so that the signal wire is in the center, which I assumed to be the wiper based on a previous topic here. Do all pots use the center connection for the wiper?

Alan Anderson
04-02-2007, 15:04
Do all pots use the center connection for the wiper?
That's true of all of the generic single-turn pots I'm familiar with. However, the five- and ten-turn pots are different, with the wiper at one end and a little offset from the other two connections. The linear "slide" pots don't seem to have a consistent pattern.