PDA

View Full Version : Help with the conversion math



Ramius
- 23rd November 2014, 20:34
Hi All!
So I have a pressure sensor that output a voltage reading based upon the pressure applied. How would I convert the voltage reading to actual pressure? I know that at zero PSI the A/D gives 7040 and divided by 16 should be a voltage of .440 volts. Thanks!

'************************************************* ******************
'* Name : XXXXSPEEDT2.bas *
'* Author : Ed Cannady *
'* Notice : Copyright (c) 2011 *
'* : All Rights Reserved *
'* Date : 8/29/2014 *
'* Version : 1.0 *
'* Notes : For a 18F1320 and 54AL07H2210 *
'************************************************* *******************

Define OSC 20
Define LOADER_USED 1
Include "Modedefs.bas"
include "hpwm10L.pbp"
ENABLE DEBUG

#CONFIG
__CONFIG _CONFIG1H, _HS_OSC_1H & _FSCM_OFF_1H
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_8K_2H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_27_2L
__CONFIG _CONFIG3H, _MCLRE_OFF_3H
__CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_ON_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
__CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H
#ENDCONFIG


Define ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 1000

ADCON1 = %11101111
TRISB = %11111111

VOLTS VAR WORD ' Volts reading
Reading var long ' What we are really reading

VOLTS = 0 ' Start with a Volts value of zero

GETVOLTS:

ADCIN 4, VOLTS

Reading = VOLTS

VOLTS = VOLTS/16
Pause 1000
GOTO GETVOLTS

pedja089
- 23rd November 2014, 21:22
There is not enough information to answer your question. You must know minimum pressure, voltage for minimum pressure, maximum pressure, and output voltage at max pressure.
Sensor output is probably ratiometric 0.5V to 4.5V. But what is maximum pressure? Or give us sensor type and datasheet.

HenrikOlsson
- 23rd November 2014, 21:31
Yes, what pedja089 said. The only clue you provided is 54AL07H2210 which returns nothing on Google.

And, I have a feeling we've been thru this before..... The PIC ADC has a resolution of 10 bits, it returns values ranging from 0 to 1023.

/Henrik.

Ramius
- 24th November 2014, 02:30
Sorry guys. The PDF was too large (22 pages as it had all the devices in the series) so to upload so I had to make it smaller! Yes it is a 0.5 - 4.5v type ratiometric device. My A/D is showing a reading of 7040 at zero psi and when I do a divide by 16 I get 440 which I am assuming means .440 volts? With a voltmeter I see .541 volts so now I have not been able to make any sense of all of this. My best guess is that this would indicate a voltage range of .440 to 4.440? Where .440 is zero and 4.440 would be at .07psi? If the A/D were 10 bit and giving 1023 as a maximum value then a reading of 7040 could not be possible. I am just so totally lost and confused with so many numbers! I just completely do not understand! :confused: Thanks!

richard
- 24th November 2014, 04:59
Yes, what pedja089 said. The only clue you provided is 54AL07H2210 which returns nothing on Google.

And, I have a feeling we've been thru this before..... The PIC ADC has a resolution of 10 bits, it returns values ranging from 0 to 1023.

/Henrik.

its just like de ja vou again
http://www.picbasic.co.uk/forum/showthread.php?t=19409&p=128578#post128578

HenrikOlsson
- 24th November 2014, 08:51
Yeah, deja vu indeed....

Ed,
* The resolution of the ADC is 10 bits.
* It does not return a reading directly in Volts.
* Basically it takes the difference between Vref+ and VRef- and divides that by 1024 (2^10, the resolution of the ADC). Each "count" in the value is then "worth" that amount.

So, if VRef- is GND (0V) and VRef+ is 5V the difference between the two is 5V. Each "count" in the ADC result is then "worth" 5/1024=4.88mV.
If the ADC returns 745 the voltage at its input is 5/1024*745=3.638V

I can't make out anything from that datasheet, it's just garbage numbers when viewed on my machine. I managed to find this one. (http://www.servoflo.com/download-archive/data-sheets/download/313/728/17.html) And, I'm guessing you've got the 7psi sensor, correct? If so then something like this might work. I have not tested it though so all bets are off....

Of course you need to configure pins etc as usual (!)



Accumulator VAR WORD
i VAR BYTE
ADResult VAR WORD

Accumulator = 0

Main:

For i = 0 to 39
ADCIN 4, ADResult
Accumulator = Accumulator + ADResult
PauseUs 500
NEXT

ADResult = Accumulator / 10 ' Psuedo 12bit resolution, ADResult is now 0-4092

' Sensor outputs 0.5V (ADResult=409 ) at 0psi (nominal)
' Sensor outputs 4.5V (ADResult=3683) at 7psi (nominal)

ADResult = ADResult - 409 ' Offset for zero output, ADResult is now 0 to 3274 for 0 to 7psi
ADResult = ADResult */ 547 ' Scale up, ADResult is now 0 to 6995 for 0 to 7psi

' Display Pressure: x.xx psi
HSEROUT["Pressure: ", DEC ADResult/1000, ".", DEC2 ADResult//1000, "psi", 13]

PAUSE 1000

Goto Main

/Henrik.

richard
- 24th November 2014, 09:43
Yeah, deja vu indeed....


I can't make out anything from that datasheet, it's just garbage numbers when viewed on my machine.

/Henrik.


ditto for the pdf
do we have a 54A L07H2210 or a 54ALL07H2210 or a 54AL007H2210 or a 54A 007H2210 ?
they are all different animals and the 54ALxxx are 3.3v devices

EarlyBird2
- 24th November 2014, 09:46
Is this not a repeat of the left and right output justification as on the previous thread in Richard's link.

7040 left justified is 110 right justified using Henrik's 4.88mV then

110*4.88/1000=0.5368 V

Or put another way 7040/64=110 which shifts the 10 bit left justified result 6 bits to the right making the result the same as a right justified result.

EarlyBird2
- 24th November 2014, 09:48
PDF works for me.

The sensor is a 0.07 psi low voltage range with output from 0.5-4.5V

richard
- 24th November 2014, 09:55
that makes it a "54A L07H2210" not what was posted , its best to be sure

steve can you read the characteristics in the data sheet ,that what comes out garbled for me

EarlyBird2
- 24th November 2014, 09:57
'* Notes : For a 18F1320 and 54AL07H2210 *

was it not?

richard
- 24th November 2014, 10:04
this is what I mean

HenrikOlsson
- 24th November 2014, 10:22
Is this not a repeat of the left and right output justification as on the previous thread in Richard's link.
Yes, that's exactly what it is. The reason for the results have been covered in that thread but not a way to end up with a correct pressure reading - which is still kind of hit and miss since we need specific details no the actual sensor used.

/Henrik.

Ramius
- 25th November 2014, 03:18
Hi All and Thanks!
Just for grins I took a 10K resistor and fed the A/D input pin with 5 volts. The reading I got was 65472! I had to print and scan the data sheet as the one Servoflo has is similar and does not show the .07 psi device I am using. Not sure why when you print 5 pages to a PDF the text scrambles, its Abobe! :D I will try the suggest code in a few days. Yes it is a 54A-L07-H-2210 a 5 volt device.

Best, Ed

Ioannis
- 25th November 2014, 05:54
And this 65472, isn't the 1023 with left justification?

Ioannis

Ioannis
- 25th November 2014, 06:00
At page 157 of the Data sheet, it is shown that the PIC defaults to ADFM at 0 (zero), so it is really Left Justified by default. You have to make it a 1 for Right Justified result.

The register is the ADCON2 and bit 7.

Ioannis

HenrikOlsson
- 25th November 2014, 06:19
Just for grins I took a 10K resistor and fed the A/D input pin with 5 volts. The reading I got was 65472!
Yes, because you have the freaking thing configured wrong for the way that ADCIN works for crying out loud :-)
Just set the justification bit correct, as Ioannis shows AND as we've already discussed in the other thread where we went thru all this resolution and justification stuff last time.

OK, so it's a 0.07psi and not 7psi as I based my code around..... Well, then we need to change the scaling but lets see if it works at all first.

/Henrik.

richard
- 25th November 2014, 06:47
that works out pretty nicely every adc 100 count is almost exactly .01 psi

0=110 , 0.07 = 820 couldn't be easier


assuming I read the data sheet properly and that 0.07 psi = 4.0 volts and vref=5 v of course

EarlyBird2
- 25th November 2014, 10:31
that works out pretty nicely every adc 100 count is almost exactly .01 psi

0=110 , 0.07 = 820 couldn't be easier


assuming I read the data sheet properly and that 0.07 psi = 4.0 volts and vref=5 v of course

Not quite Richard. In theory

0=102.4 at 0.5 volts and 0.07=921.6 at 4.5 volts.

assuming as you say the vref=5 v.

102.4 is the zero offset and 0.07/(921.6-102.4) is the slope.

to convert to psi

psi=(reading-offset)*slope

psi=(reading-102.4)*0.07/819.2

psi=(reading-102.4)*0.0000854492.....

I do seem to remember this is for a depth gauge on a model submarine and am wondering what depth of water is 0.07 psi. The answer is 100 mm of water (99.54mm).

Giving

mm of water=(reading-102.4)*0.12207028.....

just to check at maximum reading = 921.6

therefore

mm of water=(921.6-102.4)*0.12207028

mm of water=99.9999

I am now wondering if this gauge is suitable?

Acetronics2
- 25th November 2014, 20:44
I am now wondering if this gauge is suitable?

0.07 psi gauge surely is a differential one ... so, one could reasonnably think it's for measuring SPEED with a pitot tube ...

just my two cents ...

Hi, Ed

Why not download that jewel ???
http://curveexpert.software.informer.com/download/?ca13e51

Alain

Ramius
- 26th November 2014, 03:10
Hi! :) So if I understand correctly I need to use ADCON2 instead of ADCON1 with the same bit configuation? Yes Alian your are completely correct! It is a differntial sensor for my submarine. As the sub dives you need to subtract out the pressure at a given depth for the incoming pressure to stay meaningful.

Ioannis
- 26th November 2014, 06:03
You mean that at page 156 of the datasheet you saw ADCON1 and at page 157 ADCON2 and concluded that are the same at bit 7 ? They are not and must be setup accordingly to your needs ALL of them. DO NOT rely on power up defaults.

You have to set if not all, the most registers for the PIC to work as expected.

ADCON0, ADCON1, ADCON2 should ALL be set as YOU desire, NOT the PIC's default state. Each register has its own bits for different setting. Otherwise why have dozens of registers if they were all the same?

Ioannis

Ramius
- 27th November 2014, 04:13
Hi Ioannis,
This is my very first attempt at using the PIC's A/D.
I think that ADCON0 should be 000100?1 as I am not sure what "GO/DONE" should be set at.
ADCON2 looks like it should be 11101010 and again I am not certain of the last 3 bits.

Thanks, Ed

Ioannis
- 27th November 2014, 07:09
Ed,

Settings depend on your hardware and software requirements.

E.g.: Do you have internal or extrernal Vref for the ADC? If it is internal and you want the Vref to be at Vdd and ground span, you should set VFG1:0 as 00.

So, I will try to give you an approach and if it is not close to your circuit we can change it.

ADCON0: %00000001 ' This sets the ADC channel to 0 (AN0) reference at power supply and converter is ON, ready to convert.
ADCON1: %00000001 ' All inputs digital except channel 0 (AN0)
ADCON2: %10110010 ' Right justification, 16Tad acquisition time, Fosc/32 to be safe.

Now, when all this are setup, you only have to set the GO/DONE bit (ADCON0.1=1) and wait until it is cleared (WHILE ADCON0.1:WEND).

Then get your 10bit result from the ADRESH/ADRESL registers or the variable you use in ADCIN.

Ioannis

Ramius
- 27th November 2014, 17:09
Hi Ioannis!
Thank you!
The connections are very simple, the sensor output is connected to pin 8 (AN4) of the 18F1320.
So to me this would make ADCON0: %00010001.
Then ADCON1: %11101111, all inputs digital except channel 4 (AN4) which would be set to analog.
Then ADCON2: %10110010 as you wrote.

Or did I misunderstand something completely?

Again, Thank you for all the time you are spending with me.

Ed

Ioannis
- 27th November 2014, 22:09
I think you are good to go!

Ioannis

Ramius
- 28th November 2014, 01:33
Thanks Ioannis it works great now! Next is trying to understand the program Henrik wrote.

Accumulator VAR WORD
i VAR BYTE
ADResult VAR WORD

Accumulator = 0

Main:

For i = 0 to 39
ADCIN 4, ADResult
Accumulator = Accumulator + ADResult
PauseUs 500
NEXT

ADResult = Accumulator / 10 ' Psuedo 12bit resolution, ADResult is now 0-4092

' Sensor outputs 0.5V (ADResult=409 ) at 0psi (nominal)
' Sensor outputs 4.5V (ADResult=3683) at 7psi (nominal)

ADResult = ADResult - 409 ' Offset for zero output, ADResult is now 0 to 3274 for 0 to 7psi
ADResult = ADResult */ 547 ' Scale up, ADResult is now 0 to 6995 for 0 to 7psi

' Display Pressure: x.xx psi
HSEROUT["Pressure: ", DEC ADResult/1000, ".", DEC2 ADResult//1000, "psi", 13]

PAUSE 1000

Goto Main

If I know that at zero PSI the A/D gives 110 as a value and now it looks like we are using a high value of 4092 would I not take and use 4 times the 110 value?
Next, where did the 547 value come from and should it be "adjusted"?

Thanks, Ed

HenrikOlsson
- 28th November 2014, 07:18
Hi Ed,

The sensor nominally outputs 0.5V at 0 psi. With 5V as the reference the 10bit ADC will return a value of 102 (102.4 ideally) for a 0.5V input.
Becaues we are taking 40 readings and then dividing that by 10 we go from 10bit reslution to 12bit (4 times oversampling) so our 102.4 now becomes 102.4*40/10=409 which is where the 409 in the code comes from.

At full scale (7psi, 0.07psi whatever is is) the sensor nominally outputs 4.5V. With 5V as the reference the 10bit ADC will return a value of 921 (921.6 ideally) for a 4.5V input.
Because we are taking 40 readings and then dividing that by 10 we go from 10bit resoultion to 12bit (4 times oversampling) so our 921.6 now becaomes 921.6*40/10=3686.

So now we have a value ranging from 409 to 3686 for our 0 to 7 (or 0.07) psi. The first thing we need to do is remove the offset. Easy enough, just subtract 409 to get a value ranging from 0 to 3277 for our 0 to 7 (or 0.07psi).

The final step is to get that strange value into something reassembling the actual pressure and that's where the 547 numbler comes in.

The */ operator has be covered numerous times on the forum. It's like multiplying by units of 1/256. So 3277 * (1/256*547) = 7002.

So now we have a value ranging from 0 to 7002 for a pressure of 0 to 7 (or 0.07 or whatever) psi and all we need to do is to put a decimal point between the correct digitis when displaying the value.
For 0 to 7psi:
HSEROUT["Pressure: ", DEC ADResult/1000, ".", DEC2 ADResult//1000, "psi", 13]

For 0 to 0.07psi:
HSEROUT["Pressure: 0.0", DEC ADResult, "psi", 13]

Obviously, if your sensor outputs values other than the nominal (which of course is likely) the numbers needs to be tweaked to calibrate the readings.

/Henrik.

Ramius
- 28th November 2014, 15:05
Thank you Henrik!
You and the people here are incredibly smart! I cannot thank all of you enough for your support and patience in teaching me so much and guiding me out of the "fog" I tend to get into. The high pressure side of the sensor is being fed with a .094" tube so there is not a lot of pressure to sense which is why the sensor has such a small range. The low side of the sensor is "static" pressure so you can compensate for the depth and still be able to know the speed when sub is travelling through water. In Microcode Studios ICD is where I can see the readings from the sensor. So since I know from the ICD that at zero pressure I get 110 and not 102.4 should I only adjust the low value or should I also adjust the high value assuming that the sensor has basically a 4 volt span (.5v to 4.5v) or does the high value stay the same? That is, a range from .5368 volts to 4.5368 volts. Again my most sincere thanks.

Ed

HenrikOlsson
- 28th November 2014, 15:50
Hi Ed,
You may need to change both the offset and the gain value.
Just because the voltage at the low end is off by 37mV doesn't mean the high end is off by the same amount.

Numbers within () are example numbers.

Step 1, Take a bunch of readings at 0 pressure, write down the reported numbers, then calculate the average. (345)
Step 2, Take a bunch of readings at max pressure, write down the reported numbers then calculate the average. (3591)
Step 3, Figure out what you want the final range of values to be. 0-1000, 0-5000, 0-7000 etc? (0-1000)
Step 4, Calculate the "offset" and the "gain":
The "offset" is simply the value calculated in step 1. (345)
The "gain" is [whatever value you want max to be] divided by ( [value at step 2] minus [value at step 1] ) times 256 ie. 1000 / (3591 - 345) * 256 = 79

What's that 79?
Again, it's like multiplying by units of 1/256. So when our value returned by ADC routine is 3591 (max pressure) we first subtract the offset of 345 and then multiplies with 79/256, what's the result?
(3591-345) * 79 / 256 = 1001, not perfect but pretty close.


If you're using the routine I posted earlier, with the 4 times oversampling, then look at the result directly from the ADC (110 in your case), look at the result at the end of the routine. It it might be 438 or 441 and, as long as the sensor isn't super stable and "slient", it'll give you a better over all resolution.

/Henrik.

Ramius
- 14th December 2014, 18:58
One of the things I wanted to do is pubicly thank everyone especially Henrik! After finally receiving replacement sensors (I blew up the last 3 due to over pressure) I got a chance to play! One thing I noticed when firing up the code in Microcode Studio Plus and using the ICD was that the ICD display made room at the bottom to actually display the results! The HSEROUT line of code made eveything so much easier! Again many, many thanks!

Sincerely, Ed