Add support for: Grove - Temp&Humi&Barometer Sensor (BME280)
Open
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 494
- Forks
- 472
- PR merge metrics
- No merged PRs in 30d
Description
Here's the code for the sensor, if you want to integrate into your library. For the C# Win 10 IoT
All features of the sensor work as expected.
class SensorBME280
{
private I2cDevice SensorBme280;
private byte SensorAddress = 0x76;
// BME280 Calibration variables
private UInt16 T1;
private Int16 T2;
private Int16 T3;
private UInt16 P1;
private Int16 P2;
private Int16 P3;
private Int16 P4;
private Int16 P5;
private Int16 P6;
private Int16 P7;
private Int16 P8;
private Int16 P9;
private byte H1;
private Int16 H2;
private byte H3;
private Int16 H4;
private Int16 H5;
private Int16 H6;
// BME280 Data register addresses
private byte HumLsbAddr = 0xfe;
private byte HumMsbAddr = 0xfd;
private byte TmpXlsbAddr = 0xfc;
private byte TmpLsbAddr = 0xfb;
private byte TmpMsbAddr = 0xfa;
private byte PreXlsbAddr = 0xf9;
private byte PreLsbAddr = 0xf8;
private byte PreMsbAddr = 0xf7;
// BME280 Variable data calibration
private Int32 t_fine = Int32.MinValue;
// BME280 Calibration data address
enum Register : byte
{
Dig_T1 = 0x88,
Dig_T2 = 0x8a,
Dig_T3 = 0x8c,
Dig_P1 = 0x8e,
Dig_P2 = 0x90,
Dig_P3 = 0x92,
Dig_P4 = 0x94,
Dig_P5 = 0x96,
Dig_P6 = 0x98,
Dig_P7 = 0x9a,
Dig_P8 = 0x9c,
Dig_P9 = 0x9e,
Dig_H1 = 0xa1,
Dig_H2 = 0xe1,
Dig_H3 = 0xe3,
Dig_H4 = 0xe4,
Dig_H5 = 0xe5,
Dig_H6 = 0xe7,
}
// BME280 measurement data acquisition register address
enum Command : byte
{
ReadTemperature = 0xfa,
ReadPressure = 0xf7,
ReadHumidity = 0xfd,
}
public async void InitializeSensor()
{
I2cController I2c = await I2cController.GetDefaultAsync();
SensorBme280 = I2c.GetDevice(new I2cConnectionSettings(SensorAddress));
// Sensor initialization
uint osrs_t = 3;
uint osrs_p = 3;
uint osrs_h = 3;
uint mode = 3;
uint t_sb = 5;
uint filter = 0;
uint spi3w_en = 0;
uint ctrlMeasReg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint configReg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint ctrlHumReg = osrs_h;
SensorBme280.Write(new byte[] { 0xf2, (byte)ctrlHumReg });
SensorBme280.Write(new byte[] { 0xf4, (byte)ctrlMeasReg });
SensorBme280.Write(new byte[] { 0xf5, (byte)configReg });
await Task.Delay(10);
// Load calibration data
// Temperature
T1 = ReadUInt16((byte)Register.Dig_T1);
T2 = (Int16)ReadUInt16((byte)Register.Dig_T2);
T3 = (Int16)ReadUInt16((byte)Register.Dig_T3);
// Barometric pressure
P1 = ReadUInt16((byte)Register.Dig_P1);
P2 = (Int16)ReadUInt16((byte)Register.Dig_P2);
P3 = (Int16)ReadUInt16((byte)Register.Dig_P3);
P4 = (Int16)ReadUInt16((byte)Register.Dig_P4);
P5 = (Int16)ReadUInt16((byte)Register.Dig_P5);
P6 = (Int16)ReadUInt16((byte)Register.Dig_P6);
P7 = (Int16)ReadUInt16((byte)Register.Dig_P7);
P8 = (Int16)ReadUInt16((byte)Register.Dig_P8);
P9 = (Int16)ReadUInt16((byte)Register.Dig_P9);
// Humidity
H1 = ReadByte((byte)Register.Dig_H1);
H2 = (Int16)ReadUInt16((byte)Register.Dig_H2);
H3 = ReadByte((byte)Register.Dig_H3);
H4 = (short)(ReadByte((byte)Register.Dig_H4) << 4 | ReadByte((byte)Register.Dig_H4 + 1) & 0xf);
H5 = (short)(ReadByte((byte)Register.Dig_H5 + 1) << 4 | ReadByte((byte)Register.Dig_H5) >> 4);
H6 = (sbyte)ReadByte((byte)Register.Dig_H6);
}
/// <summary>
/// Temperature data acquisition (Celsius)
/// </summary>
/// <returns></returns>
public async Task<double> ReadTemperature()
{
byte tmsb = ReadByte(TmpMsbAddr);
byte tlsb = ReadByte(TmpLsbAddr);
byte txlsb = ReadByte(TmpXlsbAddr);
Int32 tmpRaw = (tmsb << 12) | (tlsb << 4) | (txlsb >> 4);
double var1, var2, T;
var1 = ((tmpRaw / 16384.0) - (T1 / 1024.0)) * T2;
var2 = ((tmpRaw / 131072.0) - (T1 / 8192.0)) * T3;
t_fine = (Int32)(var1 + var2);
T = (var1 + var2) / 5120.0;
await Task.Delay(1);
return T;
}
/// <summary>
/// Pressure data acquisition (Hectopascal)
/// </summary>
/// <returns></returns>
public async Task<double> ReadPressure()
{
byte pmsb = ReadByte(PreMsbAddr);
byte plsb = ReadByte(PreLsbAddr);
byte pxlsb = ReadByte(PreXlsbAddr);
Int32 preRaw = (pmsb << 12) | (plsb << 4) | (pxlsb >> 4);
Int64 var1, var2, P;
var1 = t_fine - 128000;
var2 = var1 * var1 * (Int64)P6;
var2 = var2 + ((var1 * (Int64)P5) << 17);
var2 = var2 + ((Int64)P4 << 35);
var1 = ((var1 * var1 * (Int64)P3) >> 8) + ((var1 * (Int64)P2) << 12);
var1 = (((((Int64)1 << 47) + var1)) * (Int64)P1) >> 33;
if (var1 == 0)
{
return 0;
}
P = 1048576 - preRaw;
P = (((P << 31) - var2) * 3125) / var1;
var1 = ((Int64)P9 * (P >> 13)) >> 25;
var2 = ((Int64)P8 * P) >> 19;
P = ((P + var1 + var2) >> 8) + ((Int64)P7 << 4);
await Task.Delay(1);
return (double)(P / 256 / 100);
}
/// <summary>
/// Humidity data acquisition (Relative Humidity)
/// </summary>
/// <returns></returns>
public async Task<double> ReadHumidity()
{
byte hmsb = ReadByte(HumMsbAddr);
byte hlsb = ReadByte(HumLsbAddr);
int humRaw = (hmsb << 8) | hlsb;
Int32 H;
H = t_fine - 76800;
H = (((((humRaw << 14) - (((Int32)H4) << 20) - ((Int32)H5 * H)) + ((Int32)16384)) >> 15) * (((((((H * ((Int32)H6)) >> 10) * (((H * ((Int32)H3)) >> 11) + ((Int32)32768))) >> 10) + ((Int32)2097152)) * ((Int32)H2) + 8192) >> 14));
H = (H - (((((H >> 15) * (H >> 15)) >> 7) * ((Int32)H1)) >> 4));
H = (H < 0 ? 0 : H);
H = (H > 419430400 ? 419430400 : H);
await Task.Delay(1);
return (UInt32)((H >> 12) / 1000);
}
public double ReadAltitude(double pressure, bool useInternationalFormula = true)
{
if (useInternationalFormula)
{
// International Barometric Formula
return 44330.0f * (1.0f - (float)Math.Pow((pressure / 1013), 0.1903f));
}
else
{
// Seeedstudio Grove BME280 formula
double a = pressure / 101325;
double b = 1 / 5.25588;
double c = Math.Pow(a, b);
c = 1.0 - c;
c = c / 0.0000225577;
c = c / 100;
return c;
}
}
/// <summary>
/// Double-byte data readout
/// </summary>
/// <param name="register"></param>
/// <returns></returns>
private UInt16 ReadUInt16(byte register)
{
byte[] writeBuf = new byte[] { 0x00 };
byte[] readBuf = new byte[] { 0x00, 0x00 };
writeBuf[0] = register;
SensorBme280.WriteRead(writeBuf, readBuf);
int h = readBuf[1] << 8;
int l = readBuf[0];
return (UInt16)(h + l);
}
/// <summary>
/// Read byte
/// </summary>
/// <param name="register"></param>
/// <returns></returns>
private byte ReadByte(byte register)
{
byte[] writeBuf = new byte[] { 0x00 };
byte[] readBuf = new byte[] { 0x00 };
writeBuf[0] = register;
SensorBme280.WriteRead(writeBuf, readBuf);
return readBuf[0];
}
/// <summary>
/// Display temperature (°C)
/// </summary>
/// <returns></returns>
public string DisplayTemperature(double temperature)
{
return $"{Math.Round(temperature, 0)} °C";
}
/// <summary>
/// Display pressure (hPa)
/// </summary>
/// <returns></returns>
public string DisplayPressure(double pressure)
{
return $"{Math.Round(pressure, 1)} hPa";
}
/// <summary>
/// Display humidity (%rh)
/// </summary>
/// <returns></returns>
public string DisplayHumidity(double humidity)
{
return $"{Math.Round(humidity, 0)}% rh";
}
/// <summary>
/// Display altitude (m)
/// </summary>
/// <returns></returns>
public string DisplayAltitude(double altitude)
{
return $"{Math.Round(altitude, 0)} m";
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No project files, tests, or entry points are named. Start by inspecting existing Grove sensor integrations in the repository and compare their public API and I2C handling with the supplied SensorBME280 code; done means the BME280 is integrated into the library with temperature, pressure, humidity, altitude, and display functionality available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, raspberry-pi
- Domain
- embedded-iot
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100