-
How to adjust values to a new range
I have 10-bit ADC reading with a usable range of 400 - 930.
How can I adjust that value to create a range of 100 to 230?
I've been dividing the ADC by 4 to get a PWM of 0 to 255, but all PWM values below 100 are useless, and values above 235 will shorten the life of a LCD.
I'm at my wits end after 2 days. :confused:
-
1 Attachment(s)
Re: How to adjust values to a new range
pbp has a max and a min commands
by combining max and min you can constrain a variable to a
range of values
Attachment 9709
-
Re: How to adjust values to a new range
But that will still leave a dead space at the beginning and end of the pot. I need to convert on the fly a value from 400-900 to 100-235.
There has to be a formula to do this. I never got far in algebra in school. I don't even know what to use as a search string in google.
-
Re: How to adjust values to a new range
The concept of mapping a range should be clear by this code example in C explained
// map a value(inputlow to inputhigh) to the range(outputlow to outputhigh)
Code:
int16 map(int16 val, int16 inpl, int16 inph, int16 outl, int16 outh){
int32 tmp=MAX(val,inpl)-inpl; // tmp = (maximum of Val and inputlow) - inputlow
tmp *= (outh-outl); // tmp = tmp * (outputhigh - outputlow)
tmp /= (inph-inpl); // tmp = tmp / (inputhigh - inputlow)
tmp += outl; // tmp = tmp + outputlow
return MIN(tmp,outh); // return the lower of tmp or outputhigh
}
-
1 Attachment(s)
Re: How to adjust values to a new range
I just realized I didn't express myself properly.
As I turn the pot, the formula should convert from 0 all the way to 1023, to a new range of 100 to 235.
Or else I have that dead spot under 400 and above 900.
Attachment 9711
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
Jerson
... tmp = (maximum of Val and inputlow) - inputlow...
I'm puzzled by what is Maximum of Val? Is that the actual ADC input?
EDIT: Oh, I get it, it's the maximum value between the input (ADC in) and InputLow (400).
-
1 Attachment(s)
Re: How to adjust values to a new range
Freaking awesome!
:D
Attachment 9712
-
Re: How to adjust values to a new range
Aaaaaaaannnd I'm screwed.
I go over 65,025 and I'm barely 1/2 to 1023 ADC input, that puts me over the WORD limit. I looked at the compiler options in MCSP and it says PBPL is for 18F only, I'm using a 16F1937 for this project.
I don't know what my options are at this point...
:confused:
EDIT: Hmmm, what if I divide my input by 4, and adjust my input range accordingly...
EDIT SOME MORE: WOOOT! It works freaking awesome! Thanks Jerson!
-
Re: How to adjust values to a new range
Since you have done it in PBP and if you don't mind, could you post the code you tested please?
Maybe there is a way to overcome the Long need using functions of 32 bit like DIV32?
Ioannis
P.S. Test it in Excel and I think there is a mistake on the B3 function. My output result on B13 is always equal to B11.
-
Re: How to adjust values to a new range
There is a mistake on B13, it should be MIN(B12;B7)
Ioannis
-
Re: How to adjust values to a new range
Quote:
As I turn the pot, the formula should convert from 0 all the way to 1023, to a new range of 100 to 235
Code:
OutputValue = 100 + (InputValue */ 34)
-
Re: How to adjust values to a new range
Many ways to skin a cat but Henriks is the best!
Fast and simple!
Ioannis
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
Ioannis
Since you have done it in PBP and if you don't mind, could you post the code you tested please?
Maybe there is a way to overcome the Long need using functions of 32 bit like DIV32?
Ioannis
P.S. Test it in Excel and I think there is a mistake on the B3 function. My output result on B13 is always equal to B11.
I divided by 4 first, then ran it through the formula. ;)
"EDIT: Hmmm, what if I divide my input by 4, and adjust my input range accordingly..."
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
Ioannis
There is a mistake on B13, it should be MIN(B12;B7)
Ioannis
Good eye. :o
I had corrected the formula in B13, but had somehow missed the text in C13 (it's just text to show what goes on in the real cells in B column).
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
HenrikOlsson
Code:
OutputValue = 100 + (InputValue */ 34)
That's awesome Henrik. It works like a charm.
Can you explain how you got 34? It's not jumping out at me.
"A simple way to think about '*/' is that it shifts the result 8 places to the right,
resulting in an automatic division by 256."
I'm just not sure how you went about figuring that out.
I'd like to convert 34 into a formula for future use when I have to use a different range (cause I'm sure to have that need - several Flight Sim variables use pots and have their own range of values).
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
Ioannis
Since you have done it in PBP and if you don't mind, could you post the code you tested please? ....
Sure thing:
Code:
ADCinput var WORD
ADCcalc var WORD
ADCinLow con 0
ADCinHigh con 255
ADCoutLow con 100
ADCoutHigh con 235
ADCcalc = ADCinput / 4 ' reduce to 0-255 to avoid WORD overflow
ADCcalc = (ADCcalc MAX ADCinlow) - adcinlow ' adjust 0 - 255 range
ADCcalc = ADCcalc * (ADCouthigh - adcoutlow)' to 100 - 235 range
ADCcalc = ADCcalc / (adcinhigh - adcinlow)
ADCcalc = ADCcalc + ADCoutlow
ADCcontrast = ADCcalc MIN ADCouthigh
I just kept things simple and did things one step at a time, just like Jerson explained it. And women say men can't follow instructions. :D
I know I can shrink this, but I'm just researching all the different bits of code I will need first, and documenting with comments what the code does and why.
-
Re: How to adjust values to a new range
This has been covered many many times on the forum so why not one more time...
Basically we want multiply the ADC value by 135/1023=0.132 so in comes the */ operator.... 0.132*256=34 (rounded up).
1023*34/256=135
512*34/256=68
128*34/256=17
When the value you want to multiply by is <1 you can get more precision with the ** operator (same thing but inherent division by 65536). In this case it doesn't matter though because the output value range is so small.
Do note that there's no expensive division going on here, all it does is discard the bottom 8 bits (in the case of */) of the multiplication.
/Henrik.
-
Re: How to adjust values to a new range
If for any reason the input may have a value over 1023 then there would be a problem with the simple equation. But since the that value comes from a specific 10 bits ADC module it defines the upper limit of 1023.
If you want to use it in other cases, a MIN/MAX would be needed.
In any case Henrik's solution is neat and fast.
Ioannis
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
HenrikOlsson
This has been covered many many times on the forum so why not one more time...
You've explained it, using my own problem as example, and I still don't completely understand it. My eyes sort of gloss over when I've read these explanations on the forum. And it's not getting better as I get older. :(
I really do appreciate you holding my hand while you pound this into my skull. :D
-
Re: How to adjust values to a new range
Allright...
[1] I believe you're with me for the 135/1023=0.132 part, right?
[2] IF the description for the */ operator WOULD have said "....resulting in an automatic division by 1000" then I think you'd see that the solultion WOULD be OutputValue = 100 + (InputValue */ 132), because 0.132*1000=132, correct?
[3] But since the */ operator "....resulting in an automatic division by 256" we must multiply 0.132 by 256 instead of 1000. Hence the value 34.
Makes sense? If not, which step?
-
Re: How to adjust values to a new range
I follow. I just could not have thought of this by myself.
-
Re: How to adjust values to a new range
Or maybe use a formula
X=135*256/1023
where X is the number you wan to use in the */
135 is the max scale value
1023 is the max ADC value
Ioannis
-
Re: How to adjust values to a new range
-
Re: How to adjust values to a new range
Quote:
Originally Posted by
amgen
not to beat this up too much........
A horse is never too dead on the web. :D
Quote:
Originally Posted by
amgen
... if you only need 135 output values, and you want to scale pot for 0 to 100%..... just use the top 8 bit from a/d and this trend line function that excel gave.
I can't believe I was playing with excel all that time and never thought of using the chart feature.
-
Re: How to adjust values to a new range
My ADC is only 10 bits, not 16.
So I just divide 10bits by 4 to reduce from 1023 down to 255, then slap it through your formula.
I haven't done any math yet (just thinking, while I work on my encoder logic), but this probably equates to what Ioannis is suggesting.
:)
-
Re: How to adjust values to a new range
deleted because I realized the formula excel created was not correct...... me bad
-
Re: How to adjust values to a new range
ok, so the a/d has setting to shift bits so you can take the high byte only as the MSB, same as /4 ...... then the formula is (53 X reading)/100 + 100................ for ....0 to 255=100 to 235