pot controled 7 segment display

i have downloaded a sketch which is a 2 seven segment display and 2 shifregisters (74HC595) which will count from 0 to 99 and it repeats i want to add a pot meter 10K to A0 pin so that the counter should count from 0 to 99 when i turn the pot from start to end (0-180 Digree)
i am posting my sketch so some one can help me

_working_7_segment_display_software_21_9_2015.ino (683 Bytes)

Please post the code here in a post for the convenience of everyone. Make sure that you use code tags when you do using the </> icon at the left of the icons above the editor window. Using the tags makes the code easier to read and deal with here.

You need to split the number into two digits:

int number = map(analogRead(A0), 0, 1023, 0, 99);
i = number / 10;
j = number % 10;

Why does anyone ever even use map(), anyway?

odometer:
Why does anyone ever even use map(), anyway?

Because reliable integer scaling is hard for beginners.

aarg:
Because reliable integer scaling is hard for beginners.

Reliable integer scaling using "map()" is much harder than any other way to do it.

Take the example posted in this thread:

int number = map(analogRead(A0), 0, 1023, 0, 99);

When mapping 1024 different input values to 100 different output values, I'd think that each 10 (or possibly 11 in some cases) input values map to one output value.

But what happens when map is used like shown above?

ONLY the input value 1023 maps to output value 99.
So at the end of the range: a single input value maps to a single output value.
In the range below 1023, it's 10 or 11 different input values mapping to a single output value.

Such strange mapping happening at the end of the range is what I name "weird" and not "reliable".

aarg:
Because reliable integer scaling is hard for beginners.

int number = (analogRead(A0) * 99) / 1023;

or better yet:

int number = (analogRead(A0) * 100) / 1024;

Actually, if they really want to be beginner friendly, why not have a built-in function like this one?

long scaledAnalogRead(int pin, long top) {
  return ((analogRead(pin) * (top + 1L)) >> 10);
}

odometer:

int number = (analogRead(A0) * 99) / 1023;

or better yet:

int number = (analogRead(A0) * 100) / 1024;

Nothing better, that code creates integer overflows in the multiplication when analogRead(A0) rises above certain values.

You have at least to use "long" calculations to avoid integer overflow:

int number = (analogRead(A0) * 99L) / 1023;

or better yet:

int number = (analogRead(A0) * 100L) / 1024;

jurs:
Nothing better, that code creates integer overflows in the multiplication when analogRead(A0) rises above certain values.

Derp! My bad!

Still, L is two letters shorter than map.

odometer:
Still, L is two letters shorter than map.

I really like the idea behind this code, as suggested by you:

return ((analogRead(pin) * (top + 1L)) >> 10);

The advantage is fast code execution.

Every division is very, very slow on 8-bit Atmegas, that have absolutely no hardware support for division (while hardware multiplication is relatively fast).

But that code just uses bit shifting instead of dividing, so it is very, very fast.
(Estimated more than 5 times faster than "map()" or other solutions that actually do a division)

On the other side: As "analogRead()" is already a slow function that takes more than 100µs, it possibly doesn't matter whether the scaling adds up 5µs or less than 1µs for scaling the value after reading it.

jurs:
I really like the idea behind this code, as suggested by you:

return ((analogRead(pin) * (top + 1L)) >> 10);

The advantage is fast code execution.

Every division is very, very slow on 8-bit Atmegas, that have absolutely no hardware support for division (while hardware multiplication is relatively fast).

But that code just uses bit shifting instead of dividing, so it is very, very fast.
(Estimated more than 5 times faster than "map()" or other solutions that actually do a division)

On the other side: As "analogRead()" is already a slow function that takes more than 100µs, it possibly doesn't matter whether the scaling adds up 5µs or less than 1µs for scaling the value after reading it.

How long does it take to divide two longs?

odometer:
How long does it take to divide two longs?

I think the time needed is not a fixed value, but the time for a division actually depends on dividend and divisor, as dividing in software is done in an interation.

Doing a division on Atmega controllers is slow

But on the other side, if the divisor is

  • a constant value and
  • a power of 2, such like 2, 4, 8, 16, …, 512, 1024 and so on
    then GCC compiler wil actually not create an division even if you write code for a division, but the compiler does in fact a fast bitshifting operation instead.

So this function:

int mapDownADCfast(int value, int maxValue)
// a very fast function for mapping value range down
{
  return value* (maxValue+1L) / 1024; // dividing by power of 2 is actually bitshifting
}

is using bitshifting and therefore much faster than that function:

int mapDownADCslow(int value, int maxValue)
// a relatively slow function for mapping value range down
{
  return value* (long)maxValue / 1023; // slower because of a division
}

which is doing a division.

I have done a small benchmark sketch if anybody likes to test the functions mapDownADCfast(), mapDownADCslow() and map() against each other.

The results of mapDownADCslow() are compatible to the map down results of the map() function, as well as the execution is slow.

The results of mapDownADCfast() are evenly distributed over the complete range of input values.

This benchmark sketch does:

  • a benchmark test of one mapping function and measures time for executing 1024 function calls
  • then prints mapping results of all three functions to Serial over the whole range
// benchmark for testing different mapping functions
// set BENCHMARK to 1 or 2 or 3 for testing different functions
#define BENCHMARK 1  // allowed are BENCHMARK 1 or 2 or 3

int mapDownADCfast(int value, int maxValue)
// a very fast function for mapping value range down
{
  return value* (maxValue+1L) / 1024; // dividing by power of 2 is actually bitshifting
}

int mapDownADCslow(int value, int maxValue)
// a relatively slow function for mapping value range down, compatible results with map()
{
  return value* (long)maxValue / 1023; // slower because of a division
}


void setup() {
  Serial.begin(115200);
  unsigned long time=micros();
  long x=0;
  for (int i=0;i<1024;i++)
  {
#if (BENCHMARK==1)
    x+= mapDownADCfast(i, 99);
#elif (BENCHMARK==2)
    x+= mapDownADCslow(i, 99);
#elif  (BENCHMARK==3)
    x+= map(i, 0,1023,0,99);
#else
  BENCHMARK_NOT_DEFINED
#endif  
  }
  Serial.print("x= ");Serial.println(x);
  Serial.print("time microseconds= ");Serial.println(micros()-time);
  Serial.println();
  Serial.println("Comparison of all 3 functions:");
  Serial.println("value\tfast\tslow\tmap()");
  for (int i=0;i<1024;i++)
  {
    Serial.print(i);Serial.print('\t');
    Serial.print(mapDownADCfast(i, 99));Serial.print('\t');
    Serial.print(mapDownADCslow(i, 99));Serial.print('\t');
    Serial.print(map(i, 0,1023,0,99));Serial.println();
  }  
}

void loop() {
}

Results of map() and mapDownADCslow() are the same: Weird at the end of the range. Only the last input value is mapped to the last output value. The mapping with these functions is distorted at the end of the range.

But results of mapDownADCfast() function are evenly distributed across the whole range of input values and executes fast.

My benchmark result using an Arduino UNO for testing the whole range 0…1023 is:

mapDownADCfast() ==> 6180 µs
mapDownADCslow() ==> 40648 µs
map() ==> 55200 µs

thomasmv:
i have downloaded a sketch which is a 2 seven segment display and 2 shifregisters (74HC595) which will count from 0 to 99 and it repeats i want to add a pot meter 10K to A0 pin so that the counter should count from 0 to 99 when i turn the pot from start to end (0-180 Digree)
i am posting my sketch so some one can help me

#define LATCH 8
#define CLK 12
#define DATA 11

//This is the hex value of each number stored in an array by index num
byte digitOne[11]= {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x83,0xF8,0x80,0x98,0x7F,}; 
byte digitTwo[12]= {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x83,0xF8,0x80,0x98,0x7F,};



void setup(){
 
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
 
}

void loop(){
 int i,j;
  for(int i=0; i<10; i++){
    //for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[i]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[j]); // digitOne
      digitalWrite(LATCH, HIGH);
      delay(1000);
    }
  }
//}

Why do you need two identical arrays? You can use the same array for more than one line of code.

Have you tried anything? Can you read the pot? These guys have given you several options for how to map that value to a 2 digit number. Try it out and let us know how it goes and we will help you get it right.