RCTIME help. Reading 0 to 5V and need steady results.
eagletalontim
Posts: 1,399
Hello once again! I am using the BS2.RCTIME function and am trying to read positive voltage from 0 to 5V. I know RCTIME returns a value from 0 to 255, but I am having problems getting it to read correctly. For one, I cannot figure out the correct resistor values to get RCTIME to respond between 0 and 255 for the range I am looking for.
Currently, this is what I am using :
[PHP]
10K 10K
Throttle in >----/\/\/\/\/----0---/\/\/\/\/
> Prop Pin
|
= .1uf Cap
|
V
GND
[/PHP]
Here is my code :
[PHP]PUB ReadThrottle
BS2.start (31,30)
repeat
dira[5]~~ ' Set as output
outa[5]:=1 ' Set high
BS2.Pause(10) ' Allow to charge
throttle := BS2.RCTime(5,1) ' Measure RCTime[/PHP]
What would be the correct way to read a 0 to 5v source with a steady result using RCTIME?
Currently, this is what I am using :
[PHP]
10K 10K
Throttle in >----/\/\/\/\/----0---/\/\/\/\/
> Prop Pin
|
= .1uf Cap
|
V
GND
[/PHP]
Here is my code :
[PHP]PUB ReadThrottle
BS2.start (31,30)
repeat
dira[5]~~ ' Set as output
outa[5]:=1 ' Set high
BS2.Pause(10) ' Allow to charge
throttle := BS2.RCTime(5,1) ' Measure RCTime[/PHP]
What would be the correct way to read a 0 to 5v source with a steady result using RCTIME?
Comments
Here is a direct link (in case login is not required) http://www.parallaxsemiconductor.com/an008
Seems there is no other way to get to the app notes. If you cannot get to them let me know and I wil download and post here (because I am certain parallax do not intend to have the app notes locked away).
I think I got it. It updates the variable adcsample. Now one question I have is since I am reading voltage from 0 to 5 volts, I need to connect the Vdd input of the ADC circuit to 5v correct?
Yes, and Vref, too. Any pin that outputs to the Propeller needs to be coupled with a 3.3K (or higher) resistor to limit the current into the pin.
Also.... If I connect the input of the circuit to the 3.3v output of the regulator, it will max out at 65535. That is with the Vdd connected to the 5v output of the 7805. If it maxes out at that low voltage, reading 5v will not work since I will only get about 60% reading. I have checked out the calculator here : http://www.pulsedpower.net/Applets/Electronics/SigmaDeltaADC/SigmaDelta.html but it does not specify what caps to use. I have some .01, .001, and one .1 on hand. I have 11,000 resistors on hand in all different sizes as well, but I have no idea what size to use to get the stability out of the ADC function. If I put the Vdd at 12 volts, will that give me a better range so I can read the full 5V without maxing out the ADC function?
Consider this, (an MCP3201 has 12 bits for 4096 values from 0 to vref) it may not be the fault of the ADC, rather the environment. If you are taking the leads off of the pot or ECM, use shielded 3 conductor cable. Ground only one end of the shield to prevent noise induced into the sense line from loop current flow in the shield. Pot wiper of course. The third wire, connect to the high side of the pot (or ECM) and run that to Vref of the ADC and that may give you better a better representation by compensating for the length of the supply lead. The shielding may help with the instability caused by all the electronic noise in the system. Also, bypass the supplies including the reference source, and low pass filter the input to the ADC as your TPS signal is not a very fast signal and keeping some of the high frequency transients out will help performance as well. As I mentioned in the other thread, you should look up the 2010 contest entry for DAQPac. It is an impressive little system that does much of the instrumentation your are needing.
FF
I quess I posted this correctly, let me know.
Your TPS is a 0-5v output, the Propeller can only do 0-3.3v with the ADC unless you put a resistor divider into the circuit. Run a 10k resistor from the TPS to the ADC input circuit (the part showed in the app note), then run a 10k resistor from the input to ground. This makes a voltage divider which converts the TPS to a 0-2.5v range, which is within the Prop's abilities without railing the input.
The ADC.spin object has more than enough precision, in fact you determine how much precision you need, then tell the driver to sample at that frequency.
Also, the AN008 app note has details on how this works:
If you got rid of the 10k going to the Prop pin and increased the other resistor to 100k.
Now, you can directly charge or discharge the cap to GND or Vdd with the Prop pin.
I think you'd have to do two readings then.
One to with the cap charged to Vdd and see if comes down below threshold in some time (for low throttle voltages).
Second with the cap at GND has see how long it takes to get to threshold (for high throttle voltages).
Shouldn't that work?
I just went out and tested the circuit as posted above without the TPS Vref and it is still way to jumpy. At 0% throttle, the voltage is 0.51v. At full throttle, it is 5.00V. The way I have it hooked up now, the display shows 1356 and sits there till about 1/4 throttle. When it hits that, it starts jumping from ~1800 to ~3400 while holding the throttle steady. It does the same at any position above 1/4 throttle all the way up to full throttle. It is like it is not picking up something correctly. I have checked all connections to ensure they are secure and connected to correct places. This is frustrating All a learning experience though! Is there a different design to the circuit that I could use the ADC with?
I am using the 12 bit output since that should be all I need. the 8 bit is really jumpy and it would be hard to get an average.
I tried using 104 ceramic caps (.1) and those did not change anything either. I must be doing something wrong since I cannot get even close to a steady reading at all from the ADC function. Since I am using the voltage divider resistor, do I need to move the Vdd to the 3.3V rail instead of the 5v? Is that what is throwing everything off for me?
Here is the code I have for the ADC :
[PHP]CON
SDF = 5 'sigma-delta feedback PROP OUTPUT
SDI = 6 'sigma-delta input PROP INPUT
PUB SigmaDelta (sample)
cognew(@asm_entry, sample) 'launch assembly program in a COG
DAT
org
asm_entry mov dira,#1<<SDF 'make SDF pin an output
movs ctra,#SDI 'POS W/FEEDBACK mode for CTRA
movd ctra,#SDF
movi ctra,#%01001_000
mov frqa,#1
mov asm_c,cnt 'prepare for WAITCNT loop
add asm_c,asm_cycles
:loop waitcnt asm_c,asm_cycles 'wait for next CNT value
'(timing is determinant after WAITCNT)
mov asm_new,phsa 'capture PHSA
mov asm_sample,asm_new 'compute sample from 'new' - 'old'
sub asm_sample,asm_old
mov asm_old,asm_new
wrlong asm_sample,par 'write sample back to Spin variable "sample"
'(WRLONG introduces timing indeterminancy here..)
'(..since it must sync to the HUB)
jmp #:loop 'wait for next sample
asm_cycles long $FFF '(use $FFFF for 16-bit, $FFF for 12-bit, or $FF for 8-bit)
asm_c res 1 'uninitialized variables follow emitted data
asm_cnt res 1
asm_new res 1
asm_old res 1
asm_sample res 1
asm_temp res 1[/PHP]
An optical encoder as shown in the link. It would require it to be mounted on a shaft, ie 1/4" shaft. You then read he values from the encoder into the Prop with the quadrature object. This is very easy to do, but I am not sure if your throttle would allow the hardware since it is not shown. You need to have a voltage range of 0 - 3v3 only to the Prop. Can you draw the exact schematic you are testing this with?
[PHP]
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
solenoida = 2
solenoidb = 3
upbutton = 0
downbutton = 1
VAR
LONG LCDstack
LONG ThrottleStack[100]
LONG lastWritten
LONG adcsample
LONG rpm
BYTE EVal1
BYTE throttle
BYTE gear
OBJ
adc : "ADC"
i2c : "Basic_I2C_Driver"
BS2 : "BS2_Functions"
lcd : "Serial_Lcd"
getrpm : "jm_freqin"
num : "simple_numbers"
PUB Main
rpm := 0
gear := 1
shiftgear(gear)
adc.SigmaDelta(@adcsample)
cognew(LCDupdate, @LCDstack)
'cognew(ReadThrottle, @ThrottleStack)
repeat
if ina[upbutton] == 1
gear++
gear := shiftgear(gear)
if ina[downbutton] == 1
gear--
gear := shiftgear(gear)
repeat while ina[downbutton] == 1 or ina[upbutton] == 1
waitcnt(3_000_000 + cnt)
waitcnt(10_000_000 + cnt)
PUB LCDupdate
getrpm.init(15)
lcd.init(8, 9600, 2)
lcd.displayOn
lcd.backLight(true)
waitcnt(2_000_000 + cnt)
lcd.gotoxy(0,0)
lcd.str(string("Testing Version "))
lcd.gotoxy(0,1)
lcd.str(string("Tims shifter V3 "))
waitcnt(200_000_000 + cnt)
lcd.cls
lcd.str(string("Gear: "))
lcd.gotoxy(0,1)
lcd.str(string("RPM : "))
repeat
rpm := getrpm.freq * 3
lcd.gotoxy(5,0)
lcd.str(num.dec(gear))
lcd.gotoxy(5,1)
lcd.str(string(" "))
lcd.gotoxy(5,1)
lcd.str(num.dec(rpm))
lcd.gotoxy(10, 0)
lcd.str(string(" "))
lcd.gotoxy(10, 0)
lcd.str(num.dec(adcsample)) ' Display
waitcnt(10_000_000 + cnt)
PUB ReadThrottle | thr, lt, ht, athr
repeat
dira[5]~~ ' Set as output
outa[5]:=1 ' Set high
BS2.Pause(10) ' Allow to charge
thr := BS2.RCTime(5,1) ' Measure RCTime
thr := ht - thr
athr := ht - lt
thr := thr * 100
thr := thr / athr
throttle := 100 - thr
PUB shiftgear(tmp)
if tmp > 4
tmp := 4
if tmp < 1
tmp := 1
dira[solenoida]~~
dira[solenoidb]~~
outa[16..23]~
dira[16..23]~~
if tmp == 1
outa[solenoida] := 1
outa[solenoidb] := 1
if tmp == 2
outa[solenoida] := 0
outa[solenoidb] := 1
if tmp == 3
outa[solenoida] := 0
outa[solenoidb] := 0
if tmp == 4
outa[solenoida] := 1
outa[solenoidb] := 0
outa[16..23] := numbers[tmp]
saveval(tmp)
'lcd.gotoxy(5,0)
'lcd.str(num.dec(tmp))
return tmp
PUB saveval(tmp) | temp, startTime
temp := tmp
if temp <> lastWritten and temp <> 0
if i2c.WritePage(i2c#BootPin, i2c#EEPROM, @EVal1, @tmp, 4)
abort ' an error occured during the write
startTime := cnt ' prepare to check for a timeout
repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, @tmp)
if cnt - startTime > clkfreq / 10
abort ' waited more than a 1/10 second for the write to finish
lastWritten := temp
return
DAT
numbers byte %0000_0000, %0101_0000, %1100_1110, %1101_1010, %0101_0011[/PHP]
Lose the 10k you have on GND.
Find a trim pot( 1k, 10k etc).
Put one side of the pot to GND
Put the other side of the pot to your throttle output(0-5)
Set throttle to max output(5v)
Adjust trim pot until you have 3v3 on the wiper.
Send wiper to the 10k as you have it on the circuit input.
This will allow a precise conversion of your 5v to 3v3.
EDIT : I tried a 1k Pot and a 10K pot. I don't have any higher than that.
Oh yeah, what Leon said. Breadboards would be a possible problem for doing ADC.