我有一個G-SHOCK電子錶具有高度計的功能,手錶的高度計功能,應該是偵測大氣壓力,根據氣壓的變化測得高度,可是總覺得誤差很大,有時可能到20-30公尺。本實作用的是 BMP280這個模組,根據規格來看,相對的精確度可達1公尺。
我原本用 Github上的 adafruit/Adafruit_BMP280_Library。執行時,無法偵測到我的BMP280模組,原本也不確定這個模組是否正常可用,試著找到 sSense-BMx280 的函式庫之後,就可以正常測得壓力與溫度。之後有時間再慢慢找看看問題在哪裡?
• 先到 itbrainpower.net 下載 sSense-BMx280.zip 。
• 將下載的壓縮檔解壓縮,放在 Arduino 主程式下的 libraries目錄內,以我的電腦來說,Arduino安裝在 C:\Program Files (x86)\Arduino,點進目錄有一個 libraries的子目錄,下載後解壓縮的目錄,整個放進 libraries 目錄,重新啟動 Arduino即可。
• GY-BMP280 x 1
• 連接線 x 4 條
程式二:可換算氣壓為高度,只是不確定這個高度是否正確?
程式二執行結果:
我原本用 Github上的 adafruit/Adafruit_BMP280_Library。執行時,無法偵測到我的BMP280模組,原本也不確定這個模組是否正常可用,試著找到 sSense-BMx280 的函式庫之後,就可以正常測得壓力與溫度。之後有時間再慢慢找看看問題在哪裡?
[BMP280 大氣壓強度(高度計)感測模組 ]
GY-BMP280高精度大氣壓強度感測模組規格如下:- 型號:GY-BMP280-3.3
- 使用芯片:BMP280
- 供電電源:3v
- 通信方式:標準IIC/SPI通信協議
- 氣壓範圍: 300- 1100hPa
- 採用沉金PCB, 機器焊接工藝保證質量
- 引腳間距:2.54mm
[安裝sSense-BMx280 Library]
sSense-BMx280函式庫提供用於使用BMP280的大氣壓強度讀取的值。• 先到 itbrainpower.net 下載 sSense-BMx280.zip 。
• 將下載的壓縮檔解壓縮,放在 Arduino 主程式下的 libraries目錄內,以我的電腦來說,Arduino安裝在 C:\Program Files (x86)\Arduino,點進目錄有一個 libraries的子目錄,下載後解壓縮的目錄,整個放進 libraries 目錄,重新啟動 Arduino即可。
[材料]
• Arduino Uno x 1• GY-BMP280 x 1
• 連接線 x 4 條
[接線與電路圖]
Arduino
|
GY-68 BMP180
|
3.3V (VCC)
|
VCC
|
GND
|
GND
|
A4
|
SDA
|
A5
|
SCL
|
[程式]
#include <sSense-BMx280I2C.h>
#include <Wire.h>
#define SERIAL_SPEED 19200
BMx280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
0x76 // I2C address. I2C specific.
);
BMx280I2C ssenseBMx280(settings);
void setup()
{
delay(5000);
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {}
DebugPort.println("s-Sense BME/BMP280 I2C sensor.");
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME/BMP280 sensor!");
delay(1000);
}
switch(ssenseBMx280.chipModel())
{
case BME280::ChipModel_BME280:
DebugPort.println("Found BME280 sensor! Humidity available.");
break;
case BME280::ChipModel_BMP280:
DebugPort.println("Found BMP280 sensor! No Humidity available.");
break;
default:
DebugPort.println("Found UNKNOWN sensor! Error!");
}
// Change some settings before using.
settings.tempOSR = BME280::OSR_X4;
ssenseBMx280.setSettings(settings);
}
void loop()
{
printBMx280Data(&DebugPort);
delay(500);
}
void printBMx280Data(Stream* client)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print(" "+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println(" Pa");
delay(1000);
}
程式二:可換算氣壓為高度,只是不確定這個高度是否正確?
#include <BMx280_EnvCalc.h>
#include <sSense-BMx280I2C.h>
#include <Wire.h>
#define SERIAL_SPEED 19200
BMx280I2C ssenseBMx280; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
void setup()
{
delay(5000);
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {} // Wait
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME280 sensor!");
delay(1000);
}
switch(ssenseBMx280.chipModel())
{
case BME280::ChipModel_BME280:
DebugPort.println("Found BME280 sensor! Humidity available.");
break;
case BME280::ChipModel_BMP280:
DebugPort.println("Found BMP280 sensor! No Humidity available.");
break;
default:
DebugPort.println("Found UNKNOWN sensor! Error!");
}
}
void loop()
{
printBMx280Data(&DebugPort);
delay(500);
}
void printBMx280Data( Stream* client )
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print(String(tempUnit == BME280::TempUnit_Celsius ? "C" :"F"));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->print(" Pa");
BMx280_EnvCalc::AltitudeUnit envAltUnit = BMx280_EnvCalc::AltitudeUnit_Meters;
BMx280_EnvCalc::TempUnit envTempUnit = BMx280_EnvCalc::TempUnit_Celsius;
float altitude = BMx280_EnvCalc::Altitude(pres, envAltUnit);
float dewPoint = BMx280_EnvCalc::DewPoint(temp, hum, envTempUnit);
float seaLevel = BMx280_EnvCalc::EquivalentSeaLevelPressure(altitude, temp, pres);
// seaLevel = BMx280_EnvCalc::SealevelAlitude(altitude, temp, pres); // Deprecated. See EquivalentSeaLevelPressure().
client->print("\r\nAltitude: ");
client->print(altitude);
client->print((envAltUnit == BMx280_EnvCalc::AltitudeUnit_Meters ? "m" : "ft"));
client->print("\tDew point: ");
client->print(dewPoint);
client->print(String(envTempUnit == BMx280_EnvCalc::TempUnit_Celsius ? "C" :"F"));
client->print("\t\tEquivalent Sea Level Pressure: ");
client->print(seaLevel);
client->println(" Pa\r\n");
delay(1000);
}
[實作結果]
程式一執行結果:程式二執行結果:



原本的Adafruit_BMP280_Library無法認到模組,應該是原本的範例程式中沒有設定模組的I2C address及chipid。他是空白的,需要使用者自己填上去。
回覆刪除擷取一段Adafruit_BMP280_Library的範例程式,位置大概在第10行左右,如下
unsigned status;
//status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);
status = bmp.begin();
其中的status = bmp.begin();
請改成status = bmp.begin(0x76, 0x60);
這樣應該就可以使用了。
即便你的氣壓換算高度是正確的(每降低1hpa,高度則上升9公尺),但是即便你在同個地點相同高度,不同時監測得的氣壓值還是不一樣,颱風來的時候最低可能不到970,冬天寒流來的時候可能高達1020,前後誤差400公尺以上,所以必須扣掉當地當時的相對海平面氣壓所得到的高度才是正確的,這就是你的手錶高度誤差的原因。
回覆刪除張貼留言