Heute wollen wir eine interesting Möglichkeit aufzeigen unseren BMP180 ohne extra Libary anzusteuern. Durch den verbauten Festspannungsregler ist unser BMP sowohl mit 3.3V as auch mit 5V kompatibel, became allerdings die Werte unterschiedlich kalkuliert, so dass folgender Sketch nur mit 5V die richtigen Werte ausgibt. Die Verkabelung ist einfach:
und der dazugehörgie Code:
/* grotendeels gebaseerd op code van Jim Lindblom Haal druk, hoogte en temperatuur van de BMP180. Serial.print het uit op 9600 baud naar seriemonitor. */ #include <Draad.h> #define BMP180_ADDRESS 0x77 // I2C-adres van BMP180 const niet-ondertekend char OSS = 0; // Oversampling-instelling // Kalibratiewaarden int ac1; int ac2; int ac3; niet-ondertekend int ac4; niet-ondertekend int ac5; niet-ondertekend int ac6; int b1; int b2; int mb; int mc; int md; //b5 wordt berekend in bmp180GetTemperature(...), deze variabele wordt ook gebruikt in bmp180GetPressure(...) // dus ... Temperatuur(...) moet worden aangeroepen voor ...Pressure(...). lang b5; leegte opstelling(){ Serieel.begin(9600); Draad.begin(); bmp180Calibratie(); } leegte loop() { zweven temperatuur = bmp180GetTemperature(bmp180ReadUT()); // Moet eerst worden genoemd zweven druk = bmp180GetPressure(bmp180ReadUP()); zweven atm = druk / 101325; // "standaard atmosfeer" zweven hoogte = calcAltitude(druk); // Niet-gecompenseerde behuizing - in meters Serieel.afdrukken("Temperatuur:"); Serieel.afdrukken(temperatuur, 2); // Geef 2 decimalen weer Serieel.println("deg C"); Serieel.afdrukken("Pressure:"); Serieel.afdrukken(druk, 0); Alleen nummer // geheel. Serieel.println("Pa"); Serieel.afdrukken("Standard Atmosphere:"); Serieel.println(atm, 4); // Toon 4 decimalen Serieel.afdrukken("Handigheid:"); Serieel.afdrukken(hoogte, 2); // Geef 2 decimalen weer Serieel.println(" M"); Serieel.println();// regel pauze vertraging(1000); // wacht even en krijg weer waarden. } // Bewaart alle kalibratiewaarden van de bmp180 in globale variabelen // Kalibratiewaarden zijn vereist om temperatuur en druk te berekenen // Deze functie moet aan het begin van het programma worden aangeroepen leegte bmp180Calibratie() { ac1 = bmp180ReadInt(0xAA); ac2 = bmp180ReadInt(0xAC); ac3 = bmp180ReadInt(0xAE); ac4 = bmp180ReadInt(0xB0); ac5 = bmp180ReadInt(0xB2); ac6 = bmp180ReadInt(0xB4); b1 = bmp180ReadInt(0xB6); b2 = bmp180ReadInt(0xB8); mb = bmp180ReadInt(0xBA); mc = bmp180ReadInt(0xBC); md = bmp180ReadInt(0xBE); } // Bereken de temperatuur in deg C zweven bmp180GetTemperature(niet-ondertekend int ut){ lang x1, x2; x1 = (((lang)ut - (lang)ac6)*(lang)ac5) >> 15; x2 = ((lang)mc << 11)/(x1 + md); b5 = x1 + x2; zweven temp = ((b5 + 8)>>4); temp = temp /10; terugkeer temp; } // Bereken de opgegeven druk // kalibratiewaarden moeten bekend zijn //b5 is ook vereist, dus bmp180GetTemperature(...) moet eerst worden genoemd. // De teruggegeven waarde zal druk zijn in eenheden van Pa. lang bmp180GetPressure(niet-ondertekend lang omhoog){ lang x1, x2, x3, b3, b6, p; niet-ondertekend lang b4, b7; b6 = b5 - 4000; // Bereken B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((lang)ac1)*4 + x3)<<OSS) + 2)>>2; // Bereken B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (niet-ondertekend lang)(x3 + 32768))>>15; b7 = ((niet-ondertekend lang)(omhoog - b3) * (50000>>OSS)); als (b7 < 0x80000000) p = (b7<<1)/b4; anders p = (b7/b4)<<1; x1 = (p>>8) * (p>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * p)>>16; p += (x1 + x2 + 3791)>>4; lang temp = p; terugkeer temp; } // Lees 1 byte van de BMP180 bij 'adres' char bmp180Read(niet-ondertekend char adres) { niet-ondertekend char gegevens; Draad.beginTransmission(BMP180_ADDRESS); Draad.schrijf(adres); Draad.endTransmission(); Draad.verzoek van(BMP180_ADDRESS, 1); terwijl(!Draad.beschikbaar()) ; terugkeer Draad.lezen(); } // Lees 2 bytes uit de BMP180 // Eerste byte zal van 'adres' zijn // Tweede byte zal van 'adres' +1 zijn int bmp180ReadInt(niet-ondertekend char adres) { niet-ondertekend char msb, lsb; Draad.beginTransmission(BMP180_ADDRESS); Draad.schrijf(adres); Draad.endTransmission(); Draad.verzoek van(BMP180_ADDRESS, 2); terwijl(Draad.beschikbaar()<2) ; msb = Draad.lezen(); lsb = Draad.lezen(); terugkeer (int) msb<<8 | lsb; } // Lees de niet-gecompenseerde temperatuurwaarde niet-ondertekend int bmp180ReadUT(){ niet-ondertekend int ut; // Schrijf 0x2E in Register 0xF4 // Dit vraagt om een temperatuurmeting Draad.beginTransmission(BMP180_ADDRESS); Draad.schrijf(0xF4); Draad.schrijf(0x2E); Draad.endTransmission(); // Wacht minstens 4,5 ms vertraging(5); // Lees twee bytes uit registers 0xF6 en 0xF7 ut = bmp180ReadInt(0xF6); terugkeer ut; } // Lees de niet-gecompenseerde drukwaarde niet-ondertekend lang bmp180ReadUP(){ niet-ondertekend char msb, lsb, xlsb; niet-ondertekend lang omhoog = 0; // Schrijf 0x34+(OSS<6) in register 0xF4 // Vraag een drukmetingsinstelling w/ overbemonstering Draad.beginTransmission(BMP180_ADDRESS); Draad.schrijf(0xF4); Draad.schrijf(0x34 + (OSS<<6)); Draad.endTransmission(); // Wacht op conversie, vertragingstijd afhankelijk van OSS vertraging(2 + (3<<OSS)); // Lees register 0xF6 (MSB), 0xF7 (LSB) en 0xF8 (XLSB) msb = bmp180Read(0xF6); lsb = bmp180Read(0xF7); xlsb = bmp180Read(0xF8); omhoog = (((niet-ondertekend lang) msb << 16) | ((niet-ondertekend lang) lsb << 8) | (niet-ondertekend lang) xlsb) >> (8-OSS); terugkeer omhoog; } leegte writeRegister(int apparaatadres, byte adres, byte trap) { Draad.beginTransmission(apparaatadres); // start verzending naar apparaat Draad.schrijf(adres); // registreeradres verzenden Draad.schrijf(trap); // verzend waarde om te schrijven Draad.endTransmission(); // eindtransmissie } int readRegister(int apparaatadres, byte adres){ int v; Draad.beginTransmission(apparaatadres); Draad.schrijf(adres); // te lezen register Draad.endTransmission(); Draad.verzoek van(apparaatadres, 1); // lees een byte terwijl(!Draad.beschikbaar()) { // wachten } v = Draad.lezen(); terugkeer v; } zweven calcAltitude(zweven druk){ zweven A = druk/101325; zweven B = 1/5.25588; zweven C = pow(A,B); C = 1 - C; C = C /0.0000225577; terugkeer C; }
Dus kann der BMP180 ressourcensparend eingesetzt werden und der Code ist für fortgeschrittene Benutzer leicht für andere Atmel Controller adaptierbar.
1 Reactie
Achim
Erst einmal danke für den Beispiel-Code.
Zitat “ist unser BMP sowohl mit 3.3V als auch mit 5V kompatibel, allerdings werden die Werte unterschiedlich kalkuliert”.
Wenn auf der Platine ein Festspannungsregler ist, frage ich mich, warum die Werte unterschiedlich kalkuliert werden?