how to change the output range of readadc

Hello
I am trying to learn a few things and I hope someone can help me.
I am doing the seven segment display experiment form the 3rd section of the picaxe manual on page 22. using the 4026b decade counter.
I managed to do it for 1, 2 and 3 numbers (changing the bit variables to word variables to enable the count upto 999).
Then I thought I would try to control and vary the number by using a potentiometer, that worked too.
I can get 0 - 255, (which i expected) but i want to change the range displayed from 0 to 999, or any other range that I might choose.
The problem is I have no idea how to do this. I am sure it must be possible but I cant work it out.
Can someone help me please?
Here is my code, mostly copied from the manual. I am using the 40x2 chip

adcsetup = 0

main: let w1 =w2
readadc a.0, w2

gosub clock
pause 1000
goto main

clock: pulsout c.1,10
if w1 = 0 then endclk
for w3 = 1 to w1
pulsout c.0, 10
next w3

endclk: return

Also is there any other way I can make the count faster? for 2 digits it is ok but 3 is quite slow.
I tried using pwmout to replace pulsout, ant it did work with varying degrees of sucsess, but I was getting from 0 - 732ish on the display for some reason.
My plan is to replace the potentiometer with a sensor to detect rotational speed, or maybe just position.
I have a fairchild qrb1134 IR emitting diode and phototransistor in my box so I wanted to use that.

thanks in advance

Steve
 

hippy

Ex-Staff (retired)
If the counter / display is a 'clear plus increment' affair the best way to get a faster response is to have a single clear and a separate increment signal for each individual digit. Then to display 999 you only have to issue a 'clear' and 9 increments to each digit; 28 pulses in total rather than 1000 pulses.
 

premelec

Senior Member
Perhaps you already have it; READADC10 will give you counts to 1023 rather than 255 [and word variable is required]. As to scaling to any particular range that takes some math with round off etc.
 

Goeytex

Senior Member
There are formulas for "mapping" one range of values to another range of values. Here is one

New_value = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

For ADC mapping or scaling , x is the value returned by ADC input value

Plug in the variable for mapping 0-255 to 0 - 999 and you get:

new_value = (ADC_Val - 0) * ( 999 -0) / (255 - 0) + 0 or
new_value = ADC_val * 999 / 255

We cant multiply by > 257 or there will be an overflow if ADC > 65 ( result > 65535) so we have to improvise.

(999/ 255 = 3.9167)

Cant use decimals either ! Yikes ! What to do?

3.9167 is close to 3.92 so I multiply that by 100 and get 392 ( an integer!) 392 is too large so I divide again by 2 and get 196 ... good (Same as 3.92 * 50)

Now the formula is: ... new_val = ADC_val * 196 / 50

Try it !

EDIT: Using READADC10 will give better granularity/resolution. The same formula / method will work but I will just give you the answer

new_value = ADC_value * 43/44
 
Last edited:
If the counter / display is a 'clear plus increment' affair the best way to get a faster response is to have a single clear and a separate increment signal for each individual digit. Then to display 999 you only have to issue a 'clear' and 9 increments to each digit; 28 pulses in total rather than 1000 pulses.
I see what you mean, yes that would be alot faster but it would mean having to make my program alot more complicated to control the "carry out" and reset times for each individual digit.
with 3 4026b decade counters the digits take care of themselves.
When I have learnt a bit more I will probably give it a try, but for now I will try to keep things simple :)
 
There are formulas for "mapping" one range of values to another range of values. Here is one

New_value = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

For ADC mapping or scaling , x is the value returned by ADC input value

Plug in the variable for mapping 0-255 to 0 - 999 and you get:

new_value = (ADC_Val - 0) * ( 999 -0) / (255 - 0) + 0 or
new_value = ADC_val * 999 / 255

We cant multiply by any value > 257 or there will be an overflow if ADC > 65 ( result > 65535) so we have to improvise.

(999/ 255 = 3.9167)

Cant use decimals either ! Yikes ! What to do?

3.9167 is close to 3.92 so I multiply that by 100 and get 392 ( an integer!) 392 is too large so I divide again by 2 and get 196 ... good (Same as 3.92 * 50)

Now the formula is: ... new_val = ADC_val * 196 / 50

Try it !
Thanks I tried it but im confused and it did not work for me.
Could you explain it again please? this time imagine you are trying to explain it to your mother :)
Im not sure where I should put this formula.
thanks for your patience
 
Thanks I tried it but im confused and it did not work for me.
Could you explain it again please? this time imagine you are trying to explain it to your mother :)
Im not sure where I should put this formula.
thanks for your patience
Wait I did it :D, I had changed the code to readadc10 before i tried your code.
changing it back to readadc worked a treat
Thanks!
 
Top