Heute wollen wir eine interessante M-glichkeit aufzeigen unseren BMP180 ohne extra Libary anzusteuern. Durch den verbauten Festspannungsregler ist unser BMP sowohl mit 3.3V als auch mit 5V kompatibel, allerdings werden die Werte unterschiedlich kalkuliert, so dass folgender Sketch nur mit 5V die richtigen Werte ausgibt. Die Verkabelung ist einfach:
Und der dazugeh-rgie Código:
/*Basado en gran parte en código de Jim Lindblom Obtenga presión, altitud y temperatura del BMP180. Serial.print en 9600 baudios en monitor serie. */ #include <Alambre.H> #define BMP180_ADDRESS 0x77 Dirección I2C de BMP180 Const Unsigned Char Oss = 0; Ajuste de sobremuestreo Valores de calibración 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; b5 se calcula en bmp180GetTemperature(...), esta variable también se utiliza en bmp180GetPressure(...) así que... Temperatura(...) debe llamarse antes de ... Presión(...). Largo b5; Vacío Configuración(){ Serial.Comenzar(9600); Alambre.Comenzar(); bmp180Calibración(); } Vacío Bucle() { Flotador Temperatura = bmp180GetTemperature(bmp180ReadUT()); DEBE llamarse primero Flotador Presión = bmp180GetPressure(bmp180ReadUP()); Flotador cajero = Presión / 101325; "Ambiente estándar" Flotador Altitud = calcAltitude(Presión); Cacculación no compensada - en medidores Serial.Impresión("Temperatura: "); Serial.Impresión(Temperatura, 2); mostrar 2 decimales Serial.println("Deg C"); Serial.Impresión("Presión: "); Serial.Impresión(Presión, 0); número entero solamente. Serial.println(" Pa"); Serial.Impresión("Atmósfera estándar: "); Serial.println(cajero, 4); mostrar 4 decimales Serial.Impresión("Altitud: "); Serial.Impresión(Altitud, 2); mostrar 2 decimales Serial.println("M"); Serial.println();salto de línea Retraso(1000); esperar un segundo y obtener valores de nuevo. } Almacena todos los valores de calibración del bmp180 en variables globales Los valores de calibración son necesarios para calcular la temperatura y la presión Esta función debe llamarse al comienzo del programa Vacío bmp180Calibración() { 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); } Calcular la temperatura en deg C Flotador bmp180GetTemperature(Unsigned Int Ut){ Largo x1, x2; x1 = (((Largo)Ut - (Largo)ac6)*(Largo)ac5) >> 15; x2 = ((Largo)Mc << 11)/(x1 + Md); b5 = x1 + x2; Flotador Temp = ((b5 + 8)>>4); Temp = Temp /10; devolución Temp; } Calcular la presión dada los valores de calibración deben conocerse b5 también es necesario por lo que bmp180GetTemperature(...) debe llamarse primero. El valor devuelto será la presión en unidades de Pa. Largo bmp180GetPressure(Unsigned Largo hacia arriba){ Largo x1, x2, x3, b3, b6, P; Unsigned Largo b4, b7; b6 = b5 - 4000; Calcular B3 x1 = (B2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((Largo)ac1)*4 + x3)<<Oss) + 2)>>2; Calcular B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (Unsigned Largo)(x3 + 32768))>>15; b7 = ((Unsigned Largo)(hacia arriba - b3) * (50000>>Oss)); Si (b7 < 0x80000000) P = (b7<<1)/b4; Más P = (b7/b4)<<1; x1 = (P>>8) * (P>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * P)>>16; P += (x1 + x2 + 3791)>>4; Largo Temp = P; devolución Temp; } Leer 1 byte del BMP180 en 'dirección' Char bmp180Leer(Unsigned Char Dirección) { Unsigned Char Datos; Alambre.beginTransmisión(BMP180_ADDRESS); Alambre.Escribir(Dirección); Alambre.endTransmission(); Alambre.solicitudDe(BMP180_ADDRESS, 1); Mientras(!Alambre.Disponible()) ; devolución Alambre.Leer(); } Leer 2 bytes del BMP180 El primer byte será de 'dirección' El segundo byte será de 'dirección'+1 Int bmp180ReadInt(Unsigned Char Dirección) { Unsigned Char Msb, Lsb; Alambre.beginTransmisión(BMP180_ADDRESS); Alambre.Escribir(Dirección); Alambre.endTransmission(); Alambre.solicitudDe(BMP180_ADDRESS, 2); Mientras(Alambre.Disponible()<2) ; Msb = Alambre.Leer(); Lsb = Alambre.Leer(); devolución (Int) Msb<<8 | Lsb; } Lea el valor de temperatura no compensado Unsigned Int bmp180ReadUT(){ Unsigned Int Ut; Escriba 0x2E en el registro 0xF4 Esto solicita una lectura de la temperatura Alambre.beginTransmisión(BMP180_ADDRESS); Alambre.Escribir(0xF4); Alambre.Escribir(0x2E); Alambre.endTransmission(); Espere al menos 4,5 ms Retraso(5); Leer dos bytes de los registros 0xF6 y 0xF7 Ut = bmp180ReadInt(0xF6); devolución Ut; } Lea el valor de presión no compensado Unsigned Largo bmp180ReadUP(){ Unsigned Char Msb, Lsb, xlsb; Unsigned Largo hacia arriba = 0; Escriba 0x34+(OSS<<6) en el registro 0xF4 Solicitar una lectura de presión con ajuste de sobremuestreo Alambre.beginTransmisión(BMP180_ADDRESS); Alambre.Escribir(0xF4); Alambre.Escribir(0x34 + (Oss<<6)); Alambre.endTransmission(); Espere la conversión, el tiempo de retardo depende de OSS Retraso(2 + (3<<Oss)); Registro de lectura 0xF6 (MSB), 0xF7 (LSB) y 0xF8 (XLSB) Msb = bmp180Leer(0xF6); Lsb = bmp180Leer(0xF7); xlsb = bmp180Leer(0xF8); hacia arriba = (((Unsigned Largo) Msb << 16) | ((Unsigned Largo) Lsb << 8) | (Unsigned Largo) xlsb) >> (8-Oss); devolución hacia arriba; } Vacío writeRegister(Int deviceAddress, Byte Dirección, Byte Val) { Alambre.beginTransmisión(deviceAddress); iniciar la transmisión al dispositivo Alambre.Escribir(Dirección); enviar dirección de registro Alambre.Escribir(Val); enviar valor para escribir Alambre.endTransmission(); transmisión final } Int readRegister(Int deviceAddress, Byte Dirección){ Int Ⅴ; Alambre.beginTransmisión(deviceAddress); Alambre.Escribir(Dirección); registrarse para leer Alambre.endTransmission(); Alambre.solicitudDe(deviceAddress, 1); leer un byte Mientras(!Alambre.Disponible()) { Esperando } Ⅴ = Alambre.Leer(); devolución Ⅴ; } Flotador calcAltitude(Flotador Presión){ Flotador Un = Presión/101325; Flotador B = 1/5.25588; Flotador C = Pow(Un,B); C = 1 - C; C = C /0.0000225577; devolución C; }
Por lo tanto, kann der BMP180 ressourcensparend eingesetzt werden und der Code ist f'r fortgeschrittene Benutzer leicht f'r andere Atmel Controller adaptierbar.
1 comentario
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?