CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

MS5803 Help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

MS5803 Help
PostPosted: Tue Apr 12, 2016 2:18 pm     Reply with quote

Hi All,

I am using a PIC16F1829 with a Meas-Spec MS5803-14BA sensor. I am having trouble calculating the pressure from the unit. I think my issue is stemming from variable type, but im not sure.

I can read all of the registers in the device over I2C without issue, but I am having issues with the following function. Calculation of "dT" is correct, but "off", "SENS" and "Pressure" are not calculating correctly.


Code:
float32 GetBusPressure(){

   GetD1D2();
   
   
   signed int32 dT = D2-Amb_C[5]*twoto(8);
   
   float32 off = Amb_C[2]*twoto(16)+((dT*Amb_C[4])/twoto(7));
   
   float32 SENS = Amb_C[1]*twoto(15)+((dT*Amb_C[3])/twoto(8));
   
   float32 Pressure = (((D1*SENS)/(twoto(21)-off))/twoto(15));
   
   return Pressure;
   
}

float32 twoto(int factor) //Efficiently return integer 2^factor  Graciously provided by Ttelmah
{
   int32 res=1;
   res<<=(factor);
   return (float32)res;
}


The following values are read from the sensor:

Amb_C[1] = 45342
Amb_C[2] = 39644
Amb_C[3] = 28929
Amb_C[4] = 27159
Amb_C[5] = 31972
Amb_C[6] = 28819

D1 = 4122586
D2 =9156890

Plugging these into an excel spreadsheet yields a pressure of 10140 04 1.014bar which is correct. The output of the above function is showing the following:

dT = 972058 (Matches Excel Calcs)
off = -1691933824 (Does not match Excel)(Excel = 2804360147
)
SENS = -669311168 (Does not match Excel)(Excel = 1595613007
)
Pressure=-49.70 (Does not match Excel)(Excel = 10140.97)


Can anyone provide any insight to what is going on here?

Sensor Datasheet: http://www.meas-spec.com/downloads/MS5803-14BA.pdf
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 12, 2016 2:53 pm     Reply with quote

quick reply
ANYTIME I have to do 'fancy math', I make sure I have LOTS of braces to ensure the compiler KNOWS what I want calculated 1st,2nd, 3rd.

You may want to 'breakup the math into smaller 'steps' and test/printout results to be sure the interim numbers agree with what is expected.

While it might not be your problem... doesn't hurt to check.

Jay
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Tue Apr 12, 2016 3:27 pm     Reply with quote

I strongly suspect you're mixing signed and unsigned types. Be explicit with your declarations in your functions and/or with your variables. If something is supposed to be unsigned, include unsigned in the declaration.

I've also learned that my CCS code always gives me what I expect if I explicitly make it use the variable size I want for intermediate calculations by using (casts).

The other suggestion to break apart calculations into smaller pieces is also very good. I've found that CCS sometimes doesn't always output what I expect if I string together too many variables in an equation.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: MS5803 Help
PostPosted: Wed Apr 13, 2016 2:03 am     Reply with quote

The datasheet is quite useful in leading you to a good implementation off this. It gives suggested variable sizes, all integers, for all these values, and gives worked examples. I can see you've read that bit as you've used those examples. So I have to ask why are you not using the suggested varaible types? Granted, there is an issue that on the 16s and 18 there is no support in CCS C for unsigned int64, but the datasheet doesn't suggest it's use.

You see, when done as the datasheet suggests, all the maths are done in integers. The "* 2^n"s become simple shifts, and need none of that float multiply by float constant nonsense.

The C values are calibrations and need only be read once, and where they are multiplied by some power of two (by shifts in integers remember) that only needs to be done once, mand the modified constant used thereafter.

So, I suggest you ditch the floats and do it again as the datasheet says, i.e. in integers. The start of the function might then look like this:

Code:


...

// Somewhere in some initialisation code:

unsigned int16 Amb_C[6];

Amb_C[5] = Read_Cal(5) << 8;    // Pre-multiply the constant to save work later

...

float32 GetBusPressure(){

   GetD1D2();
    // dT can be negative, therefore we must do the maths in signed int32.

   signed int32 dT = (signed int32)D2-Amb_C[5];



Be aware that while we know that the result of int16 * int16 can be int32, the C standard doesn't, and will only give an int16 result. Therefore you need to promote, by casting, one of the operands in the expression to int32 to force int32 arithmetic to be used. I suspect that's the sort of thing your code is falling over on, especially as you are getting sign changes.
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Apr 13, 2016 5:17 am     Reply with quote

re read this post...

man ,it must take a donkey's age to do THREE complex floats ! Done in integer math, probably less than 1/4 of the time or . Be interesting to time them and post the results so others can see why 'we old guys' are always harping that floats in PICs are 'bad'.

Jay
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Thu Apr 14, 2016 5:54 am     Reply with quote

All,

Thanks for the replies, i'll give these a try ASAP. Had to jump on another project for the time being. I'll be sure to post back with my results.

As a side note, Meas-Spec actually has some example code where they do these calcs as floats (albeit on an Atmel). Why they show ints in the datasheet and floats in the example code is beyond me!

Thanks again!
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Tue Jun 07, 2016 12:23 pm     Reply with quote

Hi all,

Finally back on this project. I think i've figured out the reason for my wacky numbers.

Some of my 32bit signed integers are turning out to be larger than 32bits. The datasheet suggests the use of 64bit signed integers, but that isnt possible on this PIC.

I have no need for a 64bit pressure value, I dont need that kind of accuracy. Is there anyway that I can "drop" some of the precision to have my math end up being 32bit?

Heres the current code:

Code:

   signed int32 dT = D2-Amb_C[5]*twoto(8);
 
   
   signed int32 Temp = 2000+(dT*((signed int32)Amb_C[6]/twoto(23)));

   
   signed int32  off =(signed int32)(Amb_C[2]*twoto(16))+((dT*Amb_C[4])/twoto(7));

   
   signed int32 SENS = (signed int32)(Amb_C[1]*twoto(15))+((dT*Amb_C[3])/twoto(8));

   
   signed int32 Pressure = ((((signed int32)D1*SENS)/(twoto(21)-off))/twoto(15));


Thanks!
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 07, 2016 2:41 pm     Reply with quote

My 'gut' instinct is to just take the reading and 'dumb it down', from 24 bit to 16 bits. That would be fast and easy (right shifts).You will have to 'do some math', test some numbers to see if this is possible and gives the proper results.

Jay
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Wed Jun 08, 2016 11:45 am     Reply with quote

Thanks,

When I try to right shift, I am given the following error:

"Only integers are supported for this operation"

The code is:

Code:

 signed int32 off =((((signed int32)(Amb_C[2]*twoto(16)))+((dT*Amb_C[4])/twoto(7)))) >> 16;


I cant seem to figure out why this error comes up. Any ideas?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 08, 2016 11:55 am     Reply with quote

Post a test program for this problem. Post the all the variable declarations
for the variables used in your equation.
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Fri Jul 01, 2016 7:22 am     Reply with quote

I was finally able to get this to work. I did the following
Code:


   dT = dT/1000;
   
   float32 OffL = 65.536*Amb_C[2];  //Left portion of OFF calculation, multiply by 1000 to get actual value
   float32 OffR = ((Amb_C[4]/1000)*dT)/twoto(7); //Right portion of OFF, multiply by 1E6 to get actual value
                   
                                         
   float32 SENSL = 32.768*(float32)Amb_C[1];   //Left Portion of SENS calculation, multiply by 1000 to get actual value
   float32 SENSR = (((float32)Amb_C[3]/1000)*(float32)dT)/256; //Right portion of SENS calculation, multiply by 1E6 to get actual value
                                           
       
                                                   
   float32 Pressure = (D1 *((SENSL*1000)+(SENSR*1000000))/twoto(21)-((OffL*1000)+(OffR*1000000)))/twoto(15);

   Pressure = 14.5*(Pressure/10000);   


I split up the calculation of "OFF" and "SENS" into two portions, making sure that no step in their calculation would ever be greater than a float32 could handle. Then, in the pressure calculation, I multiple by the required amount to bring the values "back to normal". There is a tiny bit of precision lost somewhere, but this works for my application.

Thanks to everyone for the help!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group