The below is a hacked version of the library plus the example code (GitHub - Seeed-Studio/Grove_Barometer_Sensor: test the barometer). The SoftI2C library is GitHub - yasir-shahzad/SoftI2C: Software-based I2C communication library for Arduino.
This code does compile but I have no means to test.
In your sketch directory you need to create two files, softBMP085.h and softBMP085.cpp.
softBMP085.h
/*
Modified version of https://github.com/Seeed-Studio/Grove_Barometer_Sensor for use with software I2C
Modified by @sterretje
*/
#ifndef __BMP085_H__
#define __BMP085_H__
#include <Arduino.h>
#include <SoftI2C.h>
//#include <Wire.h>
const unsigned char OSS = 0;
#define BMP085_ADDRESS 0x77
class softBMP085 {
public:
// sterretje
softBMP085(uint8_t pinSDA, int8_t pinSCL);
// sterretje end
void init(void);
long PressureCompensate;
float bmp085GetTemperature(unsigned short ut);
long bmp085GetPressure(unsigned long up);
float calcAltitude(float seaLevelPressure = 101325);
unsigned short bmp085ReadUT(void);
unsigned long bmp085ReadUP(void);
private:
// sterretje
SoftI2C _SoftWire;
// sterretje end
short ac1;
short ac2;
short ac3;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1;
short b2;
short mb;
short mc;
short md;
char bmp085Read(unsigned char address);
short bmp085ReadInt(unsigned char address);
void writeRegister(short deviceAddress, byte address, byte val);
short readRegister(short deviceAddress, byte address);
};
#endif
softBMP085.cpp
/*
Modified version of https://github.com/Seeed-Studio/Grove_Barometer_Sensor for use with software I2C
Modified by @sterretje
*/
#include "softBMP085.h"
#include <SoftI2C.h>
//#include <Wire.h>
#include <Arduino.h>
#include <math.h>
// sterretje
softBMP085::softBMP085(uint8_t pinSDA, int8_t pinSCL) : _SoftWire(pinSDA, pinSCL)
{
}
// sterretje end
void softBMP085::init(void) {
// sterretje
//Wire.begin();
_SoftWire.begin();
// sterretje end
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
// Read 1 byte from the BMP085 at 'address'
// Return: the read byte;
char softBMP085::bmp085Read(unsigned char address) {
// sterretje
/*
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
while (!Wire.available());
return Wire.read();
*/
_SoftWire.beginTransmission(BMP085_ADDRESS);
_SoftWire.write(address);
_SoftWire.endTransmission();
_SoftWire.requestFrom(BMP085_ADDRESS, 1);
while (!_SoftWire.available());
return _SoftWire.read();
// sterretje end
}
// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
short softBMP085::bmp085ReadInt(unsigned char address) {
unsigned char msb, lsb;
// sterretje
/*
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while (Wire.available() < 2);
msb = Wire.read();
lsb = Wire.read();
*/
_SoftWire.beginTransmission(BMP085_ADDRESS);
_SoftWire.write(address);
_SoftWire.endTransmission();
_SoftWire.requestFrom(BMP085_ADDRESS, 2);
while (_SoftWire.available() < 2);
msb = _SoftWire.read();
lsb = _SoftWire.read();
// sterretje end
return (short) msb << 8 | lsb;
}
// Read the uncompensated temperature value
unsigned short softBMP085::bmp085ReadUT() {
unsigned short ut;
// sterretje
/*
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
delay(5);
*/
// sterretje end
_SoftWire.beginTransmission(BMP085_ADDRESS);
_SoftWire.write(0xF4);
_SoftWire.write(0x2E);
_SoftWire.endTransmission();
delay(5);
ut = bmp085ReadInt(0xF6);
return ut;
}
// Read the uncompensated pressure value
unsigned long softBMP085::bmp085ReadUP() {
unsigned char msb, lsb, xlsb;
unsigned long up = 0;
// sterretje
/*
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS << 6));
Wire.endTransmission();
*/
_SoftWire.beginTransmission(BMP085_ADDRESS);
_SoftWire.write(0xF4);
_SoftWire.write(0x34 + (OSS << 6));
_SoftWire.endTransmission();
// sterretje end
delay(2 + (3 << OSS));
// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
msb = bmp085Read(0xF6);
lsb = bmp085Read(0xF7);
xlsb = bmp085Read(0xF8);
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8 - OSS);
return up;
}
void softBMP085::writeRegister(short deviceAddress, byte address, byte val) {
// sterretje
/*
Wire.beginTransmission(deviceAddress); // start transmission to device
Wire.write(address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
*/
_SoftWire.beginTransmission(deviceAddress); // start transmission to device
_SoftWire.write(address); // send register address
_SoftWire.write(val); // send value to write
_SoftWire.endTransmission(); // end transmission
// sterretje end
}
short softBMP085::readRegister(short deviceAddress, byte address) {
short v;
// sterretje
/*
Wire.beginTransmission(deviceAddress);
Wire.write(address); // register to read
Wire.endTransmission();
Wire.requestFrom(deviceAddress, 1); // read a byte
while (!Wire.available()) {
// waiting
}
v = Wire.read();
*/
_SoftWire.beginTransmission(deviceAddress);
_SoftWire.write(address); // register to read
_SoftWire.endTransmission();
_SoftWire.requestFrom(deviceAddress, 1); // read a byte
while (! _SoftWire.available()) {
// waiting
}
v = _SoftWire.read();
// sterretje
return v;
}
float softBMP085::calcAltitude(float seaLevelPressure) {
float pressure = bmp085GetPressure(bmp085ReadUP());//Get the temperature
float altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903));
return altitude;
}
float softBMP085::bmp085GetTemperature(unsigned short ut) {
long x1, x2;
x1 = (((long)ut - (long)ac6) * (long)ac5) >> 15;
x2 = ((long)mc << 11) / (x1 + md);
PressureCompensate = x1 + x2;
float temp = ((PressureCompensate + 8) >> 4);
temp = temp / 10;
return temp;
}
long softBMP085::bmp085GetPressure(unsigned long up) {
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;
b6 = PressureCompensate - 4000;
x1 = (b2 * (b6 * b6) >> 12) >> 11;
x2 = (ac2 * b6) >> 11;
x3 = x1 + x2;
b3 = (((((long)ac1) * 4 + x3) << OSS) + 2) >> 2;
// Calculate B4
x1 = (ac3 * b6) >> 13;
x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;
b7 = ((unsigned long)(up - b3) * (50000 >> OSS));
if (b7 < 0x80000000) {
p = (b7 << 1) / b4;
} else {
p = (b7 / b4) << 1;
}
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
p += (x1 + x2 + 3791) >> 4;
long temp = p;
return temp;
}
Example
#include "softBMP085.h"
//#include <Wire.h>
float temperature;
float pressure;
float atm;
float altitude;
softBMP085 myBarometer(8, 7); // SDA, SCL
void setup() {
Serial.begin(9600);
while (!Serial);
myBarometer.init();
}
void loop() {
temperature = myBarometer.bmp085GetTemperature(
myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first
pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());//Get the temperature
/*
To specify a more accurate altitude, enter the correct mean sea level
pressure level. For example, if the current pressure level is 1019.00 hPa
enter 101900 since we include two decimal places in the integer value。
*/
altitude = myBarometer.calcAltitude(101900);
atm = pressure / 101325;
Serial.print("Temperature: ");
Serial.print(temperature, 2); //display 2 decimal places
Serial.println(" Celsius");
Serial.print("Pressure: ");
Serial.print(pressure, 0); //whole number only.
Serial.println(" Pa");
Serial.print("Ralated Atmosphere: ");
Serial.println(atm, 4); //display 4 decimal places
Serial.print("Altitude: ");
Serial.print(altitude, 2); //display 2 decimal places
Serial.println(" m");
Serial.println();
delay(1000); //wait a second and get values again.
}
I've commented nearly every change in the library; you can clean up once you see how it was modified.
Instead of a BMP085 class there is a softBMP085 class. The constructor takes the two pins (SDA and SCL) that you want to use.
As said, I can not test so if it does not work it's up to you to try to figure it out.