Variable pot

Hi again guys.

the following code, displays a value of the potentiometer relative to the value before, I.e it tells the the change in the potentiometer, (well its supposed to)

the probelm is sometimes it updates and i am satisfied, and other times it doesnt update satisfactorily, and i am suspicious enough of my coding to believe its not correct.

while(1)
{

// A variable to store our converted analog value in:
int pot;

// Initialize the ADC:
analog_init();

// The endless loop
for(;;)
{
// Store the value of our analog input:
pot = analog10(7);

if (pot > analog10(7))
{
number = number + (pot-analog10(7));
					
}
else if (pot < analog10(7))
{
number = number - (analog10(7)-pot);
					
}
else
{
number = number;
}
lcd_line1();
           			lcd_string("number");
         			lcd_line2();
           			lcd_int(number);


}

}

I want it to update so that it is very quick to tell you the value.
What i am leading to is trying to duplicate the ipods navigating songs device - not enough to suspect copyrighting breach, dont worry.

I want it to display a different number on the screen depending on where its has got to in a list.
(the numbers being the numbers on a roulette wheel - in order:
I.e

const unsigned char single_zero_wheel[37]={0,32,15,19,4,21,2,25,17,34,6,
                                 27,13,36,11,30,8,23,10,5,24,
                                 16,33,1,20,14,31,9,22,18,29,
                                 7,28,12,35,3,26};

if (number = 25) /*number - the variable from code above */
{
lcd_line2();
           			lcd_int(char single_zero_wheel[24]);
}

then as the pot is changed, the number that appears on line 2 of the screen updates accordingly.

I’ve definately got the jist, and think i’m basically there, but dont trust my own coding!!!

The essence of your code is the following:

for(;;)
{
  pot = analog10(7);
  print out difference between pot and analog10(7)
}

The problem with this approach should be clear: you are giving the potentiometer almost no time to change between when you make your first reading and your second reading and you’re losing any potentiometer changes that happen between the last reading of one loop and the first reading of the next. When you’re dealing with an accumulation of changes, you need to be exceedingly careful not to lose readings, otherwise errors will just build over time. I recommend that you deal with the value in question itself as much as possible rather than rate of change of that value.

For example, why don’t you just use the potentiometer position to determine which array value to display? What do you gain by looking at the change in potentiometer position?

const unsigned char single_zero_wheel[37]={0,32,15,19,4,21,2,25,17,34,6,
                                 27,13,36,11,30,8,23,10,5,24,
                                 16,33,1,20,14,31,9,22,18,29,
                                 7,28,12,35,3,26};
for(;;)
{
  // scale the potentiometer ADC value (0 - 255) to be a number from 0 - 36
  unsigned char pot_idx = (unsigned char)(analog10(7) * 36 / 255);
  lcd_clear();
  lcd_line2();
  lcd_int(char single_zero_wheel[pot_idx]);
  _delay_ms(25);
}

Or am I not understanding how you want this to work?

- Ben

No no Ben, that is a much better way of doing it, i knew that my coding was not to be trusted…

THe only thing is though, as far as i can tell it shouldnt output a number above 36, and as the pot is turned the numbers should change in the order they are in the array. The only thing is i am getting numbers over 36 - I have seen upto 255, and from your code a couple of things didnt compile as you had written, I changed them to what i knew would compile, but am not sure whether it would have had a big effect.

In my code right at the top I have declared the constant array, then there is the load of stuff initializing the ADC, thn there is my main function with a small bit about the LCD and then this while loop:

while(1)
		{



// Initialize the ADC:
		analog_init();



// The endless loop
			for(;;)
			{


				// scale the potentiometer ADC value (0 - 255) to be a number from 0 - 36
  				unsigned char pot_idx = (unsigned char)(analog10(7) * 36 / 255);
  				
  				lcd_line2();
  				lcd_int(single_zero_wheel[pot_idx]);
 				 _delay_ms(25);

			}
		return 1;


		}

Which includes your code. I had to take the char out of the line lcd_int(char single_zero_wheel[pot_idx]);
because it would compile, or didnt like it there. WOuld that have had much effect, I’ve never seen it in there before. ANd the second thing I was worried about was on the line:

unsigned char pot_idx = (unsigned char)(analog10(7) * 36 / 255);

should it be multiplying by (unsigned char)? I wasnt sure what value this would take and could be the factor that is giving me high numbers…

I made two mistakes, one of which you caught:

lcd_int(char single_zero_wheel[pot_idx]);

should be:

lcd_int(single_zero_wheel[pot_idx]);

The other mistake was my calling analog10(7) instead of analog8(7). The former returns a number from 0 to 1023 while the latter returns a number from 0 to 255.

My line:

unsigned char pot_idx = (unsigned char)(analog10(7) * 36 / 255);

Is taking a number from 0 to 1023, multiplying it by 36, and dividing it by 255. If we ignore overflow issues, the result is a number between 0 and 144, which is definitely not what we want. Since we’re trying to obtain an index for our array, we want to scale the potentiometer output to be a number between 0 and 36. By using numbers greater than 36 as the index to our array, we’re essentially reading and displaying random values from RAM, which is why you were seeing junk on the display for 75% of the potentiometer positions. This can be fixed by:

unsigned char pot_idx = (unsigned char)(analog8(7) * 36 / 255);

In this line I am not multiplying by (unsigned char). What I am doing is known as “type casting”. I’m converting the integer (two-byte) result of the mathematical operation to an unsigned char (a single byte). In this case the type casting is not explicitly necessary as the compiler will know to do it automatically, but in general it’s good practice to be aware of what types will result from the operations you use. This way you can avoid unwanted overflows. Does this make sense? More importantly, does this code do what you want?

- Ben

Thanks Ben, yeah that does make sense.