Last active
July 27, 2018 12:40
-
-
Save hephaestus9/f1a09406e970803b3e0b to your computer and use it in GitHub Desktop.
Depth Sensor Code - modified j.brian
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
created August 2011 | |
by SMStrauch and with help of robtillaart and ulrichard. Thanks! | |
Manufacturer: www.intersema.ch | |
Source: http://www.meas-spec.com/downloads/Using_SPI_Protocol_with_Pressure_Sensor_Modules.pdf | |
Source: http://forum.arduino.cc/index.php?topic=67188.0 | |
Datasheet: http://media.digikey.com/pdf/Data%20Sheets/Measurement%20Specialties%20PDFs/MS5541-CM.pdf | |
Modified 2-10-2015 J.Brian | |
MS5541 Pressure Sensor calwords readout | |
This program will read your MS5441 or compatible pressure sensor every 5 seconds and show you: | |
calibration words | |
calibration factors | |
raw values | |
and compensated values of temperature and pressure | |
Assumed pressure and temp. range: 0...14 bar, -40...85°C | |
Pins: | |
MS5541 sensor attached to pins 9, 11 - 13: | |
SPI : Arduino Pin : MS5541 | |
-------------------------- | |
MOSI: 11 : DIN | |
MISO: 12 : DOUT | |
SCK : 13 : SCKL | |
MCLK: 9 : MCLK | |
CS : N/C(10) : N/A | |
Calibration Words 1-4 16-bit | |
Source: http://www.amsys.info/sheets/amsys.en.an518_e.pdf | |
Coefficients: | |
Name : Value : Bits : MIN : TYP : MAX : Variable Name : | |
C1 : Pressure Sensitivity : 13 : 0 : 2391 : 8191 : SENST1 : | |
C2 : Pressure Offset : 13 : 0 : 4888 : 8191 : OFFT1 : | |
C3 : Temp. Coef. of Press. Sensitivity : 10 : 0 : 385 : 1023 : TCS : | |
C4 : Temp. Coef. of Press. Offset : 9 : 0 : 221 : 511 : TCO : | |
C5 : Ref. Temp. : 12 : 0 : 1689 : 4095 : Tref : | |
C6 : Temp Coef. of Temp. : 7 : 0 : 58 : 127 : TEMPSENS : | |
Digital Pressure & Temp.: | |
Variable Name: Value : Bits : MIN : TYP : MAX : | |
D1 : Digital Pressure : 16 : 0 : 17000 : 40000 : | |
D2 : Digital Temperature : 16 : 0 : 27000 : 45000 : | |
Maximum Values for Calculation Results | |
Pmin = 0mbar | |
Pmax = 14bar | |
Tmin = -40°C | |
Tmax = +85°C | |
Tref = +20°C | |
: MIN : TYP : MAX : | |
UT1 = 8 * C5 + 10000 : 10000 : 28016 : 42760 : | |
dUT = D2 - UT1 : -11400 : 0 : 12350 : | |
** dTmin = (Tmin - Tref) * 190TLSB / °C | |
** dTmax = (Tmax - Tref) * 190TLSB / °C | |
OFF = C2 + 10000 + (C4-250) * dUT / 2^12 : 9246 : 14888 : 18887 : | |
** OFFmin = C2min + 10000 + (C4min - 250) * dTmax / 2^12 | |
** OFFmax = C2max + 10000 + (C4max - 250) * dTmin / 2^12 | |
SENS = C1 / 2 + (C3 + 200) * dUT / 2^13 + 3000 : 1298 : 4196 : 8939 : | |
**SENSmin = C1min / 2 + (C3max + 200) * dTmin / 2^13 + 3000 | |
**SENSmax = C1max / 2 + (C3max + 200) * dTmax / 2^13 + 3000 | |
P(0...14bar, with 1mbar resolution) : 0 : : 14000 : | |
TEMP = 200 + dT * (C6 + 100) / 2 ^ 11 : -400 : : 850 : | |
**(-40...85°C, with 0.1 °C resolution, in 0.1 °C units) | |
*/ | |
// include library: | |
#include <SPI.h> | |
//******************************************************************* | |
//One of the following defines have to be uncommented but never both | |
//If Coeffecients have ben set: | |
#define CONSTANTS_SET true | |
//otherwise | |
//#define CALIBRATION true; | |
//******************************************************************** | |
#ifdef CONSTANTS_SET | |
const long SENST1 = 63; | |
const long OFFT = 8077; | |
const long TCS = 386; | |
const long TCO = 234; | |
const long Tref = 2097; | |
const long TEMPSENS = 55; | |
#endif | |
#ifdef CALIBRATION | |
long SENST1 = 2723; | |
long OFFT = 4648; | |
long TCS = 388; | |
long TCO = 224; | |
long Tref = 2309; | |
long TEMPSENS = 54; | |
#endif | |
// generate a MCKL signal pin | |
const int clock = 9; | |
//Hex Values for writing to MS5541 | |
byte D1_HIGH = 0x0F; | |
byte D1_LOW = 0x40; | |
byte D2_HIGH = 0x0F; | |
byte D2_LOW = 0x20; | |
byte W1_HIGH = 0x1D; | |
byte W1_LOW = 0x50; | |
byte W2_HIGH = 0x1D; | |
byte W2_LOW = 0x60; | |
byte W3_HIGH = 0x1D; | |
byte W3_LOW = 0x90; | |
byte W4_HIGH = 0x1D; | |
byte W4_LOW = 0xA0; | |
byte DUMMY = 0x00; | |
unsigned int word_1 = 0; | |
unsigned int word_2 = 0; | |
unsigned int word_3 = 0; | |
unsigned int word_4 = 0; | |
byte inByte_low = 0x00; | |
unsigned int D1 = 0; | |
unsigned int D2 = 0; | |
long UT1 = 0; | |
long dT = 0; | |
long TEMP = 0; | |
long OFF = 0; | |
long SENS = 0; | |
long PCOMP = 0; | |
float TEMPREAL = 0; | |
long dT2 = 0; | |
float TEMPCOMP = 0; | |
void Reset_Sequence_Command(); | |
#ifdef CALIBRATION | |
void getCValues(); | |
void getCalibrationWords(); | |
#endif | |
void getDigitalValues(); | |
void getRealValues(); | |
void setup() { | |
Serial.begin(9600); | |
SPI.begin(); | |
SPI.setBitOrder(MSBFIRST); | |
SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz | |
pinMode(clock, OUTPUT); | |
delay(100); | |
} | |
void loop() | |
{ | |
TCCR1B = TCCR1B & B11111000 | B00000001; //generates the MCKL signal | |
analogWrite(clock, 128) ; | |
#ifdef CALIBRATION | |
getCalibrationWords(); | |
getCValues(); | |
#endif | |
getDigitalValues(); | |
getRealValues(); | |
delay(500); | |
} | |
void Reset_Sequence_Command() { | |
SPI.setDataMode(SPI_MODE0); | |
SPI.transfer(0x15); | |
SPI.transfer(0x55); | |
SPI.transfer(0x40); | |
} | |
#ifdef CALIBRATION | |
void getCalibrationWords() { | |
//Calibration word 1 | |
SPI.transfer(W1_HIGH); | |
SPI.transfer(W1_LOW); | |
SPI.setDataMode(SPI_MODE1); | |
word_1 = SPI.transfer(DUMMY); | |
word_1 = word_1 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
word_1 = word_1 | inByte_low; | |
Reset_Sequence_Command();//resets the sensor | |
//Calibration word 2; | |
SPI.transfer(W2_HIGH); | |
SPI.transfer(W2_LOW); | |
SPI.setDataMode(SPI_MODE1); | |
word_2 = SPI.transfer(DUMMY); | |
word_2 = word_2 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
word_2 = word_2 | inByte_low; | |
Reset_Sequence_Command();//resets the sensor | |
//Calibration word 3; | |
SPI.transfer(W3_HIGH); | |
SPI.transfer(W3_LOW); | |
SPI.setDataMode(SPI_MODE1); | |
word_3 = SPI.transfer(DUMMY); | |
word_3 = word_3 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
word_3 = word_3 | inByte_low; | |
Reset_Sequence_Command();//resets the sensor | |
//Calibration word 4; | |
SPI.transfer(W4_HIGH); | |
SPI.transfer(W4_LOW); | |
SPI.setDataMode(SPI_MODE1); | |
word_4 = SPI.transfer(DUMMY); | |
word_4 = word_4 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
word_4 = word_4 | inByte_low; | |
Serial.print("Calibration word 1 ="); | |
Serial.println(word_1); | |
Serial.print("Calibration word 2 ="); | |
Serial.println(word_2); | |
Serial.print("Calibration word 3 ="); | |
Serial.println(word_3); | |
Serial.print("Calibration word 4 ="); | |
Serial.println(word_4); | |
} | |
#endif | |
#ifdef CALIBRATION | |
void getCValues() { | |
//now we do some bitshifting to extract the calibration factors | |
//out of the calibration words; read datasheet AN510 for better understanding | |
SENST1 = word_1 >> 3 & 0x1FFF; | |
OFFT = ((word_1 & 0x07) << 10) | ((word_2 >> 6) & 0x03FF); | |
TCS = (word_3 >> 6) & 0x03FF; | |
TCO = (word_4 >> 7) & 0x07FF; | |
Tref = ((word_2 & 0x003F) << 6) | (word_3 & 0x003F); | |
TEMPSENS = word_4 & 0x007F; | |
Reset_Sequence_Command(); | |
Serial.print("SENST1 (C1): "); | |
Serial.println(SENST1); | |
Serial.print("OFFT (C2): "); | |
Serial.println(OFFT); | |
Serial.print("TCS (C3): "); | |
Serial.println(TCS); | |
Serial.print("TCO (C4): "); | |
Serial.println(TCO); | |
Serial.print("Tref (C5): "); | |
Serial.println(Tref); | |
Serial.print("TEMPSENS (C6): "); | |
Serial.println(TEMPSENS); | |
} | |
#endif | |
void getDigitalValues() { | |
Reset_Sequence_Command(); | |
//Pressure (D1): | |
SPI.transfer(D1_HIGH); | |
SPI.transfer(D1_LOW); | |
//delay(35); | |
SPI.setDataMode(SPI_MODE1); | |
D1 = SPI.transfer(DUMMY); | |
D1 = D1 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
D1 = D1 | inByte_low; | |
Serial.print("Pressure raw ="); | |
Serial.println(D1); | |
Reset_Sequence_Command(); | |
//Temperature (D2): | |
SPI.transfer(D2_HIGH); | |
SPI.transfer(D2_LOW); | |
//delay(35); | |
SPI.setDataMode(SPI_MODE1); | |
D2 = SPI.transfer(DUMMY); | |
D2 = D2 << 8; | |
inByte_low = SPI.transfer(DUMMY); | |
D2 = D2 | inByte_low; | |
Serial.print("Temperature raw ="); | |
Serial.println(D2); | |
} | |
void getRealValues() { | |
//calculation of the real values by means of the calibration factors | |
UT1 = (Tref << 3) + 10000; | |
dT = D2 - UT1; | |
TEMP = 200 + ((dT * (TEMPSENS + 100)) >> 11); | |
OFF = OFFT + (((TCO - 250) * dT) >> 12) + 10000; | |
SENS = (SENST1/2) + (((TCS + 200) * dT) >> 13) + 3000; | |
PCOMP = (SENS * (D1 - OFF) >> 12) + 1000; | |
TEMPREAL = TEMP/10; | |
//2nd order compensation only for T > 0°C | |
dT2 = dT - ((dT >> 7 * dT >> 7) >> 3); | |
TEMPCOMP = (200 + (dT2*(TEMPSENS+100) >>11))/10; | |
Serial.print("Real Temperature in °C="); | |
Serial.println(TEMPREAL); | |
Serial.print("Compensated pressure in mbar ="); | |
Serial.println(PCOMP); | |
Serial.print("2nd order compensated temperature in °C ="); | |
Serial.println(TEMPCOMP); | |
Serial.println(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment