import smbus
import time

# BMP280 default address
BMP280_I2C_ADDR = 0x76

# Register addresses
TEMP_MSB_REG = 0xFA
TEMP_LSB_REG = 0xFB
TEMP_XLSB_REG = 0xFC
CONTROL_REG = 0xF4
CONFIG_REG = 0xF5
CALIB_START = 0x88

# Initialize I2C bus
bus = smbus.SMBus(1)  # Use 1 for Raspberry Pi Zero W

def read_calibration():
    calib = bus.read_i2c_block_data(BMP280_I2C_ADDR, CALIB_START, 24)
    dig_T1 = calib[1] << 8 | calib[0]
    dig_T2 = (calib[3] << 8 | calib[2]) if calib[3] < 128 else ((calib[3] << 8 | calib[2]) - 65536)
    dig_T3 = (calib[5] << 8 | calib[4]) if calib[5] < 128 else ((calib[5] << 8 | calib[4]) - 65536)
    return dig_T1, dig_T2, dig_T3

dig_T1, dig_T2, dig_T3 = read_calibration()

def read_temperature():
    # Set control register to forced mode, 1x oversampling for temperature
    bus.write_byte_data(BMP280_I2C_ADDR, CONTROL_REG, 0x25)
    time.sleep(0.1)  # Wait for measurement

    # Read raw temperature data
    msb = bus.read_byte_data(BMP280_I2C_ADDR, TEMP_MSB_REG)
    lsb = bus.read_byte_data(BMP280_I2C_ADDR, TEMP_LSB_REG)
    xlsb = bus.read_byte_data(BMP280_I2C_ADDR, TEMP_XLSB_REG)
    
    # Combine bytes
    raw_temp = (msb << 12) | (lsb << 4) | (xlsb >> 4)
    
    # Apply calibration using floating point calculations
    var1 = ((raw_temp / 16384.0) - (dig_T1 / 1024.0)) * dig_T2
    var2 = (((raw_temp / 131072.0) - (dig_T1 / 8192.0)) ** 2) * dig_T3
    t_fine = var1 + var2
    temp_celsius = t_fine / 5120.0
    return temp_celsius

if __name__ == "__main__":
    try:
        while True:
            temperature = read_temperature()
            print(f"Temperature: {temperature:.2f}°C")
            time.sleep(5)  # Read every 5 seconds
    except KeyboardInterrupt:
        print("Measurement stopped.")
