0.1.1 MS5611_SPI

This commit is contained in:
rob tillaart 2022-10-27 16:59:08 +02:00
parent 413dcc8411
commit 52cc321539
8 changed files with 197 additions and 76 deletions

View File

@ -1,3 +1,18 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
@ -9,3 +24,6 @@ compile:
- esp32
# - esp8266
# - mega2560
- rpipico

View File

@ -0,0 +1,22 @@
# Change Log MS5611
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.1] - 2022-10-27
- sync with MS5611
- add RP2040 support to build-CI
- add CHANGELOG.md
- add isConnected() ==> read() should return MS5611_READ_OK
- add getManufacturer()
- add getSerialCode()
- add parameter mathMode to **reset()** to switch between pressure math.
- see readme for details.
- minor edits.
## [0.1.0] 2022-01-18
- initial version, based upon MS5611 (15-okt-2014)

View File

@ -1,12 +1,11 @@
//
// FILE: MS5611_SPI.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: MS5611 (SPI) Temperature & Humidity library for Arduino
// URL: https://github.com/RobTillaart/MS5611
// VERSION: 0.1.1
// PURPOSE: MS5611 (SPI) Temperature & Pressure library for Arduino
// URL: https://github.com/RobTillaart/MS5611_SPI
//
// HISTORY:
// 0.1.0 2022-01-18 initial version by Rob Tillaart (15-okt-2014)
// HISTORY: see changelog.md
#include "MS5611_SPI.h"
@ -22,11 +21,11 @@
/////////////////////////////////////////////////////
//
// PUBLIC
// PUBLIC
//
MS5611_SPI::MS5611_SPI(uint8_t select, uint8_t dataOut, uint8_t dataIn, uint8_t clock)
{
// _address = deviceAddress; // TODO
// _address = deviceAddress; // TODO
_samplingRate = OSR_ULTRA_LOW;
_temperature = MS5611_NOT_READ;
_pressure = MS5611_NOT_READ;
@ -37,7 +36,7 @@ MS5611_SPI::MS5611_SPI(uint8_t select, uint8_t dataOut, uint8_t dataIn, uint8_t
_temperatureOffset = 0;
_compensation = true;
// SPI
// SPI
_select = select;
_dataIn = dataIn;
_dataOut = dataOut;
@ -48,7 +47,7 @@ MS5611_SPI::MS5611_SPI(uint8_t select, uint8_t dataOut, uint8_t dataIn, uint8_t
bool MS5611_SPI::begin()
{
// print experimental message.
// print experimental message.
Serial.println(MS5611_SPI_LIB_VERSION);
pinMode(_select, OUTPUT);
@ -93,38 +92,40 @@ bool MS5611_SPI::begin()
}
bool MS5611_SPI::reset()
bool MS5611_SPI::isConnected()
{
int rv = read();
return (rv == MS5611_READ_OK);
}
bool MS5611_SPI::reset(uint8_t mathMode)
{
command(MS5611_CMD_RESET);
uint32_t start = micros();
// while loop prevents blocking RTOS
while (micros() - start < 3000) // increased as first ROM values were missed.
// while loop prevents blocking RTOS
while (micros() - start < 3000) // increased as first ROM values were missed.
{
yield();
delayMicroseconds(10);
}
// constants that were multiplied in read()
// do this once and you save CPU cycles
C[0] = 1;
C[1] = 32768L; // SENSt1 = C[1] * 2^15
C[2] = 65536L; // OFFt1 = C[2] * 2^16
C[3] = 3.90625E-3; // TCS = C[3] / 2^6
C[4] = 7.8125E-3; // TCO = C[4] / 2^7
C[5] = 256; // Tref = C[5] * 2^8
C[6] = 1.1920928955E-7; // TEMPSENS = C[6] / 2^23
// initialize the C[] array
initConstants(mathMode);
// read factory calibrations from EEPROM.
bool ROM_OK = true;
for (uint8_t reg = 0; reg < 7; reg++)
{
// used indices match datasheet.
// C[0] == manufacturer - read but not used;
// C[7] == CRC - skipped.
// used indices match datasheet.
// C[0] == manufacturer - read but not used;
// C[7] == CRC - skipped.
uint16_t tmp = readProm(reg);
C[reg] *= tmp;
// _deviceID is a simple SHIFT XOR merge of PROM data
// _deviceID is a simple SHIFT XOR merge of PROM data
_deviceID <<= 4;
_deviceID ^= tmp;
// Serial.println(readProm(reg));
// Serial.println(readProm(reg));
if (reg > 0)
{
ROM_OK = ROM_OK && (tmp != 0);
@ -136,22 +137,22 @@ bool MS5611_SPI::reset()
int MS5611_SPI::read(uint8_t bits)
{
// VARIABLES NAMES BASED ON DATASHEET
// ALL MAGIC NUMBERS ARE FROM DATASHEET
// VARIABLES NAMES BASED ON DATASHEET
// ALL MAGIC NUMBERS ARE FROM DATASHEET
convert(MS5611_CMD_CONVERT_D1, bits);
// NOTE: D1 and D2 seem reserved in MBED (NANO BLE)
// NOTE: D1 and D2 seem reserved in MBED (NANO BLE)
uint32_t _D1 = readADC();
convert(MS5611_CMD_CONVERT_D2, bits);
uint32_t _D2 = readADC();
// Serial.println(_D1);
// Serial.println(_D2);
// Serial.println(_D1);
// Serial.println(_D2);
// TEST VALUES - comment lines above
// uint32_t _D1 = 9085466;
// uint32_t _D2 = 8569150;
// TEST VALUES - comment lines above
// uint32_t _D1 = 9085466;
// uint32_t _D2 = 8569150;
// TEMP & PRESS MATH - PAGE 7/20
// TEMP & PRESS MATH - PAGE 7/20
float dT = _D2 - C[5];
_temperature = 2000 + dT * C[6];
@ -160,16 +161,16 @@ int MS5611_SPI::read(uint8_t bits)
if (_compensation)
{
// SECOND ORDER COMPENSATION - PAGE 8/20
// COMMENT OUT < 2000 CORRECTION IF NOT NEEDED
// NOTE TEMPERATURE IS IN 0.01 C
// SECOND ORDER COMPENSATION - PAGE 8/20
// COMMENT OUT < 2000 CORRECTION IF NOT NEEDED
// NOTE TEMPERATURE IS IN 0.01 C
if (_temperature < 2000)
{
float T2 = dT * dT * 4.6566128731E-10;
float t = (_temperature - 2000) * (_temperature - 2000);
float offset2 = 2.5 * t;
float sens2 = 1.25 * t;
// COMMENT OUT < -1500 CORRECTION IF NOT NEEDED
// COMMENT OUT < -1500 CORRECTION IF NOT NEEDED
if (_temperature < -1500)
{
t = (_temperature + 1500) * (_temperature + 1500);
@ -180,7 +181,7 @@ int MS5611_SPI::read(uint8_t bits)
offset -= offset2;
sens -= sens2;
}
// END SECOND ORDER COMPENSATION
// END SECOND ORDER COMPENSATION
}
_pressure = (_D1 * sens * 4.76837158205E-7 - offset) * 3.051757813E-5;
@ -210,6 +211,19 @@ float MS5611_SPI::getPressure() const
};
// EXPERIMENTAL
uint16_t MS5611_SPI::getManufacturer()
{
return readProm(0);
}
// EXPERIMENTAL
uint16_t MS5611_SPI::getSerialCode()
{
return readProm(7) >> 4;
}
void MS5611_SPI::setSPIspeed(uint32_t speed)
{
_SPIspeed = speed;
@ -241,11 +255,11 @@ void MS5611_SPI::setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t se
/////////////////////////////////////////////////////
//
// PRIVATE
// PRIVATE
//
void MS5611_SPI::convert(const uint8_t addr, uint8_t bits)
{
// values from page 3 datasheet - MAX column (rounded up)
// values from page 3 datasheet - MAX column (rounded up)
uint16_t del[5] = {600, 1200, 2300, 4600, 9100};
uint8_t index = bits;
@ -257,7 +271,7 @@ void MS5611_SPI::convert(const uint8_t addr, uint8_t bits)
uint16_t waitTime = del[index];
uint32_t start = micros();
// while loop prevents blocking RTOS
// while loop prevents blocking RTOS
while (micros() - start < waitTime)
{
yield();
@ -268,7 +282,7 @@ void MS5611_SPI::convert(const uint8_t addr, uint8_t bits)
uint16_t MS5611_SPI::readProm(uint8_t reg)
{
// last EEPROM register is CRC - Page 13 datasheet.
// last EEPROM register is CRC - Page 13 datasheet.
uint8_t promCRCRegister = 7;
if (reg > promCRCRegister) return 0;
@ -297,7 +311,7 @@ uint16_t MS5611_SPI::readProm(uint8_t reg)
uint32_t MS5611_SPI::readADC()
{
// command(MS5611_CMD_READ_ADC);
// command(MS5611_CMD_READ_ADC);
uint32_t value = 0;
@ -323,7 +337,7 @@ uint32_t MS5611_SPI::readADC()
value += swSPI_transfer(0x00);
}
digitalWrite(_select, HIGH);
// Serial.println(value, HEX);
// Serial.println(value, HEX);
return value;
}
@ -363,11 +377,36 @@ uint8_t MS5611_SPI::swSPI_transfer(uint8_t val)
digitalWrite(clk, LOW);
}
digitalWrite(dao, LOW);
// Serial.print(" # ");
// Serial.println(value, HEX);
// Serial.print(" # ");
// Serial.println(value, HEX);
return value;
}
void MS5611_SPI::initConstants(uint8_t mathMode)
{
// constants that were multiplied in read() - datasheet page 8
// do this once and you save CPU cycles
//
// datasheet ms5611 | appNote
// mode = 0; | mode = 1
C[0] = 1;
C[1] = 32768L; // SENSt1 = C[1] * 2^15 | * 2^16
C[2] = 65536L; // OFFt1 = C[2] * 2^16 | * 2^17
C[3] = 3.90625E-3; // TCS = C[3] / 2^8 | / 2^7
C[4] = 7.8125E-3; // TCO = C[4] / 2^7 | / 2^6
C[5] = 256; // Tref = C[5] * 2^8 | * 2^8
C[6] = 1.1920928955E-7; // TEMPSENS = C[6] / 2^23 | / 2^23
if (mathMode == 1) // Appnote version for pressure.
{
C[1] = 65536L; // SENSt1
C[2] = 131072L; // OFFt1
C[3] = 7.8125E-3; // TCS
C[4] = 1.5625e-2; // TCO
}
}
// -- END OF FILE --

View File

@ -2,8 +2,8 @@
//
// FILE: MS5611_SPI.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: MS5611 (SPI) Temperature & Humidity library for Arduino
// VERSION: 0.1.1
// PURPOSE: S5611 (SPI) Temperature & Pressure library for Arduino
// URL: https://github.com/RobTillaart/MS5611_SPI
@ -29,11 +29,11 @@
// CS to GND ==> 0x77
#define MS5611_SPI_LIB_VERSION (F("0.1.0 EXPERIMENTAL"))
#define MS5611_SPI_LIB_VERSION (F("0.1.1 EXPERIMENTAL"))
#define MS5611_READ_OK 0
#define MS5611_ERROR_2 2 // TODO ??
#define MS5611_ERROR_2 2 // TODO ??
#define MS5611_NOT_READ -999
@ -53,27 +53,29 @@ public:
explicit MS5611_SPI(uint8_t select, uint8_t dataOut = 255, uint8_t dataIn = 255, uint8_t clock = 255);
bool begin();
bool isConnected();
// reset command + get constants
// returns false if ROM constants == 0;
bool reset();
// reset command + get constants
// mathMode = 0 (default), 1 = factor 2 fix.
// returns false if ROM constants == 0;
bool reset(uint8_t mathMode = 0);
// the actual reading of the sensor;
// returns MS5611_READ_OK upon success
// the actual reading of the sensor;
// returns MS5611_READ_OK upon success
int read(uint8_t bits);
// wrapper, uses the preset oversampling rate.
// wrapper, uses the preset oversampling rate.
inline int read() { return read( (uint8_t) _samplingRate); };
// sets oversampling to a value between 8 and 12
// sets oversampling to a value between 8 and 12
void setOversampling(osr_t samplingRate);
// oversampling rate is in osr_t
// oversampling rate is in osr_t
osr_t getOversampling() const { return (osr_t) _samplingRate; };
// temperature is in ²C
// temperature is in ²C
float getTemperature() const;
// pressure is in mBar
// pressure is in mBar
float getPressure() const;
// OFFSET - 0.3.6
@ -82,10 +84,10 @@ public:
void setTemperatureOffset(float offset = 0) { _temperatureOffset = offset; };
float getTemperatureOffset() { return _temperatureOffset; };
// to check for failure
// to check for failure
int getLastResult() const { return _result; };
// last time in millis() when the sensor has been read.
// last time in millis() when the sensor has been read.
uint32_t lastRead() const { return _lastRead; };
uint32_t getDeviceID() const { return _deviceID; };
@ -93,38 +95,43 @@ public:
void setCompensation(bool flag = true) { _compensation = flag; };
bool getCompensation() { return _compensation; };
// develop functions.
// develop functions.
/*
void setAddress(uint8_t address) { _address = address; }; // RANGE CHECK
uint8_t getAddress() const { return _address; };
uint8_t detectAddress() { todo }; // works with only one on the bus?
*/
// EXPERIMENTAL
uint16_t getManufacturer();
uint16_t getSerialCode();
// speed in Hz
void setSPIspeed(uint32_t speed);
uint32_t getSPIspeed() { return _SPIspeed; };
// debugging
// debugging
bool usesHWSPI() { return _hwSPI; };
// ESP32 specific
// ESP32 specific
#if defined(ESP32)
void selectHSPI() { _useHSPI = true; };
void selectVSPI() { _useHSPI = false; };
bool usesHSPI() { return _useHSPI; };
bool usesVSPI() { return !_useHSPI; };
// to overrule ESP32 default hardware pins
// to overrule ESP32 default hardware pins
void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select);
#endif
private:
protected:
void convert(const uint8_t addr, uint8_t bits);
uint32_t readADC();
uint16_t readProm(uint8_t reg);
int command(const uint8_t command);
void initConstants(uint8_t mathMode);
uint8_t _address;
uint8_t _samplingRate;

View File

@ -8,13 +8,12 @@
# MS5611_SPI
Arduino library (SPI) for MS5611 temperature and pressure sensor.
Arduino library (SPI) for MS5611 pressure (and temperature) sensor.
## Description
The MS5611 is a high resolution temperature and pressure sensor a.k.a GY-63.
The MS5611 is a high resolution pressure (and temperature) sensor a.k.a GY-63.
The high resolution is made possible by oversampling many times.
This library only implements the SPI interface.
@ -23,6 +22,13 @@ Based upon the 0.3.6 version of the I2C library,
see - https://github.com/RobTillaart/MS5611
#### Compatibility
The library should be compatible with MS56XX, MS57xx and MS58xx devices (to be tested).
Some device types will returns only 50% of the pressure value.
This is solved by calling **reset(1)** to select the math used.
#### Self heating
In some configurations especially when using SPI the sensor showed a self heating.
@ -142,8 +148,12 @@ Based upon 0.3.8 of the I2C MS5611 library.
#### Base
- **MS5611_SPI(uint8_t select, uint8_t dataOut = 255, uint8_t dataIn = 255, uint8_t clock = 255)** constructor.
- **bool begin()** initializes internals,
- **reset()** resets the chip and loads constants from its ROM.
- **bool begin()** initializes internals,
- **bool isConnected()** checks device by calling **read()**.
- **bool reset(uint8_t mathMode = 0)** resets the chip and loads constants from its ROM.
Returns false if ROM could not be read.
- mathMode = 0 follows the datasheet math (default).
- mathMode = 1 will adjust for a factor 2 in the pressure math.
- **int read(uint8_t bits)** the actual reading of the sensor.
Number of bits determines the oversampling factor. Returns MS5611_READ_OK upon success.
- **int read()** wraps the **read()** above, uses the preset oversampling (see below).
@ -210,6 +220,13 @@ Having a device-ID can be used in many ways:
Note: this is not an official ID from the device / datasheet, it is made up from calibration data.
#### getManufacturer
The meaning of the manufacturer and serialCode value is unclear.
- **uint16_t getManufacturer()** returns manufacturer private info.
- **uint16_t getSerialCode()** returns serialCode from the PROM\[6].
#### 2nd order pressure compensation
- **setCompensation(bool flag = true)** to enable/desiable the 2nd order compensation.
@ -245,5 +262,16 @@ See examples
## Future
#### must
- update documentation
- follow I2C library.
- investigate internal heating with SPI.
#### should
- proper error handling.
- move all code to .cpp
#### could
- redo lower level functions?
- handle the read + math of temperature first?

View File

@ -7,6 +7,7 @@ MS5611 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
reset KEYWORD2
read KEYWORD2
@ -25,6 +26,12 @@ getPressureOffset KEYWORD2
getDeviceID KEYWORD2
setCompensation KEYWORD2
getCompensation KEYWORD2
getManufacturer KEYWORD2
getSerialCode KEYWORD2
# Instances (KEYWORD2)

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MS5611_SPI.git"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=MS5611_SPI
version=0.1.0
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library (SPI) for MS5611 temperature and pressure sensor