## Notes on using Cortex A/D for discrete inputs

Revised: 12/13/2010

Ok, I admit it, I was so used to using the PIC 5v processor , that I assumed that the 5v pull-up resistor would give a digital 4096 (12 bit max value)  reading with an open pin (no connection).     The cortex, however, only outputs around 250 counts .    This is understandable when you examine the  following interface facts:

1) the cortex is a 3.3 v ARM processor

2) there is 470k pull up resistor connected between the input pin and a 5v supply

3)there is a 20k pull down resistor connected between the A/D input and ground.

4) there is a series input resistor of 10k connected between the input pin and the A/D input.

So with no input, we would expect a digital value of     5v*(20k)/(470k+20k + 10k) *4096/3.3v=248 . This is just ohms law applied to series resistors working as a voltage divider.  This is indeed close to what I see using the debug with a  potentiometer sensor type.

With a plug shorting the input to ground ,  the debug shows a digital value of 5 .   This should be zero in a perfect world since the  input to the 10k series resistor is  now grounded and the 470k cannot pull up the potential since it too has been grounded.

If you want to use an A/D as a discrete input port connected to a touch sensor or plug then the RobotC logic should  use the following code:

bool b_input = SensorValue(pot) < 125; // Reads true when plug in or sw closed

I would like RobotC  to offer the option to connect a touch sensor to an A/D.  But right now only the POTENTIOMETER is appropriate.

Using a pot input to generate discrete states for selecting autonomous scripts.

A simple equation that uses modulo arithmetic can be used to generate an integer number of inputs.

Let  max_no_inputs and script_number  be integers.

then

script_number =( SensorValue[pot]*max_no_inputs)/4096 + 1;

script_number will run from 1 to max_no_inputs based upon the pot setting.  Here we are making use of the integer division truncation to generate an integer output.  We just have to add a pointer and some division marks on the pot to indicate what area of the pot we are in.  In the past I have use a 12 tooth gear filed to a point and glued a dial to the pot face.

Using plugs to create digital states:

Suppose we want four states:  1, 2, 3 , 4

This requires two boolean inputs generated from two A/D ports  plug1 and plug2.

b1 = SensorValue(plug1)<125   and b2 = SensorValue(plug2)<125

Now we can map these states to integers in two ways:

1) If statements

if(!b1 && !b2)  { script_no = 1;}   // no plugs in

else if(b1 && !b2)  {script_no = 2;} // plug1 in , plug2 out

else if(!b1 && b2) { script_no = 3;} // plug2 in , plug1 out

else   {script_no = 4;}  // both plug1 and plug2 in

int script_no =  1*b1 + 2*b2  + 1  ;

If we add another plug3 to get b3 then we can get 8 states;

int script_no =  1*b1 + 2*b2  + 4*b3 + 1  ;

Pot Nonlinearity note:

The counts are not linear with pot rotation due to the fact that the series and pull-down resistors are about the same magnitude of the Vex potentiometer (10k) and they load the pot down.  One can derive the formula for the exact counts using circuit theory.   If you ignore the 470k pull-up resistor (it has negligible current draw when a pot is present) then the counts are given by

counts = 4096*5/3.3*( p*2)/((1-p)*(p+ 3) + 3*p)  where p is the pot ratio [0 to 1]

If p = 1 ( pot outputs 5 volts)    counts = 4096*10/9.9  or about full value

If p= 0 (pot outputs 0 volts)   counts =  0

if p = .5     counts = 4096* 5/3.3*1/3.25= 4096*( .466)

The .466 would be .5 if the pot wasn’t loaded down.  So it is about a 6% error.     Correction software could use the inverse of the above counts eq and solve for p given counts.  This would be the real ratio for a given count.