Community forums

MS5611 jumping values


#1

Hi,

I recently received the MS5611 breakout board and tried to hook it up to the Arduino UNO. After some attempts with code I found online I decided to build my own. It seems to be working, except for an occasional jump in the temperature and pressure values caused by steps in D1 and D2 as seen in the picture:


It looks like it may be a discretization problem. Has anyone seen this before? Could it be my code or do you suspect a hardware problem?

My code:

[code]/*
Some parts based on code from 2011 Fabio Varesano
*/

#include “SSTMS5611.h”

SSTMS5611::SSTMS5611() {
;
}

void SSTMS5611::init(uint8_t address) {

_addr =  address;
temperature = 0;
pressure = 0;

_OSR = SSTMS5611_DEFAULT_OSR; //default oversampling rate
_conversionStarted = false;
_conversionType = D2_CONVERSION;
_conversionStartTime = 0;
_conversionInterval = SSTMS5611_DEFAULT_CONVERSION_INTERVAL;

// disable internal pullups of the ATMEGA which Wire enable by default
#if defined(AVR_ATmega168) || defined(AVR_ATmega8) || defined(AVR_ATmega328P)
// deactivate internal pull-ups for twi
// as per note from atmega8 manual pg167
cbi(PORTC, 4);
cbi(PORTC, 5);
#else
// deactivate internal pull-ups for twi
// as per note from atmega128 manual pg204
cbi(PORTD, 0);
cbi(PORTD, 1);
#endif

reset(); // reset the device to populate its internal PROM registers
delay(1000); // some safety time
if(readPROM()==-1) // reads the PROM into object variables for later use
{
Serial.print(" ERROR READING PROM VALUES for MS5611 Device…");
}

startConversion();
_conversionType = D1_CONVERSION;
delay(_conversionInterval);
update();

if(debug)
{

  Serial.print(" PROM Values: ");
  Serial.print(_C[0],DEC);
  Serial.print(" ");
  Serial.print(_C[1],DEC);
  Serial.print(" ");
  Serial.print(_C[2],DEC);
  Serial.print(" ");
  Serial.print(_C[3],DEC);
  Serial.print(" ");
  Serial.print(_C[4],DEC);
  Serial.print(" ");
  Serial.print(_C[5],DEC);
  Serial.println();
  Serial.println();

}

}

/**

  • Send a reset command to the device. With the reset command the device
  • populates its internal registers with the values read from the PROM.
    */
    void SSTMS5611::reset() {
    Wire.beginTransmission(_addr);
    Wire.write(SSTMS5611_RESET);
    Wire.endTransmission();
    }

/**

  • Reads factory calibration and store it into object variables.
    */
    int SSTMS5611::readPROM() {
    for (int i=0;i<SSTMS5611_PROM_REG_COUNT;i++) {
    Wire.beginTransmission(_addr);
    Wire.write(SSTMS5611_PROM_BASE_ADDR + (i * SSTMS5611_PROM_REG_SIZE));
    Wire.endTransmission();

    Wire.beginTransmission(_addr);
    Wire.requestFrom(_addr, (uint8_t) SSTMS5611_PROM_REG_SIZE);
    if(Wire.available()) {
    _C* = Wire.read() << 8 | Wire.read();

    //DEBUG_PRINT(_C*);
    }
    else {
    return -1; // error reading the PROM or communicating with the device
    }
    }
    return 0;
    }

void SSTMS5611::update() {

if((millis() - _conversionStartTime) >= _conversionInterval) // time enough has passed to finish conversion
{
	uint32_t conversion = getConversion();
	
	startConversion();
	
	if(conversion != 0)
	{
		if(_conversionType == D1_CONVERSION)
		{
			D1 = conversion;
			_conversionType = D2_CONVERSION;
			calculatePressure();
			
			if(debug)
			{
				Serial.print(" D1: ");
				Serial.print(D1,DEC);
			}
			
		}
		else
		{
			D2 = conversion;
			_conversionType = D1_CONVERSION;
			calculateTemperature();
			
			if(debug)
			{
				Serial.print(" D2: ");
				Serial.print(D2,DEC);
			}
		}
		
	}
	
	
	
}

}

void SSTMS5611::startConversion() {

uint8_t conversionCommand;

if(_conversionType == D2_CONVERSION)
{
	conversionCommand = SSTMS5611_D1 + _OSR; //see page 9, figure 4 on datasheet
}
else
{
	conversionCommand = SSTMS5611_D2 + _OSR;
}

Wire.beginTransmission(_addr);
Wire.write(conversionCommand);
Wire.endTransmission();
_conversionStartTime = millis();

}

uint32_t SSTMS5611::getConversion() {

unsigned long conversion = 0;

// start read sequence
Wire.beginTransmission(_addr);
Wire.write(0);
Wire.endTransmission();

Wire.beginTransmission(_addr);
Wire.requestFrom(_addr, (uint8_t) SSTMS5611_D1D2_SIZE);
if(Wire.available()) 
{
	conversion = Wire.read() * 65536 + Wire.read() * 256 + Wire.read();
}
else 
{
	conversion = 0;
}

return conversion;

}

void SSTMS5611::calculateTemperature() {

var_dT = D2 - (((int32_t)_C[4]) << 8);
int64_t var_debug = ((int64_t)var_dT )*((int64_t)_C[5]);
var_TEMP = 2000+(var_debug/8388608); //2000 + (((int64_t)var_dT * _C[5])) >>23);
temperature = ((float)var_TEMP)/100;

/*if(debug)
{
	Serial.print(" D2: ");
	Serial.print((int32_t)D2);
	Serial.print(" dT: ");
	Serial.print((unsigned long)var_dT);
	Serial.print(" Debug: ");
	Serial.print((unsigned long) (var_debug));
	Serial.print(" TEMP: ");
	Serial.print((unsigned long)var_TEMP);
}*/

}

void SSTMS5611::calculatePressure() {
int64_t C2_64 = ((int64_t)_C[1]) ;
int64_t C4_64 = (int64_t)_C[3];
int64_t C1_64 = ((int64_t)_C[0]) ;
int64_t C3_64 = ((int64_t)_C[2]);

int64_t dT_64 = (int64_t)var_dT;

var_OFF = (C2_64 << 16) + ((C4_64*dT_64) >> 7);
var_SENS = (C1_64 << 15)+ ((C3_64*dT_64) >> 8);
var_P = ((((int64_t)D1 * var_SENS) >> 21) - var_OFF) >> 15;
pressure = ((float)var_P)/100;

/*if(debug)
{
	Serial.print(" D1: ");
	Serial.print((int32_t)D1);
	Serial.print(" OFF: ");
	Serial.print((int32_t)(var_OFF/1000000));
	Serial.print(" SENS: ");
	Serial.print((int32_t)(var_SENS/1000000));
	Serial.print(" P: ");
	Serial.print((int32_t)var_P);
}*/

}

void SSTMS5611::setOSR(uint8_t OSR) {
_OSR = OSR;
}

void SSTMS5611::setConversionInterval(uint8_t interval_ms) {
_conversionInterval = interval_ms;
}[/code]**


#2

Here is a sample code I’ve written.

Give it a try.

[code]
/*****************************************
MS5611 Sensor

Code example writen by Leo Nutz

© 2012 www.ALTDuino.de
******************************************/

#include <Wire.h>

#define ADDRESS 0x77 // or 0x76 sensor address

uint32_t D1 = 0;
uint32_t D2 = 0;
int64_t dT = 0;
int64_t OFF = 0;
int64_t SENS = 0;
int32_t T = 0;
int32_t P = 0;
uint16_t C[7];

float Temperature;
float Pressure;

void setup()
{
// Disable internal pullups because 10Kohms are on the breakout
PORTC |= (1 << 4);
PORTC |= (1 << 5);

Wire.begin();
Serial.begin(9600);
delay(100);
initial(ADDRESS);
}

void loop()
{
D2 = read_SENSOR(ADDRESS, 0x58); // get raw temperature value from sensor
D1 = read_SENSOR(ADDRESS, 0x48); // get raw pressure value from sensor

dT = D2 - ((int64_t)C[5] << 8);
OFF = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
SENS = ((int64_t)C[1] << 15) + ((dT * C[3]) >> 8);

T = (((int64_t)dT * (int64_t)C[6]) >> 23) + 2000; // calculate temperature

if(T < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1    = pow(dT, 2) / 2147483648;
OFF1  = 5 * (((T - 2000) << 2) >> 2);
SENS1 = 5 * (((T - 2000) << 2) >> 4);

if(T < -1500) // if temperature lower than -15 Celsius 
{
  OFF1  = OFF1  +  7 *  ((T + 1500) << 2);
  SENS1 = SENS1 + 11 * (((T + 1500) << 2) >> 2);
} // lower than -15 celsius

T    -=    T1;
OFF  -=  OFF1; 
SENS -= SENS1;

}

P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15; // calculate pressure

Temperature = (float)T / 100;
Pressure = (float)P / 100;

Serial.print(“TEMPERATURE = “); Serial.print(Temperature); Serial.print(” C : PRESSURE = “); Serial.print(Pressure); Serial.println(” mbar”);

delay(100);
}

uint32_t read_SENSOR(uint8_t address, uint8_t code)
{
uint32_t value = 0;
// initialize pressure/temperature conversion
Wire.beginTransmission(address);
Wire.write(code);
Wire.endTransmission();
delay(10);
// send conversion command, start read sequence
Wire.beginTransmission(address);
Wire.write(0x00); // read command
Wire.endTransmission();
// set device address and start read sequence
Wire.requestFrom(address, (uint8_t)3);
if (Wire.available() >= 3)
{
for(uint8_t i = 0; i < 3; i++)
{
value = (value << 8) | Wire.read();
}
}
return value;
} // end read_SENSOR

void initial(uint8_t address)
{

Serial.println();
Serial.println(“PROM COEFFICIENTS”);

Wire.beginTransmission(address);
Wire.write(0x1E); // reset
Wire.endTransmission();
delay(10);

for (int i = 0; i < 6; i++) {

Wire.beginTransmission(address);
Wire.write(0xA2 + (i * 2));
Wire.endTransmission();

Wire.requestFrom(address, (uint8_t)6);
delay(10);
if(Wire.available())
{
   C* = Wire.read() << 8 | Wire.read();
}
else {
  Serial.println("Error reading PROM 1");
}
Serial.print("C"); Serial.print(i); Serial.print(" = "); Serial.println(C*);

}
Serial.println();
}
[/code]**


#3

I’m posting this reply as we came across the same issue as the original poster, and have now solved it. The solution may help someone else in the future.
We’re using a MS5611-BA03 on SPI on a different board (a Pixhawk autopilot). We had a log from a user that showed unusual temperature/pressure values when flying on a very hot day. We then did bench tests up to high temperatures and got the same type of graph for D1/D2 that rput shows above.
We then noticed that it was the bottom bit of the top byte of the 24 bit D1 that was getting lost - the top byte was always even, when we expected it to be a smooth progression as the sensor cooled. We also found that if we increased the SPI bus speed from 5MHz to 20MHz that the problem disappeared.
We solved the problem by changing the GPIO speed settings on the CLK, MISO and MOSI pins. They were at 2MHz, when they should be at 50MHz . Changing to 50MHz fixed the problem over the whole operating temperature range of the MS5611. It seems that we need quite sharp edges on the signal for the MS5611 to be happy.
We also found that SPI MODE3 was much more reliable than MODE0.
We’re following up with MS to try to understand the results.
Cheers, Tridge


#4

Tridge,

could you try the code from my above post, just out of curiosity.

Edit: Nevermind, your running in SPI and not in I2C mode.

Thanks.

Leo


#5

Hi Leo,
i’ve just tried your code and my temperature and pression are correct and stable
however how can i make to read the altitude ?
thanks for you help


#6

Give this a try:

[code]/*****************************************
MS5611 Sensor

Code example writen by Leo Nutz

with altitude calculation (1/2015)

© 2012 www.ALTDuino.de

******************************************/

#include <Wire.h>

#define ADDRESS 0x77 // or 0x76 sensor address

uint32_t D1 = 0;
uint32_t D2 = 0;
int64_t dT = 0;
int64_t OFF = 0;
int64_t SENS = 0;
int32_t T = 0;
int32_t P = 0;
uint16_t C[7];

float Temperature;
float Pressure;
float Altitude;

void setup()
{
// Disable internal pullups because 10Kohms are on the breakout
PORTC |= (1 << 4);
PORTC |= (1 << 5);

Wire.begin();
Serial.begin(9600);
delay(100);
initial(ADDRESS);
}

void loop()
{
D2 = read_SENSOR(ADDRESS, 0x58); // get raw temperature value from sensor
D1 = read_SENSOR(ADDRESS, 0x48); // get raw pressure value from sensor

dT = D2 - ((int64_t)C[5] << 8);
OFF = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
SENS = ((int64_t)C[1] << 15) + ((dT * C[3]) >> 8);

T = (((int64_t)dT * (int64_t)C[6]) >> 23) + 2000; // calculate temperature

if(T < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1    = pow(dT, 2) / 2147483648;
OFF1  = 5 * (((T - 2000) << 2) >> 2);
SENS1 = 5 * (((T - 2000) << 2) >> 4);

if(T < -1500) // if temperature lower than -15 Celsius 
{
  OFF1  = OFF1  +  7 *  ((T + 1500) << 2);
  SENS1 = SENS1 + 11 * (((T + 1500) << 2) >> 2);
} // lower than -15 celsius

T    -=    T1;
OFF  -=  OFF1; 
SENS -= SENS1;

}

P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15; // calculate pressure

Temperature = (float)T / 100;
Pressure = (float)P / 100;
Altitude = (pow(1013.25f / Pressure, 0.190223f) - 1.0f) * 44330.08f;

Serial.print(“TEMPERATURE = “); Serial.print(Temperature); Serial.print(” C : PRESSURE = “); Serial.print(Pressure); Serial.print(” mbar”); Serial.print(" C : ALTITUDE = “); Serial.print(Altitude); Serial.println(” meters");

delay(100);
}

uint32_t read_SENSOR(uint8_t address, uint8_t code)
{
uint32_t value = 0;
// initialize pressure/temperature conversion
Wire.beginTransmission(address);
Wire.write(code);
Wire.endTransmission();
delay(10);
// send conversion command, start read sequence
Wire.beginTransmission(address);
Wire.write(0x00); // read command
Wire.endTransmission();
// set device address and start read sequence
Wire.requestFrom(address, (uint8_t)3);
if (Wire.available() >= 3)
{
for(uint8_t i = 0; i < 3; i++)
{
value = (value << 8) | Wire.read();
}
}
return value;
} // end read_SENSOR

void initial(uint8_t address)
{

Serial.println();
Serial.println(“PROM COEFFICIENTS”);

Wire.beginTransmission(address);
Wire.write(0x1E); // reset
Wire.endTransmission();
delay(10);

for (int i = 0; i < 6; i++) {

Wire.beginTransmission(address);
Wire.write(0xA2 + (i * 2));
Wire.endTransmission();

Wire.requestFrom(address, (uint8_t)6);
delay(10);
if(Wire.available())
{
   C* = Wire.read() << 8 | Wire.read();
}
else {
  Serial.println("Error reading PROM 1");
}
Serial.print("C"); Serial.print(i); Serial.print(" = "); Serial.println(C*);

}
Serial.println();
}[/code]**


#7

Thanks Leo
And with this code you get a stable altitude ? How many centimeters variations ?
The altitude result is well in meter, centimeter ?
I will try this this evening


#8

i have just tried your code, but the altitude is not stable …
the values jump of + - 1 meter !


#9

Here a sample of my output:

TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.86 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.65 mbar C : ALTITUDE = 586.08 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.69 mbar C : ALTITUDE = 585.71 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.69 mbar C : ALTITUDE = 585.71 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters TEMPERATURE = 22.87 C : PRESSURE = 945.68 mbar C : ALTITUDE = 585.80 meters TEMPERATURE = 22.87 C : PRESSURE = 945.68 mbar C : ALTITUDE = 585.80 meters TEMPERATURE = 22.87 C : PRESSURE = 945.68 mbar C : ALTITUDE = 585.80 meters TEMPERATURE = 22.87 C : PRESSURE = 945.66 mbar C : ALTITUDE = 585.99 meters TEMPERATURE = 22.87 C : PRESSURE = 945.68 mbar C : ALTITUDE = 585.80 meters TEMPERATURE = 22.87 C : PRESSURE = 945.67 mbar C : ALTITUDE = 585.90 meters

How does yours look like?


#10

Hi Léo,
here my results for coefficients (strange it’s write C0 to C5 and in the data sheet it’s write C1 to C6) :

PROM COEFFICIENTS C0 = 46730 C1 = 48786 C2 = 27951 C3 = 25049 C4 = 30995 C5 = 27214

here my measures results :

TEMPERATURE = 19.96 C : PRESSURE = 985.22 mbar C : ALTITUDE = 237.20 meters TEMPERATURE = 19.96 C : PRESSURE = 985.22 mbar C : ALTITUDE = 237.20 meters TEMPERATURE = 19.96 C : PRESSURE = 985.23 mbar C : ALTITUDE = 237.11 meters TEMPERATURE = 19.96 C : PRESSURE = 985.21 mbar C : ALTITUDE = 237.28 meters TEMPERATURE = 19.96 C : PRESSURE = 985.23 mbar C : ALTITUDE = 237.11 meters TEMPERATURE = 19.96 C : PRESSURE = 985.24 mbar C : ALTITUDE = 237.02 meters TEMPERATURE = 19.96 C : PRESSURE = 985.21 mbar C : ALTITUDE = 237.28 meters TEMPERATURE = 19.96 C : PRESSURE = 985.22 mbar C : ALTITUDE = 237.20 meters TEMPERATURE = 19.96 C : PRESSURE = 985.20 mbar C : ALTITUDE = 237.37 meters TEMPERATURE = 19.96 C : PRESSURE = 985.21 mbar C : ALTITUDE = 237.28 meters TEMPERATURE = 19.96 C : PRESSURE = 985.24 mbar C : ALTITUDE = 237.02 meters TEMPERATURE = 19.96 C : PRESSURE = 985.21 mbar C : ALTITUDE = 237.28 meters TEMPERATURE = 19.96 C : PRESSURE = 985.25 mbar C : ALTITUDE = 236.94 meters TEMPERATURE = 19.96 C : PRESSURE = 985.22 mbar C : ALTITUDE = 237.20 meters

there is again near 40cm of variations, but it’s best as before

but for that i have must change this :

[code]void loop()
{
D2 = read_SENSOR(ADDRESS, 0x58); // get raw temperature value from sensor
D1 = read_SENSOR(ADDRESS, 0x48); // get raw pressure value from sensor

dT = D2 - ((int64_t)C[5] << 8);
OFF = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
SENS = ((int64_t)C[1] << 15) + ((dT * C[3]) >> 8);

T = (((int64_t)dT * (int64_t)C[6]) >> 23) + 2000; // calculate temperature

if(T < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1    = pow(dT, 2) / 2147483648;
OFF1  = 5 * (((T - 2000) << 2) >> 2);
SENS1 = 5 * (((T - 2000) << 2) >> 4);

if(T < -1500) // if temperature lower than -15 Celsius 
{
  OFF1  = OFF1  +  7 *  ((T + 1500) << 2);
  SENS1 = SENS1 + 11 * (((T + 1500) << 2) >> 2);
} // lower than -15 celsius

T    -=    T1;
OFF  -=  OFF1; 
SENS -= SENS1;

}

P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15; // calculate pressure
[/code]

by this :

[code]void loop()
{
D2 = read_SENSOR(ADDRESS, 0x58); // get raw temperature value from sensor
D1 = read_SENSOR(ADDRESS, 0x48); // get raw pressure value from sensor

dT = D2 - ((int64_t)C[5]*256);
OFF = ((int64_t)C[2]*65536) + ((dT * C[4])/128);
SENS = ((int64_t)C[1]*32768) + ((dT * C[3])/256);

T = (((int64_t)dT * (int64_t)C[6])/8388608) + 2000; // calculate temperature

if(T < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1    = pow(dT, 2) / 2147483648;
OFF1  = 5 * (pow(T-2000,2)/2);
SENS1 = 5 * (pow(T-2000,2)/4);

if(T < -1500) // if temperature lower than -15 Celsius 
{
  OFF1  = OFF1  +  7 *  (pow(T+1500,2));
  //SENS1 = SENS1 + 11 * (((T+1500) << 2)/2);
  SENS1 = SENS1 + 11 * (((T+1500)*(T+1500))/2);
  //SENS1 = SENS1 + 11 * ((pow(T+1500,2))/2);
} // lower than -15 celsius

T    -=    T1;
OFF  -=  OFF1; 
SENS -= SENS1;

}

P = ((((int64_t)D1 * SENS)/2097152) - OFF)/32768; // calculate pressure
[/code]

one thing i don’t understand, i want change this line :

by this :

but arduino say me there is a problem :
"unable to find a register to spill in class ‘POINTER_REGS’ "
Why ?

and is it possible to make the altitude results more stable ?


#11

Your readings are perfect for raw readings.

Now you have to use filtering to make the readings more stable in short periods of time.

For example by using averaging.

Here some formula examples: en.wikipedia.org/wiki/Average


#12

Well, thanks for your help Leo
I will look at that tomorrow afternoon when i will come back from my job. I understand i must use Moving Average
But have you got an exemple of this method under arduino ?

Else what do you think of the previous error on POINTER_REGS ?

Thanks again


#13

My recommendation: Don’t touch anything on the original code.

Work on averaging the values.

Also keep in mind: Pressure is constantly changing over time!!


#14

Ok, i will not modify your original code

But for Moving average i can add it ?


#15

I meant don’t modify the sensor calculations.

Anything else goes… :slight_smile:


#16

Ok i will look how to use moving average
Thanks


#17

Hi,
my sketch is now working !
but the sketch is too big, i need to reduce it…
is it possible to make the same job less using Wire.h library ? because Wire.h library made 10Ko !!! and it’s already 1/3 of arduino nano’s memory …
thanks


#18

Post your complete code and maybe we can find something.


#19

hi Leo,
here my complete code

[code]/*****************************************
MS5611 Sensor

Code example writen by Leo Nutz

with altitude calculation (1/2015)

© 2012 www.ALTDuino.de

******************************************/

#include <Wire.h>

#define ADDRESS 0x77 // or 0x76 sensor address

uint32_t D1 = 0;
uint32_t D2 = 0;
int32_t dT = 0;
int64_t OFF = 0;
int64_t SENS = 0;
int32_t T = 0;
int32_t P = 0;
uint16_t C[7];

float Temperature;
float Pressure;
float Altitude;

const int numReadings = 10;
float readings[numReadings];
int index = 0;
float total = 0;
float average = 0;

void setup()
{
// Disable internal pullups because 10Kohms are on the breakout
PORTC |= (1 << 4);
PORTC |= (1 << 5);

Wire.begin();
Serial.begin(9600);
delay(100);
initial(ADDRESS);

for(int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;

}

void loop()
{
D2 = read_SENSOR(ADDRESS, 0x58); // get raw temperature value from sensor
D1 = read_SENSOR(ADDRESS, 0x48); // get raw pressure value from sensor

dT = D2 - ((int64_t)C[5]*256);
OFF = ((int64_t)C[2]*65536) + ((dT * C[4])/128);
SENS = ((int64_t)C[1]*32768) + ((dT * C[3])/256);

T = (((int64_t)dT * (int64_t)C[6])/8388608) + 2000; // calculate temperature

if(T < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1    = pow(dT, 2) / 2147483648;
OFF1  = 5 * (pow(T-2000,2)/2);
SENS1 = 5 * (pow(T-2000,2)/4);

if(T < -1500) // if temperature lower than -15 Celsius 
{
  OFF1  = OFF1  +  7 *  (pow(T+1500,2));
  SENS1 = SENS1 + 11 * (((T+1500)*(T+1500))/2);
} // lower than -15 celsius

T    -=    T1;
OFF  -=  OFF1; 
SENS -= SENS1;

}

P = ((((int64_t)D1 * SENS)/2097152) - OFF)/32768; // calculate pressure

Temperature = (float)T / 100;
Pressure = (float)P / 100;
Altitude = (pow(1013.25f / Pressure, 0.190223f) - 1.0f) * 44330.08f;

//Serial.print(“TEMPERATURE = “); Serial.print(Temperature); Serial.print(” C : PRESSURE = “); Serial.print(Pressure); Serial.print(” mbar”); Serial.print(" C : ALTITUDE = “); Serial.print(Altitude); Serial.println(” meters");
//delay(100);

total = total - readings[index];
readings[index] = Altitude;
total = total + readings[index];
index = index + 1;
if(index >= numReadings){
index = 0;
}
average = total / numReadings;
Serial.println(average);
delay(100);

}

uint32_t read_SENSOR(uint8_t address, uint8_t code)
{
uint32_t value = 0;
// initialize pressure/temperature conversion
Wire.beginTransmission(address);
Wire.write(code);
Wire.endTransmission();
delay(10);
// send conversion command, start read sequence
Wire.beginTransmission(address);
Wire.write(0x00); // read command
Wire.endTransmission();
// set device address and start read sequence
Wire.requestFrom(address, (uint8_t)3);
if (Wire.available() >= 3)
{
for(uint8_t i = 0; i < 3; i++)
{
value = (value << 8) | Wire.read();
}
}
return value;
} // end read_SENSOR

void initial(uint8_t address)
{

Serial.println();
Serial.println(“PROM COEFFICIENTS”);

Wire.beginTransmission(address);
Wire.write(0x1E); // reset
Wire.endTransmission();
delay(10);

for (int i = 0; i < 6; i++) {

Wire.beginTransmission(address);
Wire.write(0xA2 + (i * 2));
Wire.endTransmission();

Wire.requestFrom(address, (uint8_t)6);
delay(10);
if(Wire.available())
{
   C* = Wire.read() << 8 | Wire.read();
}
else {
  Serial.println("Error reading PROM 1");
}
Serial.print("C"); Serial.print(i); Serial.print(" = "); Serial.println(C*);

}
Serial.println();
}[/code]**


#20

Wouldn’t this be simpler?

total = total + Altitude; index = index + 1; if(index >= numReadings){ Serial.println(total / numReadings); index = 0; total = 0; }

Unless you are a very good programmer you could tweak the wire code otherwise stick with the wire library and tweak the baro code.