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

Bar30 Pressure Sensor use with PIC

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



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

Bar30 Pressure Sensor use with PIC
PostPosted: Tue Dec 05, 2017 2:09 pm     Reply with quote

I am trying to convert Arduino C++ code to control the Bar30 pressure sensor to CCS C for use with a PIC.
The Arduino code is:

Code:
      // Read calibration values and CRC
      for ( uint8_t i = 0 ; i < 7 ; i++ ) {
         Wire.beginTransmission(MS5837_ADDR);
         Wire.write(MS5837_PROM_READ+i*2);
         Wire.endTransmission();
   
         Wire.requestFrom(MS5837_ADDR,2);
         C[i] = (Wire.read() << 8) | Wire.read();
      }

Note that the array CAL[] is 16 bit. My code (with variables declared elsewhere)is:

Code:
// read CRC & calibration values
    for (i=0; i<7; i++)                          // C[0] includes CRC
    {
     I2C_START ();                               // start I2C
     I2C_WRITE (BAR30_WRT_ADDR);           // write to sensor
     I2C_WRITE (BAR30_PROM_READ + i*2);    // A0, A2, A4, A6, A8, AA, AC (ADDR 0 TO 6)
     I2C_STOP ();                                // stop I2C
     I2C_START ();                               // start I2C
     I2C_WRITE (BAR30_READ_ADDR);          // read address
     CAL[i] = I2C_READ()<<8 | I2C_READ(0);    // NACK so we don't hang
     I2C_STOP ();                                // stop I2C
    }


The PROM address is buried in the PROM_READ address in bits 1 to 3 and appear in the correct place so don`t fret over that part of the code. The problem is in the second last line.
For i=0 the first read is 00E0 which should shift to 0E00. The second read is 0001 so the two ORd together should be 0E01 but the above gives 0001.
If I change that line to:

Code:
CAL[i] = I2C_READ();
CAL[i] = CAL[i]<<8;
CAL[i] = CAL[i] | I2C_READ(0);


Then I get 0E01 for CAL[0] which is correct.

even
Code:
CAL[i] = I2C_READ<<8;

Does not work. I realize that it reads 8 bits into a 16 bit word.

What is the difference between the two pieces of code and why do they act differently?
Why does the Arduino code work? Or does it?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Dec 05, 2017 2:38 pm     Reply with quote

Remember the fundamental integer size in CCD is an int8.
Now in any maths operation, the operator sizes are determined by the largest maths size in the operands, not the destination. I2C_read returns an int8, so the shift will be attempted in an int8, which is then transferred to the int16 destination. The Arduino functions return their default int, which is 16bit.

So:
Code:

CAL[i] = ((int16)(I2C_READ())<<8) | I2C_READ(0);


Should work. This casts the return from the I2C_read to an int16 type, then does the rotation, the or's in the second read.

In fact thinking about it this should also work:
Code:

CAL[i] = I2C_READ()<<8L | I2C_READ(0);

depends on whether the compiler correctly handles the shift in a 16bit because the amount is a 'long'.

However worth also saying, why not use make16?. Much more efficient. This is directly coded as a byte move.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue Dec 05, 2017 4:39 pm     Reply with quote

Thanks Ttelmah, I suspected something like that but could not understand why, or if, the Arduino code worked.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Wed Dec 06, 2017 8:42 am     Reply with quote

Problem1.
The Arduino code uses int64 for several variables.
I am using a PIC17F882 and the CCS PCM compiler does not accept int64.
Any suggestions? The manual gives int64 as valid but it produces a compile error, is it accepted by PCH?

Problem 2.
This sensor is not what I expected. The math is extensive and is eating up all my PIC resorces. A PIC16F886 will help solve the memory problem. What I would like to do is dedicate a PIC to the sensor. How do I do that when my I2C master PIC is talking to several other PICs on I2C and this sensor-dedicated PIC needs to talk to the sensor on I2C. My master PIC also talks to the control console on the serial port so I can't use that. Any suggestions? Can I have more than one I2C bus connected to a PIC? A third software port? Any examples? Can I have two masters on one bus?

Problem3.
I tried make16 as suggested but don't think it will work mixing int8 and int16. It takes the LSB of the int16 no matter which order the variables are placed. So:

int x = 0xC3;
int16 y = 0xA7B4;
int16 z = 0;
z = make16 (y,x);

gives z = B4C3 or C3B4 if I switch x and y in the make16(). It just dawned on me that if I don't shift the int16 it will work. I will play some more.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Dec 06, 2017 9:12 am     Reply with quote

You should be using the make16 to assemble the two bytes directly from the i2c commands. So the line you pasted is assembling two 8bit values from the i2c to make an int16. Does this perfectly....
If you load the PCM or PCH manual directly, they do not refer to int64. This is only supported by PCD.
Yes you can have as many I2C's as you want. Obviously using software I2C not hardware. #USE I2C, and stream names to say which one you want to talk to.

Honestly there is a problem.
The sensor itself returns two of it's calibration coefficients as signed int64 values. Now it is probably possible to bodge these and use a different type, but it is going to be a _lot_ of work, investigating how these are used and the maths involved. Far easier to have int64 available to you. Now it is possible to code your own int64 maths, but it is going to get large. If you have got PCD, then consider getting one of the small PIC24/30's, and using this to handle this sensor, then having this send the result to your other PIC, or switching all the code to this. Given that you can get these chips now in 5v versions, in DIP28 and DIP40 packages, for under $2, with 256K of ROM, it makes trying to fit such code in the older PIC's rather pointless....
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Wed Dec 06, 2017 10:10 am     Reply with quote

Thanks Ttelmah, this is getting beyond my abilities. I have some simple pressure transducers that convert pressure to voltage. They will not be as accurate as the Bar30, nor will they be temperature compensated, but they are within my capabilities.
I thought the Bar30 would simply return a pressure (depth) when asked, the way my tilt compensated compass does all the math for me and returns direction, pitch, and roll. I was not looking for weeks of work or extra cost.
There are other issues with this sensor. There is no O-ring groove and the thread is M10 meaning I will have to machine a flat and groove in the side of my 9" diameter ROV. Very difficult so an adapter must be made. My old pressure sensors have 1/8 NPT so very easy.
"consider getting one of the small PIC24/30's" Yes but over $400 Cdn for the PCD compiler. I could switch to Arduino or better yet a Raspberry Pi which I have. Both have free compilers.
This is all too much of a distraction from my working ROV with a working Robotic Arm. It is successful because I kept it within my abilities. I will have to re-think this.
You have been a great help, thanks.
temtronic



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

View user's profile Send private message

PostPosted: Wed Dec 06, 2017 10:53 am     Reply with quote

Sigh, I feel your pain, BTDT, several times. Seems EVERY R&D, proof of concept project is 'easy' until the ugly details emerge !

Perhaps search for a 'smart sensor', or at least one that better fits your needs. Having to machine seals is NOT easy,or fun.BTDT. A 'smart' sensor would be one that sends back the 'number' not a bunch of bits that need to be converted into the 'reading'. Decide on a max range for the sensor, and go from there.There's a LOT of 'process control' stuff that may fit your need, but it takes time to sift through the data.

As for the dedicated PIC, essentially YOU are building a 'smart sensor' or us old guys would say 'distributed processing'. Depending on the 'master' or 'host' PIC, I'd probably use RS485 to communicate with the 'smart pressure sensor'. I2C has tight limits compared to RS485. In another recent thread there was an octal I2C 'expander', it _might_ have a use but again look at the details.
For the 'math', if you decide to go PIC, stay with the 16 or 18 series, do the 'math' once; you'll save $400 by flipping to the other PICs AND save a LOT of grief/time learning 'yet another PIC'. Staying with what you KNOW will save a LOT of R&D time.

Just bits and bytes to think about.

Jay
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Wed Dec 06, 2017 11:20 am     Reply with quote

Thanks Temtronic, I think it might be easier to use an Arduino since I have already got $80 invested in the Bar30. It would be a useful skill to learn and affordable for a retired hobbyist. i have local Arduino makers that can help.

A PIC in my control console gets data from another PIC via I2C then sends and receives by RS485 on a pair of wires to the main PIC in the ROV. This main PIC talks to three other PICs by I2c to control and monitor the ROV. It also talks to three PICs in various sections of the robotic arm, again on the same I2C, This lets the satellite PICs take as much time as needed to handle their tasks. The Bar30 software has some long delays so I don't want that software in my main PIC, it will make my steering control sluggish.

I WAS WRONG ABOUT THE O-RING and apologize to the company. What I saw was the back of a nut that unscrews. There is a groove and I don't need a threaded hole, just a hole with a flat outer surface. One problem solved.
temtronic



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

View user's profile Send private message

PostPosted: Wed Dec 06, 2017 6:51 pm     Reply with quote

Just remember anything an Ardunio can do a PIC can do BETTER !
You've already got a lot of time invested in PICs so converting the A-code into PIC code is a one time investment,BTDT... I'm staying with PICs..getting too old to learn yet another micro,it's quirky C and compiler.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sat Dec 09, 2017 1:01 pm     Reply with quote

I have most of the Aduino code converted to PIC and working.
The last of the code involves big numbers which I cannot get to work.

Code:
float32 SENS;
SENS = 123456789;


results in displaying SENS = -5392220.13

Code:
SENS = 12345678;


displays as 12345678.08

Code:
SENS = 1.23456789E6;


displays as 1234567.92

Code:
SENS = 1.23456789E7;


displays as 12345679.36

Code:
SENS = 1.23456789E8;


displays as -5392220.13

where did I see that before (above)
So the following gives garbage, unlike my HP calculator.

Code:
float32 SENS;    // or just float SENS;
dT=6.8261E4;
C1=3.4857E4;
C3=2.0538E4;
    SENS = (C1*3.2768E4) + ((C3*dT)/256);


What am I doing wrong and what should I do?
Why does the compiler not complain or warn?
Edit: I am starting a new thread with this one.


Last edited by rovtech on Sun Dec 10, 2017 1:25 pm; edited 1 time in total
temtronic



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

View user's profile Send private message

PostPosted: Sat Dec 09, 2017 1:07 pm     Reply with quote

my 'gut feeling' is that it's a 'casting' issue though I am NOT a C programmer.
perhaps declare all them variables as floating point as see what happens.
when I started programming there were 2 kinds of numbers , ones and zeros, thing have changed a bit in 40+ years
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sat Dec 09, 2017 2:02 pm     Reply with quote

Yes I tried using all floating point numbers with the same erroneous results.

I tried a test code (sketch) on an Arduino and it will not print a 64 bit variable so I don't know if the equation gives the correct answer. It will print an int32_t.

A guy using a powerful Arduino Due had this to say before jumping through hoops and many lines of code to print a 64 bit number:

"I've read in the Reference section that the DOUBLE data type on the Due is a 64-bit variable. Unfortunately, the Serial.print won't handle a 64-bit variable. I haven't been able to print out a uint64_t either." (unsigned int64).

So an Arduino may not solve the problem either. I do have a Raspberry Pi that I could get to do the math......
My HP calculator can be connected serially.
Whatever happened to plain old guzzintas?
(You know 2 guzzinta 6 three times)

Edit:
My problem with the Arduino print was explained to me:
"The reason you are unable to print at int64_t is because there is no "Serial.print" function definition for Serial.print(int64_t var). The math libraries support the 64 bit operations but you cannot print the numbers with Arduino's current code."


Last edited by rovtech on Mon Dec 11, 2017 8:25 am; edited 1 time in total
temtronic



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

View user's profile Send private message

PostPosted: Sun Dec 10, 2017 6:04 am     Reply with quote

I just feel sorry for the poor little PIC having to crunch huge numbers ! They weren't made that that kind of 'abuse'.
I am curious as to the code space needed for say just 'c=a+b' though. Perhaps someone has already 'ported' or 'translated' a small library?
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