壓力感測器實作 – GMP102數位式氣壓感測器
電路圖
HUB-5168
Ameba A1_Lite
程式列表
GMP102.h
|
#ifndef __GMP102_H__ #define __GMP102_H__ #define GMP102_7BIT_I2C_ADDR
0x6C //SA0=GND //#define
GMP102_7BIT_I2C_ADDR 0x6D //SA0=VIO #define GMP102_TEMPERATURE_SENSITIVITY 256.00 //1 Celsius = 256
code #define GMP102_T_CODE_TO_CELSIUS(tCode) (((float)(tCode)) /
GMP102_TEMPERATURE_SENSITIVITY) //Registers
Address #define GMP102_REG_RESET 0x00 #define GMP102_REG_PID 0x01 #define GMP102_REG_STATUS 0x02 #define
STATUS_DRDY 0x01 #define GMP102_REG_PRESSH 0x06 #define GMP102_REG_PRESSM 0x07 #define GMP102_REG_PRESSL 0x08 #define GMP102_REG_TEMPH 0x09 #define GMP102_REG_TEMPL 0x0A #define GMP102_REG_CMD 0x30 #define
T_Forced_mode 0x08 #define
P_Forced_mode 0x09 #define GMP102_REG_CONFIG1 0xA5 #define
CONFIG1_RAW 0x02 #define GMP102_REG_CONFIG2 0xA6 #define GMP102_REG_CONFIG3 0xA7 #define GMP102_REG_CALIB00 0xAA //Total
calibration register count: AAh~BBh total 18 #define GMP102_CALIBRATION_REGISTER_COUNT 18 //Total
calibration parameter count: total 9 #define GMP102_CALIBRATION_PARAMETER_COUNT
(GMP102_CALIBRATION_REGISTER_COUNT/2) //Soft
reset #define GMP102_SW_RST_SET_VALUE
0x24 /*
PID */ #define GMP102_PID__REG GMP102_REG_PID /*
Soft Rest bit */ #define GMP102_RST__REG
GMP102_REG_RESET #define GMP102_RST__MSK 0x24 #define GMP102_RST__POS 0 /*
DRDY bit */ #define GMP102_DRDY__REG
GMP102_REG_STATUS #define GMP102_DRDY__MSK 0x01 #define GMP102_DRDY__POS 0 /*
P OSR bits */ #define GMP102_P_OSR__REG
GMP102_REG_CONFIG2 #define GMP102_P_OSR__MSK 0x07 #define GMP102_P_OSR__POS 0 /*
T OSR bits */ #define GMP102_T_OSR__REG
GMP102_REG_CONFIG3 #define GMP102_T_OSR__MSK 0x07 #define GMP102_T_OSR__POS 0 #define GMP102_GET_BITSLICE(regvar, bitname) \ ((regvar & bitname##__MSK)
>> bitname##__POS) #define GMP102_SET_BITSLICE(regvar, bitname, val) \ ((regvar & ~bitname##__MSK)
| ((val<<bitname##__POS)&bitname##__MSK)) typedef enum { GMP102_P_OSR_256 = 0x04, GMP102_P_OSR_512 = 0x05, GMP102_P_OSR_1024 = 0x00, GMP102_P_OSR_2048 = 0x01, GMP102_P_OSR_4096 = 0x02, GMP102_P_OSR_8192 = 0x03, GMP102_P_OSR_16384 = 0x06, GMP102_P_OSR_32768 = 0x07, }
GMP102_P_OSR_Type; typedef enum { GMP102_T_OSR_256 = 0x04, GMP102_T_OSR_512 = 0x05, GMP102_T_OSR_1024 = 0x00, GMP102_T_OSR_2048 = 0x01, GMP102_T_OSR_4096 = 0x02, GMP102_T_OSR_8192 = 0x03, GMP102_T_OSR_16384 = 0x06, GMP102_T_OSR_32768 = 0x07, }
GMP102_T_OSR_Type; #endif // __GMP102_H__ |
GMP102_Ameba.ino
|
/* * Program Description: * -------------------- * * Ameba BW16 GMP102 *
--------- ------------- * 3.3V
| VDD | Pin8 | *
VSS | VSS | Pin7 | *
| SCL -----> SCL | Pin4 | *
| SDA -----> SDA | Pin3 | *
|
*
---------- * ---------- * GMP102 Application note for Calibrated
Pressure Calculation *
https://github.com/GlobalMEMS/Application-Notes */ /*---------------------------------------------------------------------------- * Includes *----------------------------------------------------------------------------*/ #include <GTimer.h> #include "BLEDevice.h" #include <Wire.h> #include "GMP102.h" /*---------------------------------------------------------------------------- * DEFINITIONS *----------------------------------------------------------------------------*/ #define BLE_DEVICE_NAME
"Ameba_BLE" #define UART_SERVICE_UUID
"6E400001-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_RX
"6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX
"6E400003-B5A3-F393-E0A9-E50E24DCCA9E" #define STRING_BUF_SIZE 100 //
HUB 5168 #define GreenLED 3 //PA30 #define BlueLED 9 //PA15 //#define DebugPrg /*----------------------------------------------------------------------------*/ /*
STRUCTURES
*/ /*----------------------------------------------------------------------------*/ typedef union _SystemStatus { char _byte; struct { unsigned
b_10msDone:1; unsigned
b_100msDone:1; unsigned
b_1secDone:1; unsigned
RESV:5; }; }
SystemStatus; /*----------------------------------------------------------------------------*/ /*
Global CONSTANTS
*/ /*----------------------------------------------------------------------------*/ BLEService
UartService(UART_SERVICE_UUID); BLECharacteristic
Rx(CHARACTERISTIC_UUID_RX); BLECharacteristic
Tx(CHARACTERISTIC_UUID_TX); BLEAdvertData
advdata; BLEAdvertData
scndata; bool notify = false; bool updated = false; String
rxString = ""; int counter = 0; bool TimerDone = false; unsigned long now; SystemStatus SystemStatusbits; unsigned char Data_Buffer[128]={0}; unsigned char buffer; int PADCData,ADC0; int TADCData; float pressure,height,temperature,DisplayData; unsigned char CalData[18]; float CalData2[9]; static const float GMP102_CALIB_SCALE_FACTOR[] = { 1.0E+00, 1.0E-05, 1.0E-10, 1.0E-05, 1.0E-10, 1.0E-15, 1.0E-12, 1.0E-17, 1.0E-21 }; static float
fp_base_sea_level_Pa = 101325.f; /*----------------------------------------------------------------------------*/ /*
Start Function
*/ /*----------------------------------------------------------------------------*/ void setup(void) { pinMode(BlueLED,
OUTPUT); Wire.begin(); Serial.begin(115200); //
optional serial monitor Serial.println(F("\r\nGobalMEMS
GMP102 test")); advdata.addFlags(GAP_ADTYPE_FLAGS_LIMITED
|
GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED); advdata.addCompleteName(BLE_DEVICE_NAME); scndata.addCompleteServices(BLEUUID(UART_SERVICE_UUID)); Rx.setWriteNRProperty(true); // Enable write
without response (write command) Rx.setWritePermissions(GATT_PERM_WRITE); Rx.setWriteCallback(writeCB); Rx.setBufferLen(STRING_BUF_SIZE); Tx.setReadProperty(true); Tx.setReadPermissions(GATT_PERM_READ); Tx.setNotifyProperty(true); Tx.setCCCDCallback(notifCB); Tx.setBufferLen(STRING_BUF_SIZE); UartService.addCharacteristic(Rx); UartService.addCharacteristic(Tx); BLE.init(); BLE.configAdvert()->setAdvData(advdata); BLE.configAdvert()->setScanRspData(scndata); BLE.configServer(1); BLE.addService(UartService); BLE.beginPeripheral(); SensorInital(); // timerid 0,
period 10s, invoke Timerhandler GTimer.begin(0, (10 * 1000 * 1000), Timerhandler); now =
millis(); // system timer0 SystemStatusbits._byte
= 0; } void loop(void) { char
String1[200]; digitalWrite(BlueLED,
LOW); PDataRead(); digitalWrite(BlueLED,
HIGH); TDataRead(); temperature=TADCData/GMP102_TEMPERATURE_SENSITIVITY; pressure=GMP102_PRESSURE_CAL(TADCData,PADCData); height=GMP102_Altitude_CAL(pressure); sprintf(String1,"Temperature:%d
'C, Pressure:%d hPa, Approx Altitude:%d m", (int)temperature,(int)pressure/100,(int)height); Serial.println(String1); if(TimerDone
== true) { if(updated){ Serial.println(rxString); //
raw output updated = false; //
clear flag for another update } String msg = ("Temperature:
" +
String((int)
temperature) + "°C\t" + "Pressure:
" +
String((int)
pressure/100) + "hPa\n"); Tx.writeString(msg); if (BLE.connected(0) &&
notify) { Tx.notify(0); } } SYS_TIMER(); //
work on timer0 if(SystemStatusbits.b_1secDone==1) { SystemStatusbits.b_1secDone=0; } } /*----------------------------------------------------------------------------*/ /*
Write I2C Device Register Data
*/ /*----------------------------------------------------------------------------*/ void I2C_WriteData(unsigned char DeviceAddr, unsigned char *DataBuffer, unsigned char StartAddress, unsigned char ByteCount) { // Send the
received data to slave Wire.beginTransmission(DeviceAddr); //Device_ID_Addr Wire.write(StartAddress); for(;ByteCount>0;ByteCount--) { Wire.write(*DataBuffer++); } Wire.endTransmission(); } /*----------------------------------------------------------------------------*/ /*
Read I2C Device Register Data
*/ /*----------------------------------------------------------------------------*/ void I2C_ReadData(unsigned char DeviceAddr, unsigned char *DataBuffer, unsigned char StartAddress, unsigned char ByteCount) { unsigned char au8DestinationData; // send the
received data to slave Wire.beginTransmission(DeviceAddr); //Device_ID_Addr Wire.write(StartAddress); Wire.endTransmission(); Wire.requestFrom(DeviceAddr,
ByteCount); // request 1 bytes
from slave device //Read Register
Data From I2C Device for(;ByteCount>0;ByteCount--) { while (Wire.available()) // slave may send
less than requested { au8DestinationData =
Wire.read(); //
receive a byte as character *DataBuffer++ = (unsigned char)
au8DestinationData; #if
defined(DebugPrg) Serial.print(F("Addr-")); Serial.print(StartAddress++,HEX); Serial.print(F(":")); Serial.println(au8DestinationData,HEX); #endif } } } /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ void PDataRead(void) { char
Raw=0; char
DRDY=0; do { Data_Buffer[0]=CONFIG1_RAW; I2C_WriteData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CONFIG1,1); delay(1000); I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CONFIG1,1); Raw=Data_Buffer[0]; delay(1000); }while(Raw!=CONFIG1_RAW); Data_Buffer[0]=P_Forced_mode; //P-Forced mode,
Make a single shot pressure conversion I2C_WriteData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CMD,1); delay(1000); while(DRDY!=STATUS_DRDY) { I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_STATUS,1); DRDY=Data_Buffer[0]; delay(1000); } //I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_PRESSH,5); I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_PRESSH,3); PADCData=(Data_Buffer[0]<<16)+(Data_Buffer[1]<<8)+Data_Buffer[2]; #if defined(DebugPrg) Serial.println(PADCData,HEX); #endif if((PADCData<0)||(PADCData>0x800000)) { PADCData=~PADCData; PADCData=PADCData&0xFFFFFF; PADCData=PADCData+1; } } void TDataRead(void) { char
Raw=0; char
DRDY=0; do { Data_Buffer[0]=0x00; I2C_WriteData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CONFIG1,1); delay(1000); I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CONFIG1,1); Raw=Data_Buffer[0]; delay(1000); }while(Raw!=0x00); Data_Buffer[0]=T_Forced_mode; //T-Forced mode,
Make a single shot pressure conversion I2C_WriteData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_CMD,1); delay(1000); I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_STATUS,1); DRDY=Data_Buffer[0]; delay(1000); while(DRDY!=STATUS_DRDY) { I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_STATUS,1); DRDY=Data_Buffer[0]; delay(1000); } I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_TEMPH,2); TADCData=((Data_Buffer[0]<<8)+Data_Buffer[1]); #if defined(DebugPrg) Serial.println(TADCData,HEX); #endif } int GMP102_PRESSURE_CAL(int temp_data,int press_data) { // 100 Pa = 1
millibar (Pa = newton per square meter) int
data = CalData2[0]+ CalData2[1]*temp_data+ CalData2[2]*temp_data*temp_data+ CalData2[3]*press_data+ CalData2[4]*temp_data*press_data+ CalData2[5]*temp_data*temp_data*press_data+ CalData2[6]*press_data*press_data+ CalData2[7]*temp_data*press_data*press_data+ CalData2[8]*temp_data*temp_data*press_data*press_data; return
data; } int GMP102_Altitude_CAL(float press_data) { // Pressure
altitude conversion // See
https://en.wikipedia.org/wiki/Pressure_altitude float
data = 44307.694f *(1.0f -pow(press_data/fp_base_sea_level_Pa,0.190284f)); return
data; } void SensorInital(void) { char
Raw=0; char
DRDY=0; unsigned char i,WriteData[4]={0,0,0,0}; int
tmp; /* GMP102 soft
reset */ Data_Buffer[0]=GMP102_SW_RST_SET_VALUE; I2C_WriteData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_RESET,1); delay(100); /* Wait 100ms for
reset complete */ I2C_ReadData(GMP102_7BIT_I2C_ADDR,Data_Buffer,GMP102_REG_PID,1); #if defined(DebugPrg) Serial.print(GMP102_REG_PID,HEX); Serial.print(F(":")); Serial.println(Data_Buffer[0]); #endif /* GMP102 get the
pressure calibration parameters */ I2C_ReadData(GMP102_7BIT_I2C_ADDR,CalData,GMP102_REG_CALIB00,18); delay(1000); for(i=0;i<9;i++) { tmp=(CalData[i*2]<<8)+CalData[i*2+1]; CalData2[i]=((tmp<<16)>>18)*(pow(10,CalData[i*2+1]&0x03))*GMP102_CALIB_SCALE_FACTOR[i]; } I2C_WriteData(GMP102_7BIT_I2C_ADDR,WriteData,GMP102_REG_CALIB00,4); } void writeCB (BLECharacteristic*
chr, uint8_t connID) { printf("Characteristic
%s write by connection %d :\n",
chr->getUUID().str(), connID); if (updated
== false &&
chr->getDataLen() > 0) { rxString =
chr->readString(); updated = true; } } void notifCB (BLECharacteristic*
chr, uint8_t connID, uint16_t cccd) { if (cccd
&
GATT_CLIENT_CHAR_CONFIG_NOTIFY) { printf("Notifications
enabled on Characteristic %s for connection %d \n",
chr->getUUID().str(),
connID); notify = true; } else { printf("Notifications
disabled on Characteristic %s for connection %d \n",
chr->getUUID().str(),
connID); notify = false; } } void Timerhandler(uint32_t data) { counter++; Serial.print("counter:
"); Serial.println(counter); TimerDone = true; } /*----------------------------------------------------------------------------*/ void SYS_TIMER() { static
byte tm_10ms = 0; static
byte tm_100ms = 0; static
byte tm_1sec = 0; while (millis() -
now >= 10) { now += 10; tm_10ms++; tm_100ms++; tm_1sec++; } if (tm_1sec
>= 100) { tm_1sec -= 100; SystemStatusbits.b_1secDone=1; //PROCESS_1sec(); } if (tm_100ms
>= 10) { tm_100ms -= 10; SystemStatusbits.b_100msDone=1; //PROCESS_100ms(); } if (tm_10ms
!= 0) { tm_10ms -= 1; SystemStatusbits.b_10msDone=1; //PROCESS_10ms(); } } //void
PROCESS_1sec(){ //} //void
PROCESS_100ms(){ //} //void
PROCESS_10ms(){ //} /*----------------------------------------------------------------------------*/ /*
End Of File
*/ /*----------------------------------------------------------------------------*/ |
沒有留言:
張貼留言