ms5611: Initial implementation

Signed-off-by: Henry Bruce <henry.bruce@intel.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Henry Bruce 2016-07-22 15:52:55 -07:00 committed by Mihai Tudor Panu
parent d79799bab9
commit 98e3621c93
9 changed files with 449 additions and 0 deletions

View File

@ -268,6 +268,7 @@ add_example (bmp280)
add_example (bno055) add_example (bno055)
add_example (l3gd20) add_example (l3gd20)
add_example (bmx055) add_example (bmx055)
add_example (ms5611)
# These are special cases where you specify example binary, source file and module(s) # These are special cases where you specify example binary, source file and module(s)
include_directories (${PROJECT_SOURCE_DIR}/src) include_directories (${PROJECT_SOURCE_DIR}/src)

63
examples/c++/ms5611.cxx Normal file
View File

@ -0,0 +1,63 @@
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include "ms5611.hpp"
static int is_running = 0;
void
sig_handler(int signo)
{
printf("got signal\n");
if (signo == SIGINT) {
is_running = 1;
}
}
//! [Interesting]
int
main(int argc, char **argv)
{
upm::MS5611* sensor = new upm::MS5611(0);
signal(SIGINT, sig_handler);
while (!is_running) {
int value = sensor->getTemperatureCelsius();
std::cout << "Temperature = " << value << "C" << std::endl;
value = sensor->getPressurePa();
std::cout << "Pressure = " << value << "Pa" << std::endl;
sleep(1);
}
std::cout << "exiting application" << std::endl;
delete sensor;
return 0;
}
//! [Interesting]

View File

@ -0,0 +1,50 @@
/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var factory = require('jsupm_ms5611');
// Instantiate a MS5611 instance using default i2c bus and address
var sensor = new factory.MS5611();
// now output data every 250 milliseconds
setInterval(function()
{
var temperature = sensor.getTemperatureCelsius();
var pressure = sensor.getPressurePa();
console.log("Temperature: " + temperature + " C");
console.log("Pressure: " + pressure + " Pa");
}, 250);
// exit on ^C
process.on('SIGINT', function()
{
sensor = null;
sensorObj.cleanUp();
sensorObj = null;
console.log("Exiting.");
process.exit(0);
});

View File

@ -0,0 +1,6 @@
include_directories(..)
set (libname "ms5611")
set (libdescription “Pressure and temperature sensor”)
set (module_src ${libname}.cxx)
set (module_hpp ${libname}.hpp)
upm_module_init()

View File

@ -0,0 +1,8 @@
%module javaupm_ms5611
%include "../upm.i"
%{
#include "ms5611.hpp"
%}
%include "ms5611.hpp"

View File

@ -0,0 +1,8 @@
%module jsupm_ms5611
%include "../upm.i"
%{
#include "ms5611.hpp"
%}
%include "ms5611.hpp"

215
src/ms5611/ms5611.cxx Normal file
View File

@ -0,0 +1,215 @@
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include "ms5611.hpp"
// Used to prevent silent failure in mraa_i2c_write()
// Value come from I2C_SMBUS_I2C_BLOCK_MAX in i2c driver
#define MAX_I2C_WRITE_SIZE 32
#define MS5611_CMD_ADC_READ (0x00)
#define MS5611_CMD_RESET (0x1E)
#define MS5611_CMD_CONV_D1 (0x40)
#define MS5611_CMD_CONV_D2 (0x50)
#define MS5611_CMD_READ_PROM (0xA0)
#define MS5611_OSR_ULTRA_LOW_POWER 0x00
#define MS5611_OSR_LOW_POWER 0x02
#define MS5611_OSR_STANDARD 0x04
#define MS5611_OSR_HIGH_RES 0x06
#define MS5611_OSR_ULTRA_HIGH_RES 0x08
#define MS5611_PROM_SIZE 8
using namespace upm;
MS5611::MS5611(int i2cBus, int address)
{
status = mraa::ERROR_INVALID_RESOURCE;
i2c = new mraa::I2c(2);
this->address = address;
i2c->address(address);
prom = new uint16_t[MS5611_PROM_SIZE];
status = i2c->writeByte(MS5611_CMD_RESET);
if (status != mraa::SUCCESS)
UPM_THROW("Reset failed.");
delayms(5);
for (int i = 0; i < MS5611_PROM_SIZE; ++i) {
uint8_t buf[2];
int bytesRead = i2c->readBytesReg(MS5611_CMD_READ_PROM + 2*i, buf, 2);
if (bytesRead != 2)
UPM_THROW("PROM address failed.");
prom[i] = buf[0] << 8;
prom[i] |= buf[1];
// printf("Read PROM entry %d = %04x\n", i, prom[i]);
}
// printf("CRC = %X\n", promCrc4());
if (promCrc4() != (prom[7] & 0x000F))
UPM_THROW("PROM checksum error.");
setOverSampling(ULTRA_HIGH_RES);
}
MS5611::~MS5611()
{
delete[] prom;
delete i2c;
}
int MS5611::promCrc4() {
unsigned int n_rem;
unsigned int crc_read;
unsigned char n_bit;
n_rem = 0x00;
crc_read = prom[7];
prom[7]=(0xFF00 & (prom[7]));
for (int cnt = 0; cnt < 16; cnt++) {
if (cnt%2 == 1) {
n_rem ^= (unsigned short) ((prom[cnt>>1]) & 0x00FF);
} else {
n_rem ^= (unsigned short) (prom[cnt>>1]>>8);
}
for (n_bit = 8; n_bit > 0; n_bit--) {
if (n_rem & (0x8000)) {
n_rem = (n_rem << 1) ^ 0x3000;
} else {
n_rem = (n_rem << 1);
}
}
}
n_rem= (0x000F & (n_rem >> 12));
prom[7]=crc_read;
return (n_rem ^ 0x0);
}
// Set oversampling value
void MS5611::setOverSampling(OsrMode osrMode)
{
switch (osrMode)
{
case ULTRA_LOW_POWER:
osr = MS5611_OSR_ULTRA_LOW_POWER;
samplePeriod = 1;
break;
case LOW_POWER:
osr = MS5611_OSR_LOW_POWER;
samplePeriod = 2;
break;
case STANDARD:
osr = MS5611_OSR_STANDARD;
samplePeriod = 3;
break;
case HIGH_RES:
osr = MS5611_OSR_HIGH_RES;
samplePeriod = 5;
break;
case ULTRA_HIGH_RES:
osr = MS5611_OSR_ULTRA_HIGH_RES;
samplePeriod = 10;
break;
}
}
void MS5611::delayms(int millisecs)
{
struct timespec sleepTime, rem;
uint64_t nanosecs = 1000ULL * millisecs;
sleepTime.tv_sec = millisecs / 1000;
sleepTime.tv_nsec = (millisecs % 1000) * 1000000;
while ((nanosleep( &sleepTime, &sleepTime ) != 0 ) && ( errno == EINTR ) );
}
uint32_t MS5611::readADC(int adcReg)
{
uint32_t value;
uint8_t buf[3];
i2c->address(address);
status = i2c->writeByte(adcReg + osr);
if (status != mraa::SUCCESS)
UPM_THROW("Convert D2 failed");
delayms(100);
int bytesRead = i2c->readBytesReg(MS5611_CMD_ADC_READ, buf, 3);
if (bytesRead != 3)
UPM_THROW("ADC read failed");
// printf("%02X%02X%02X\n", buf[0], buf[1], buf[2]);
value = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2];
return value;
}
uint32_t MS5611::readRawTemperature()
{
return readADC(MS5611_CMD_CONV_D2);
}
uint32_t MS5611::readRawPressure()
{
return readADC(MS5611_CMD_CONV_D1);
}
int MS5611::getTemperatureCelsius()
{
uint32_t D2 = readRawTemperature();
int64_t dT = D2 - ((uint64_t)prom[5] << 8);
int32_t temp = 2000 + ((int64_t)dT * (int64_t)prom[6]) / (int64_t)(1 << 23);
return (temp + 50) / 100;
}
int MS5611::getPressurePa()
{
int32_t rawTemp = readRawTemperature();
int32_t rawPressure = readRawPressure();
int64_t dT = rawTemp - ((uint64_t)prom[5] << 8);
int64_t offset = ((uint32_t)prom[2] << 16) + ((dT * (prom[4]) >> 7)); //was OFF = (C[2] << 17) + dT * C[4] / (1 << 6);
int64_t scaler = ((uint32_t)prom[1] << 15) + ((dT * (prom[3]) >> 8)); //was SENS = (C[1] << 16) + dT * C[3] / (1 << 7);
int32_t temp = 2000 + (int64_t)dT * (int64_t)prom[6] / (int64_t)(1 << 23);
if(temp < 2000) {
float T1 = (temp - 2000) * (temp - 2000);
int64_t offsetDelta = (5 * T1) / 2;
int64_t scalerDelta = (5 * T1) / 4;
if(temp < -1500) {
T1 = (temp + 1500) * (temp + 1500);
offsetDelta += 7 * T1;
scalerDelta += 11 * T1 / 2;
}
offset -= offsetDelta;
scaler -= scalerDelta;
}
int pressure = ((((int64_t)rawPressure * scaler ) >> 21) - offset) / (double) (1 << 15);
return pressure;
}

89
src/ms5611/ms5611.hpp Normal file
View File

@ -0,0 +1,89 @@
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2016 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "upm/iPressureSensor.hpp"
#include "upm/iTemperatureSensor.hpp"
#include "mraa/i2c.hpp"
namespace upm
{
#define MS5611_ADDRESS 0x76
/**
* @brief ms5611 Barometric Pressure Sensor library
* @defgroup ms5611 libupm-ms5611
* @ingroup meas i2c temp pressure
*/
/**
* @brief API for MS5611 Barometric Pressure Sensor library
*
* Measurement Specialties
* [MS5611-01BA03](http://www.te.com/usa-en/product-CAT-BLPS0036.html)
* Automotive Catalog Low-EMI, High-Performance 4-Channel LED Driver
*
* @library ms5611
* @sensor ms5611
* @comname Meas-Spec MS5611 Barometric Pressure Sensor library
* @altname MS5611
* @type temp pressure
* @man meas
* @con i2c
* @if ilightcontroller
*
*/
class MS5611 : public IPressureSensor, ITemperatureSensor
{
public:
enum OsrMode
{
ULTRA_LOW_POWER, LOW_POWER, STANDARD, ULTRA_HIGH_RES, HIGH_RES
};
MS5611(int i2cBus = 0, int address = MS5611_ADDRESS);
~MS5611();
const char* getModuleName() { return "ms5611"; }
void setOverSampling(OsrMode osrMode);
int getTemperatureCelsius();
int getPressurePa();
private:
int promCrc4();
uint32_t readADC(int adcReg);
void delayms(int millisecs);
uint32_t readRawPressure();
uint32_t readRawTemperature();
mraa::Result status;
mraa::I2c* i2c;
int address;
uint16_t *prom;
int osr;
int samplePeriod;
};
}

View File

@ -0,0 +1,9 @@
%module pyupm_ms5611
%include "../upm.i"
%feature("autodoc", "3");
%include "ms5611.hpp"
%{
#include "ms5611.hpp"
%}