#include <Wire.h>
#include <LiquidCrystal.h>
#define BMP085_ADDRESS 0x77
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const unsigned char OSS = 0;
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
long b5;
void setup(){
lcd.begin(16,2);
lcd.setCursor(0,1);
Wire.begin();
bmp085Calibration();
}
void loop()
{
float temperature = bmp085GetTemperature(bmp085ReadUT());
float pressure = bmp085GetPressure(bmp085ReadUP());
float atm = pressure / 101325;
float altitude = calcAltitude(pressure);
pressure = pressure / 100;
lcd.clear();
lcd.print("Temp: ");
lcd.print(temperature, 2);
lcd.print(" C");
lcd.setCursor(0,2);
lcd.print("cisni: ");
lcd.print(pressure);
lcd.print("hPa");
delay(10000);
}
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
float bmp085GetTemperature(unsigned int ut){
long x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;
float temp = ((b5 + 8)>>4);
temp = temp /10;
return temp;
}
long bmp085GetPressure(unsigned long up){
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;
b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
// Calculate B4
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));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
long temp = p;
return temp;
}
char bmp085Read(unsigned char address)
{
unsigned char data;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;
return Wire.read();
}
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
return (int) msb<<8 | lsb;
}
unsigned int bmp085ReadUT(){
unsigned int ut;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
delay(5);
ut = bmp085ReadInt(0xF6);
return ut;
}
unsigned long bmp085ReadUP(){
unsigned char msb, lsb, xlsb;
unsigned long up = 0;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
delay(2 + (3<<OSS));
msb = bmp085Read(0xF6);
lsb = bmp085Read(0xF7);
xlsb = bmp085Read(0xF8);
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
return up;
}
void writeRegister(int deviceAddress, byte address, byte val) {
Wire.beginTransmission(deviceAddress);
Wire.write(address);
Wire.write(val);
Wire.endTransmission();
}
int readRegister(int deviceAddress, byte address){
int v;
Wire.beginTransmission(deviceAddress);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(deviceAddress, 1);
while(!Wire.available()) {
}
v = Wire.read();
return v;
}
float calcAltitude(float pressure){
float A = pressure/101325;
float B = 1/5.25588;
float C = pow(A,B);
C = 1 - C;
C = C /0.0000225577;
float X = pressure / 100000;
return C;
}
74zł za czujnik ????? to sie chyba mija z celem
no bez kitu :d
na ebay’u ten czujnik można dostać taniej :)
Projekt fajny i ciekawy, ale –robert– ma rację. Znalazłem ten czujnik na ebay za 1,69€ + 1€ przesyłka co daje po przeliczeniu na złotówki nie całe 12 złotych.
http://www.ebay.pl/itm/New-GY-65-BMP085-Digital-Barometric-Pressure-Sensor-Module-Board-For-Arduino-/111217757507?pt=UK_Sound_Vision_Other&hash=item19e5184d43
10zł!
Panowie, ale o co ten ból zadka ? Chłopak podał namiary na Nettigo zapewne by wziąć udział w promocji o której pisał Łukasz. Komu chce się czekać na wysyłkę z Chin niech sobie kupi czujnik w Chinach i po kłopocie. A sam artykuł całkiem ciekawy, jedyne do czego można się przyczepić to ten bootloader w tym wypadku zupełnie zbędny. Pozdrawiam.
podasz bootloadera do atmegi ?
chodzi skrypty do boards.txt ? czy pilk bootloadera?
pliki bootloadera poprosze . Te co mam coś mi nie działają
Bootloader jest na forum.
Wszystko ładnie, ale w przypadku wgrywania na “Zewnętrzną” ATmege musisz dodać kondensatory filtrujące zasilanie oraz rezystor do RESET.
Polecam lekturę: http://mirekk36.blogspot.com/2012/04/mikrokontroler-prawidowe-zasilanie.html
Przepraszam bardzo ale wpis tragiczny i propaguje BARDZO złe nawyki.
– Kondensatory filtrujące napięcie zasilania mikrokontrolera
– Rezystor na pinie reset
– Cewka na zasilaniu części analogowej (no, w tym projekcie możnaby ewentualnie ją pominąć, bo nie używamy ADC)
– 5V i masę podłączamy do KAŻDEGO pinu Vcc i GND (tak, nawet jeżeli nie używamy ADC)!!!
– na stronie Nettigo znajduje się taka uwaga: “Zasilanie 1.8 – 3.6 V. Podanie napięcia zasilającego 5V uszkodzić może czujnik!”. No ja tutaj stabilizatora na 3V3 nie widzę, ale na pewno nie byłoby przy nim kondensatorów :P
– nie dam głowy (bo nie używam tego typu wyświetlaczy), ale mocno wydaje mi się, że na jednej z nóżek powinien być potencjometr, albo chociaż rezystor…
Bez urazy, ale moim zdaniem wpis szkodliwy, bo ktoś wejdzie na tą stronę, przejrzy projekt i nie zaglądając w komentarze podłączy układ tak jak to pokazałeś, pięknie smażąc sobie moduł za 80zł. (o zasilaniu mikrokontrolera nawet nie będę już wspominał)
napięcie 5V nie uszkadza czujnika, potencjometr można ominąc gdy nie jest potrzebny, układ działa i jakoś nic się z nim nie dzieję.
“napięcie 5V nie uszkadza czujnika” – lepiej znasz budowę układu niż jego producent? imponujące. polecam lekturę noty katalogowej wykorzystanego przez Ciebie układu:
https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf
strona 7, tabela 2 “Absolute maximum ratings”, wiersz 2 “Supply voltage (on all pins) MAX: +4.25V”
przy czym jest to maksymalne napięcie, jakie można podać na dowolną nóżkę – w innym miejscu (strona 6, tabela 1, wiersz 2) znajduje się wyraźna informacja, że maksymalne dopuszczalne napięcie zasilania to 3.6V.
“układ działa i jakoś nic się z nim nie dzieję” – gratuluję, że się nic nie dzieje – masz po prostu dużo szczęścia. polecam notę katalogową mikrokontrolera ATmega328 (pozwolisz, że nie podam konkretnych stron) w której znajdują się informacje informujące o KONIECZNOŚCI stosowania filtrowania napięcia zasilania, podłączania WSZYSTKICH pinów odpowiedzialnych za zasilanie układu i podciągnięciu pinu reset do zasilania przez rezystor.
jeżeli nie chce Ci się wertować noty mikrokontrolera, to przeczytaj chociaż ten artykuł, do którego link już gdzieś tutaj w komentarzach się pojawił:
http://mikrokontrolery.blogspot.com/2011/04/minimalne-podlaczanie-pinow.html
i drobna uwaga (już poza “konkursem”) – każdy ma prawo popełniać błędy (też to często robię), ale jeżeli ktoś zwraca Ci na nie uwagę to należy umieć się do nich przyznać, a nie dalej brnąć.
jako “Uczeń Technikum Informatycznego” powinieneś być otwarty na nową wiedzę i uwagi, a nie uważać się za alfę i omegę.
toż luzuj, napisałem że u mnie nic nie powoduje napięcie 5V. Może uszkodzić a nie musi, nie wiem gdzie udałem alfe i omege ale ok.
Jest jakiś w miarę prosty sposób na bezprzewodowy odczyt temperatury? Cholernie by mi się coś takiego przydało, żeby mieć podgląd temperatury z kotłowni w salonie.
Witam,
Jak już ktoś wcześniej zauważył układ BMP085 należy zasilić 3.3V, ale również magistrala I2C również musi działać na poziomie 3.3V! Do tego celu należy użyć konwertera logicznego np. https://nettigo.pl/products/126.
Tak więc artykuł wymaga jeszcze kilku poprawek.
Pozdrawiam,
—
malebranchi
ok, dzięki
btw kiedyś również miałem chęć opisania tego układu i nawet zacząłem to robić, ale jak to zwykle bywa, zabrakło mi motywacji do dokończenia. Niemniej mały szkic popełniłem:
https://majsterkowo.pl/?p=5934&preview=true
Pozdrawiam,
—
malebranchi
DZIWIĘ SIĘ ŻE POSZŁO TO NA GŁÓWNĄ Z TYLOMA BŁĘDAMI.
Kilka komentarzy jest już na temat zasilania tego układu i mikroprocesora więc nie będę się powtarzał. Moim zdaniem moderatorzy tej strony powinni postawić jasne sprawo: albo poprawić zasilanie albo wylatuje do kosza..
Wykonałem ten projekt, ale po pierwsze użyłem bibliotek producenta do obsługi BMP085, zmodyfikowałem tylko program wyświetlający odczytane dane w konsoli do wyświetlania ich na LCD. Dodatkowo zrobiłem układ zasilania dla poziomu 5V pod ATmegę i 3.3V do czujnika. Wszystko działa luks torpeda
Prosta metoda zastosowania czujnika BMP085 w układach zasilanych 5V jest przedstawiona http://4.bp.blogspot.com/-Sh9HWlMoRig/UwjU99AvecI/AAAAAAAAFcU/5ASqxRqzORU/s1600/WxSSR_v1-aprs.png