Home        Store        Docs        Blog

MS5837-30BA + Particle Electron

Hello, I’m trying to interface the particle electron with the MS5837-30BA Pressure/Temperature Sensor. I had to change D1/D2 for P1/P2 because these variables are already used as macros to define the pin names on the Particle electron.

The code compiles without any issues but I am unable to see readings from the sensor on the serial monitor. The window only shows the following message:
Screen Shot 2020-02-24 at 1.49.17 AM
How would I fix this problem?

Link to the code

Hello,

Some things are not clear:

  • What hardware are you using? is it an Arduino board?
  • What is the other device connected?
  • What exact part of the code did you change? I can’t find mentions to D0 or D1 there. (and it looks like you linked our repo by mistake)

Also keep in mind that this is an I²C Device, it needs to be connected to the I²C bus of Arduino (A4 and A5 on an Arduino UNO, usually differente on each other board model). Also I²C Buses support multiple devices, so you should be able to connect both your devices to the same pins.

Hello, I am using the Particle Electron board connected with the MS5837-30BA Pressure sensor. I used the code provided by the company and only changed the D1and D2 variables because they are already used as macros to define the pin names on the Particle electron.

[https://github.com/bluerobotics/BlueRobotics_MS5837_Library/blob/master/MS5837.cpp]

(https://github.com/bluerobotics/BlueRobotics_MS5837_Library/blob/master/MS5837.h)

I’m not familiar with those boards. How is the sensor wired to the board?
It should be connected to pins attached to the I2C buses:


Either D0/D1 or C4/C5.

Depending on how Arduino-like these boards are, you may need to do some additional setup of the I2C peripherals (chosing the right I2C bus, for instance).

Take a look at how their examples at the online IDE work, I assume some of them use I²C.

The Particle Electron board is a “cellular Arduino” , which allow developers to use Arduino code to build mobile wireless devices based on GSM cellular connections.

My only issue is that when I run the code provided by the company, I am unable to see readings from the sensor on the serial monitor.

and the window only shows this message:

Connections from the Sensor to the Particle Electron board:
(SDA–> D0, SCL–>D1, 3.3v --> 3.3v, GND–> GND)

How would I fix this problem?

Hi,

Have you figure out your problem ?

Hello, not yet.

Basically the sensor is not initializing correctly and I’m getting this message on the monitor:

Init failed!
Are SDA/SCL connected correctly?
Blue Robotics Bar30: White=SDA, Green=SCL

This is the code I’m using:

bar30.uno

#include <Wire.h>
#include “MS5837.h”

MS5837 sensor;

void setup() {

Serial.begin(9600);

Serial.println(“Starting”);

Wire.begin();

// Initialize pressure sensor
// Returns true if initialization was successful
// We can’t continue with the rest of the program unless we can initialize the sensor
while (!sensor.init()) {
Serial.println(“Init failed!”);
Serial.println(“Are SDA/SCL connected correctly?”);
Serial.println(“Blue Robotics Bar30: White=SDA, Green=SCL”);
Serial.println("\n\n\n");
delay(5000);
}

sensor.setModel(MS5837::MS5837_30BA);
sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
}

void loop() {
// Update pressure and temperature readings
sensor.read();

Serial.print(“Pressure: “);
Serial.print(sensor.pressure());
Serial.println(” mbar”);

Serial.print(“Temperature: “);
Serial.print(sensor.temperature());
Serial.println(” deg C”);

Serial.print(“Depth: “);
Serial.print(sensor.depth());
Serial.println(” m”);

Serial.print(“Altitude: “);
Serial.print(sensor.altitude());
Serial.println(” m above mean sea level”);

delay(1000);
}

MS5837.cpp

#include “MS5837.h”
#include <Wire.h>

#define MS5837_ADDR 0x76
#define MS5837_RESET 0x1E
#define MS5837_ADC_READ 0x00
#define MS5837_PROM_READ 0xA0
#define MS5837_CONVERT_D1_8192 0x4A
#define MS5837_CONVERT_D2_8192 0x5A

const float MS5837::Pa = 100.0f;
const float MS5837::bar = 0.001f;
const float MS5837::mbar = 1.0f;

const uint8_t MS5837::MS5837_30BA = 0;
const uint8_t MS5837::MS5837_02BA = 1;

MS5837::MS5837() {
fluidDensity = 1029;
}

bool MS5837::init() {
// Reset the MS5837, per datasheet
Wire.beginTransmission(MS5837_ADDR);
Wire.write(MS5837_RESET);
Wire.endTransmission();

// Wait for reset to complete
delay(10);

// 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();
}

// Verify that data is correct with CRC
uint8_t crcRead = C[0] >> 12;
uint8_t crcCalculated = crc4(C);

if ( crcCalculated == crcRead ) {
	return true; // Initialization success
}

return false; // CRC fail

}

void MS5837::setModel(uint8_t model) {
_model = model;
}

void MS5837::setFluidDensity(float density) {
fluidDensity = density;
}

void MS5837::read() {
// Request D1 conversion
Wire.beginTransmission(MS5837_ADDR);
Wire.write(MS5837_CONVERT_D1_8192);
Wire.endTransmission();

delay(20); // Max conversion time per datasheet

Wire.beginTransmission(MS5837_ADDR);
Wire.write(MS5837_ADC_READ);
Wire.endTransmission();

Wire.requestFrom(MS5837_ADDR,3);
P1 = 0;
P1 = Wire.read();
P1 = (P1 << 8) | Wire.read();
P1 = (P1 << 8) | Wire.read();

// Request D2 conversion
Wire.beginTransmission(MS5837_ADDR);
Wire.write(MS5837_CONVERT_D2_8192);
Wire.endTransmission();

delay(20); // Max conversion time per datasheet

Wire.beginTransmission(MS5837_ADDR);
Wire.write(MS5837_ADC_READ);
Wire.endTransmission();

Wire.requestFrom(MS5837_ADDR,3);
P2 = 0;
P2 = Wire.read();
P2 = (P2 << 8) | Wire.read();
P2 = (P2 << 8) | Wire.read();

calculate();

}

void MS5837::calculate() {
// Given C1-C6 and D1, D2, calculated TEMP and P
// Do conversion first and then second order temp compensation

int32_t dT = 0;
int64_t SENS = 0;
int64_t OFF = 0;
int32_t SENSi = 0;
int32_t OFFi = 0;  
int32_t Ti = 0;    
int64_t OFF2 = 0;
int64_t SENS2 = 0;

// Terms called
dT = P2-uint32_t(C[5])*256l;
if ( _model == MS5837_02BA ) {
	SENS = int64_t(C[1])*65536l+(int64_t(C[3])*dT)/128l;
	OFF = int64_t(C[2])*131072l+(int64_t(C[4])*dT)/64l;
	P = (P1*SENS/(2097152l)-OFF)/(32768l);
} else {
	SENS = int64_t(C[1])*32768l+(int64_t(C[3])*dT)/256l;
	OFF = int64_t(C[2])*65536l+(int64_t(C[4])*dT)/128l;
	P = (P1*SENS/(2097152l)-OFF)/(8192l);
}

// Temp conversion
TEMP = 2000l+int64_t(dT)*C[6]/8388608LL;

//Second order compensation
if ( _model == MS5837_02BA ) {
	if((TEMP/100)<20){         //Low temp
		Serial.println("here");
		Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL);
		OFFi = (31*(TEMP-2000)*(TEMP-2000))/8;
		SENSi = (63*(TEMP-2000)*(TEMP-2000))/32;
	}
} else {
	if((TEMP/100)<20){         //Low temp
		Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL);
		OFFi = (3*(TEMP-2000)*(TEMP-2000))/2;
		SENSi = (5*(TEMP-2000)*(TEMP-2000))/8;
		if((TEMP/100)<-15){    //Very low temp
			OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l);
			SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l);
		}
	}
	else if((TEMP/100)>=20){    //High temp
		Ti = 2*(dT*dT)/(137438953472LL);
		OFFi = (1*(TEMP-2000)*(TEMP-2000))/16;
		SENSi = 0;
	}
}

OFF2 = OFF-OFFi;           //Calculate pressure and temp second order
SENS2 = SENS-SENSi;

if ( _model == MS5837_02BA ) {
	TEMP = (TEMP-Ti);
	P = (((P1*SENS2)/2097152l-OFF2)/32768l)/100;
} else {
	TEMP = (TEMP-Ti);
	P = (((P1*SENS2)/2097152l-OFF2)/8192l)/10;
}

}

float MS5837::pressure(float conversion) {
return P*conversion;
}

float MS5837::temperature() {
return TEMP/100.0f;
}

float MS5837::depth() {
return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665);
}

float MS5837::altitude() {
return (1-pow((pressure()/1013.25),.190284))145366.45.3048;
}

uint8_t MS5837::crc4(uint16_t n_prom) {
uint16_t n_rem = 0;

n_prom[0] = ((n_prom[0]) & 0x0FFF);
n_prom[7] = 0;

for ( uint8_t i = 0 ; i < 16; i++ ) {
	if ( i%2 == 1 ) {
		n_rem ^= (uint16_t)((n_prom[i>>1]) & 0x00FF);
	} else {
		n_rem ^= (uint16_t)(n_prom[i>>1] >> 8);
	}
	for ( uint8_t 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 = ((n_rem >> 12) & 0x000F);

return n_rem ^ 0x00;

}

MS5837.h

#ifndef MS5837_H_BLUEROBOTICS
#define MS5837_H_BLUEROBOTICS

#include “Arduino.h”

class MS5837 {
public:
static const float Pa;
static const float bar;
static const float mbar;

static const uint8_t MS5837_30BA;
static const uint8_t MS5837_02BA;

MS5837();

bool init();

/** Set model of MS5837 sensor. Valid options are MS5837::MS5837_30BA (default)
 * and MS5837::MS5837_02BA.
 */
void setModel(uint8_t model);

/** Provide the density of the working fluid in kg/m^3. Default is for 
 * seawater. Should be 997 for freshwater.
 */
void setFluidDensity(float density);

/** The read from I2C takes up to 40 ms, so use sparingly is possible.
 */
void read();

/** Pressure returned in mbar or mbar*conversion rate.
 */
float pressure(float conversion = 1.0f);

/** Temperature returned in deg C.
 */
float temperature();

/** Depth returned in meters (valid for operation in incompressible
 *  liquids only. Uses density that is set for fresh or seawater.
 */
float depth();

/** Altitude returned in meters (valid for operation in air only).
 */
float altitude();

private:
uint16_t C[8];
uint32_t P1, P2;
int32_t TEMP;
int32_t P;
uint8_t _model;

float fluidDensity;

/** Performs calculations per the sensor data sheet for conversion and
 *  second order compensation.
 */
void calculate();

uint8_t crc4(uint16_t n_prom[]);

};

#endif

The Electron boards don’t have built-in pull-up resistors on SCL and SDA and neither does the Bar30 sensor module. You might try adding pull-ups to VCC on SCL and SDA and see if that solves it.