我有一個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公尺以上,所以必須扣掉當地當時的相對海平面氣壓所得到的高度才是正確的,這就是你的手錶高度誤差的原因。
回覆刪除張貼留言