0

I am reading values from a potentiometer that I can rotate to produce a range of numbers from 0-1023. I want to be able to display these numbers in terms of a horizontal bar graph on an LCD screen. The LCD screen is 20 blocks wide so the 0-1023 must be scaled down to 0-20. The character I want to use to produce the bar graph is a block that fills one entire block out of the 20 available. The bit pattern for this block is 0b11110001.

   block = 0b11110001; 
   BarGraph = ((DELVAL2/5115)*2000);

   lcd_putxy(2,0,buf);
   for (delay = 0; delay < 50000; delay++);      // introduce a delay 

   sprintf(buf, "*", BarGraph); 
   lcd_putxy(2,0,buf);

I was hoping somebody could explain to me how to achieve this and the best method for scaling down my potentiometer values.

user_1
  • 45
  • 1
  • 3
  • 8
  • 2
    Did you not like the answers to your similar recent [previous question](http://stackoverflow.com/questions/41148145/how-to-scale-a-number-range-of-numbers-in-c)? I would like to close this question as a **duplicate**. – Weather Vane Dec 14 '16 at 18:32
  • There were days where programming was taken/tought as applied mathematics. – alk Dec 14 '16 at 18:37
  • The second part to my last question is unanswered. Apologies for the repost. @WeatherVane – user_1 Dec 14 '16 at 18:38
  • 1
    Scaling the range `0..1023` to `0..19` is trivial. Then print `N` blocks on the line followed by `20 - N` spaces. – Weather Vane Dec 14 '16 at 18:40
  • You want to double check, whether your use-case requires the 0 to be handled exclusively. Will say if you want to have the LCD show *something* for *any* value >0. Which would require scaling 1-1023 to 0-19 or 1-20 (depending how you index the 20 elements). – alk Dec 14 '16 at 18:41
  • Don't quite get what you're asking. We can reduce 0-1023 to 0-19 via (x * 20)/1024. You need to watch for overflow. – Malcolm McLean Dec 14 '16 at 20:49
  • @MalcolmMcLean (x*5)/256 and no chance of overflow on any compliant C Platform. – Persixty Dec 14 '16 at 21:25
  • Possible duplicate of [How to scale a number/range of numbers in c](https://stackoverflow.com/questions/41148145/how-to-scale-a-number-range-of-numbers-in-c) – Armali Oct 10 '18 at 11:43

2 Answers2

1

Your calculation has mistake

 BarGraph = ((DELVAL2/5115)*2000);

DELVAL2 is 0-1023. You divide it by 5115, so you get value between 0 and 1. It's probably casted to 0. 0 Mutliplied by 2000 is still 0.

Try first multiply, then divide:

BarGraph = (DELVAL2*2000/5115);

Also for printing

 sprintf(buf, "*", BarGraph); 

will not work. Refer to sprintf function or simple use loop for putting symbol in buf array.

Mazi
  • 182
  • 8
  • And, in general, you should always reduce your constant ratios to avoid unnecessary overflows during multiplication. So, 2000/5115 => 400/1023. – tonypdmtr Dec 15 '16 at 13:51
0

All you need to do is take the full range of the ADC and divide it by the number of LCD Characters (1024 / 20 = 51.2). Round the value up to 52 to include all possible values in the ADC Range. This means you have 20 available LCD characters to display a full range of 0 - 1023. Each LCD character will represent 0 to 52 ADC Counts (except the last one due to rounding).

Pseudo Code:

  • First, clear the display for a new update.
  • Check if ADC Counts >= 0 and ADC Counts <= 51: Turn 'ON' LCD Block 0.
  • Else if ADC Counts >= 52 and ADC Counts <=103: Turn 'ON' LCD Block 0 & 1.
  • Else if ADC Counts >=104 and ADC Counts <=155: Turn 'ON' LCD Block 0 & 1 & 2.

You would do this sort of pattern for all of the remaining 17 entries.

Cheers!

Brandon83
  • 206
  • 1
  • 7
  • 1
    Actually, it's much simpler that this: You do ADC_VALUE*20/1023 and you get the number (integer part) of blocks to fill using a simple loop. No need for a long series of IF ... ELSE statements. (Also, note that you need to divide with 1023, not 1024 if you need to absolutely accurate. 1024 may be close enough and easier to deal with if you want to use shifting instead of division but technically it is not quite right. To see why, consider the maximum value read from the 10-bit ADC -- 1023 -- which cancels out with the 1023 in the denominator.) – tonypdmtr Dec 15 '16 at 14:00
  • I agree with the formula provided and the for loop implementation. But you have to remember that a 10-bit ADC provides 1024 values (0 to 1023). This is why I have (1024 / 20) in my post to account for the zero'ith value. The values need to be bucketized into 20 equal segments. I do like your approach much better! – Brandon83 Dec 15 '16 at 14:41