BMP085 е сензор за измерване на атмосферно налягане. Може да се намери запоен върху брейкаут борд с два PullUp резистора от 4,7k и 0,1uF кондензатор. Платката има изходни пинове на разстояние 2.56mm, които я правят лесна за използване с платка бредборд. Сензорът се захранва с 1.8 до 3.6V постоянно напрежение и осъществява комуникация с микроконтролер по I2C.
Комуникацията се осъществява по линиите SDA и SCL и може да започне 10ms след захранване на сензора. Микроконтролерът трябва да изпълни условието START, като свали от HIGH (високо ниво) на LOW (ниско ниво) линията SDA, докато SCL е HIGH. След всеки 8 бита, сензорът отговаря със сигнал ACK и след последния такъв сигнал, микроконтролерът трябва да прекъсне комуникацията с условието STOP. То се изпълнява като линията SDA се вдигне от LOW на HIGH, докато SCL е HIGH.
Адресът на сензора е 1110111x, като последния бит е 1 за операция Read и 0 за операция Write.
Измерването започва след изпращането на адреса за операция Write, указател към регистъра с адрес 0xF4 и един байт с контролни данни. Тези данни могат да са следните:
Различните режими на измерване имат времетраене от 4.5 до 25.5 ms.
За да получи резултатът от измерването, микроконтролерът трябва да изпрати адреса за операция Write и указател към регистър 0xF6. След ACK от сензора, микроконтролерът трябва да рестартира комуникацията и да изпрати адреса за операция Read. Сензорът връща 2 байта, като микроконтролерът трябва да потвърди първия с ACK, а втория с NAK и да прекъсне комуникацията със STOP.
Стойността на атмосферното налягане в паскали се изчислява чрез допълнителни кофиценти, които са записани в EEPROM паметта на сензора и могат да се прочетат от микроконтролер по I2C интерфейса. Коефицентите могат да се вземат и от дейташита на продукта:
Алгоритъмът за компенсация на стойността получена от сензора е следният:
UP е некомпенсираната стойност прочетена от сензора,а oss показва режима на измерване и може да приема стойностите:
Променливата p присвоява стойността на атмосферното налягане в Pa. За да се превърне в hPa трябва да се умножи по 0.01.
Пример
Даденият по-долу код осъществява комуникация със сензора по линии SDA и SCL. Arduino прочита стойността за атмосферното налягане, компенсира отклонението и по зададения алгоритъм и извежда я като hPa в Serial Monitor.
Vcc и GND пиновете на сензора се свързват съответно към 3.3V и GND, a SCL и SDA към А5 и А4.
За да се програмира Arduino с дадения по-долу код, трябва да се инсталира библиотека, написана от Peter Fleury. Файловете, които са необходими на Arduino могат да се изтеглят от тук. Библиотеката се разархивира в libraries от "arduino-00xx" директорията.
След като се инсталира библиотеката, кода който трябва да се зареди на Arduino е следният:
// библиотека за комуникация по I2C #include <i2cmaster.h> //// адрес, на който се открива BMP085 int dev = 0xEE; // 11101110 //// коефиценти за калибриране на BMP085 short ac1 = 408; // AC1 short ac2 = -72; // AC2 short ac3 = -14383; // AC3 unsigned short ac4 = 32741; // AC4 unsigned short ac5 = 32757; // AC5 unsigned short ac6 = 23153; // AC6 short b1 = 6190; // B1 short b2 = 4; // B2 short mb = -32767; // MB short mc = -8711; // MC short md = 2868; // MD //// променливи за изчисляване на налягането long pval; // присвоява резултата long x1, x2, x3, b3, b5, b6, p; unsigned long b4, b7; short oss = 0; // режим на измерване void setup() { // начални инициализации Serial.begin(9600); // започва серийна комуникация с PC delay(10); // изчаква 10ms за да се установи сензора i2c_init(); // започва комуникация по I2C шината } void loop() { // програмен цикъл // изпълнява условието START .. // изпраща адреса на сензора с последен бит за операция "Write" .. // изчаква ACK от сензора i2c_start_wait(dev + I2C_WRITE); // изпраща адреса на регистър 0x74 .. // изчаква ACK от сензора i2c_write(0xF4); // изпраща контролони данни за измерване с ниска консумация(oss=0) .. // изчаква ACK от сензора i2c_write(0x34); // прекъсва комуникацията i2c_stop(); // изчаква да завърши измерването delay(30); // изпълнява условието START .. // изпраща адреса на сензора с последен бит за операция "Write" .. // изчаква ACK от сензора i2c_start_wait(dev + I2C_WRITE); // изпраща адреса на регистър 0xF6 .. // изчаква ACK от сензора i2c_write(0xF6); // изпълнява условието START .. // изпраща адреса на сензора с последен бит за операция "Read" .. // изчаква ACK от сензора i2c_rep_start(dev + I2C_READ); // прочита първия байт и го присвоява на променлива от тип long .. // връща ACK на сензора unsigned long up = i2c_readAck(); // прави байта старши за променливата up = up << 8; // прочита и присвоява втория байт като младши за променливата .. // връща NAK на сензора up |= i2c_readNak(); // прекъсва комуникацията i2c_stop(); //// изчислява налягането в Pa b6 = b5 - 4000; x1 = (b2 * (b6 * b6 >> 12)) >> 11; x2 = ac2 * b6 >> 11; x3 = x1 + x2; b3 = (((long ) ac1 * 4 + x3)<<oss + 2) >> 2; 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); p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2; x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; pval = p + ((x1 + x2 + 3791) >> 4); //// Извежда стойността в Serial Monitor Serial.print("pressure = "); Serial.print((float)pval/100); // превръща с-та в hPa Serial.println(" hPa"); // мерна единица // закъснение от 2 сек. delay(2000); } |