Created
July 23, 2023 03:22
-
-
Save k-takata/16dfca7faebe38a30bb592c1d70bf0cc to your computer and use it in GitHub Desktop.
Using AE-BME680 with GR-CITRUS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!mruby | |
class BME680 | |
ID = 0x77 | |
#REG_COEFF3 = 0x00 | |
REG_FIELD0 = 0x1D | |
REG_IDAC_HEAT0 = 0x50 | |
REG_RES_HEAT0 = 0x5A | |
REG_GAS_WAIT0 = 0x64 | |
REG_SHD_HEATR_DUR = 0x6E | |
REG_CTRL_GAS_0 = 0x70 | |
REG_CTRL_GAS_1 = 0x71 | |
REG_CTRL_HUM = 0x72 | |
REG_CTRL_MEAS = 0x74 | |
REG_CONFIG = 0x75 | |
REG_UNIQUE_ID = 0x83 | |
REG_COEFF1 = 0x8A | |
REG_CHIP_ID = 0xD0 | |
REG_RESET = 0xE0 | |
REG_COEFF2 = 0xE1 | |
REG_VARIANT_ID = 0xF0 | |
LEN_COEFF1 = 23 | |
LEN_COEFF2 = 14 | |
#LEN_COEFF3 = 5 | |
#LEN_COEFF_ALL = LEN_COEFF1 + LEN_COEFF2 + LEN_COEFF3 | |
LEN_FIELD = 17 | |
def initialize | |
@i2c = I2c.new(1) | |
end | |
def init | |
@i2c.write(ID, REG_RESET, 0xB6) | |
#delay(100) | |
if @i2c.read(ID, REG_CHIP_ID) != 0x61 then | |
puts "BME680 not found." | |
end | |
#puts(["ctrl_meas", @i2c.read(ID, REG_CTRL_MEAS)]) | |
get_calib_data() | |
#puts(["@coeff", @coeff]) | |
end | |
def u16(msb, lsb) | |
return (msb << 8) + lsb | |
end | |
def s16(msb, lsb) | |
return (msb << 8) + lsb + (((msb & 0x80) == 0) ? 0 : ~0xffff) | |
end | |
def u8(b) | |
return b | |
end | |
def s8(b) | |
return b + (((b & 0x80) == 0) ? 0 : ~0xff) | |
end | |
def get_calib_data | |
@coeff = [] | |
delay 10 | |
@i2c.begin(ID) | |
@i2c.lwrite(REG_COEFF1) | |
@i2c.end(0) | |
@i2c.request(ID, LEN_COEFF1) | |
LEN_COEFF1.times do | |
@coeff << @i2c.lread() | |
end | |
@i2c.begin(ID) | |
@i2c.lwrite(REG_COEFF2) | |
@i2c.end(0) | |
@i2c.request(ID, LEN_COEFF2) | |
LEN_COEFF2.times do | |
@coeff << @i2c.lread() | |
end | |
#@i2c.begin(ID) | |
#@i2c.lwrite(REG_COEFF3) | |
#@i2c.end(0) | |
#@i2c.request(ID, LEN_COEFF3) | |
#LEN_COEFF3.times do | |
# @coeff << @i2c.lread() | |
#end | |
@par_t1 = u16(@coeff[32], @coeff[31]) | |
@par_t2 = s16(@coeff[1], @coeff[0]) | |
@par_t3 = s8(@coeff[2]) | |
@par_p1 = u16(@coeff[5], @coeff[4]) | |
@par_p2 = s16(@coeff[7], @coeff[6]) | |
@par_p3 = s8(@coeff[8]) | |
@par_p4 = s16(@coeff[11], @coeff[10]) | |
@par_p5 = s16(@coeff[13], @coeff[12]) | |
@par_p6 = s8(@coeff[15]) | |
@par_p7 = s8(@coeff[14]) | |
@par_p8 = s16(@coeff[19], @coeff[18]) | |
@par_p9 = s16(@coeff[21], @coeff[20]) | |
@par_p10 = u8(@coeff[22]) | |
@par_h1 = (@coeff[25] << 4) + (@coeff[24] & 0x0f) | |
@par_h2 = (@coeff[23] << 4) + ((@coeff[24] >> 4) & 0x0f) | |
@par_h3 = s8(@coeff[26]) | |
@par_h4 = s8(@coeff[27]) | |
@par_h5 = s8(@coeff[28]) | |
@par_h6 = u8(@coeff[29]) | |
@par_h7 = s8(@coeff[30]) | |
@par_g1 = s8(@coeff[35]) | |
@par_g2 = s16(@coeff[34], @coeff[33]) | |
@par_g3 = s8(@coeff[36]) | |
end | |
def set_op_mode(mode) | |
# Wait until it becomes to sleep mode. | |
cur_mode = 0 | |
loop do | |
cur_mode = @i2c.read(ID, REG_CTRL_MEAS) | |
break if (cur_mode & 0x03) == 0 | |
delay 10 | |
end | |
if mode != 0 then | |
@i2c.write(ID, REG_CTRL_MEAS, (cur_mode & ~0x03) | (mode & 0x03)) | |
end | |
end | |
def set_conf(osrs_t, osrs_p, osrs_h, filter) | |
set_op_mode(0) | |
tmp = @i2c.read(ID, REG_CTRL_MEAS) | |
@i2c.write(ID, REG_CTRL_MEAS, ((osrs_t & 0x07) << 5) | ((osrs_p & 0x07) << 2) | (tmp & 0x03)) | |
tmp = @i2c.read(ID, REG_CTRL_HUM) | |
@i2c.write(ID, REG_CTRL_HUM, (tmp & ~0x07) | (osrs_h & 0x07)) | |
tmp = @i2c.read(ID, REG_CONFIG) | |
@i2c.write(ID, REG_CONFIG, (tmp & ~0x1C) | ((filter & 0x07) << 2)) | |
end | |
def set_heatr_conf(osrs_t, osrs_p, osrs_h, filter) | |
# TODO | |
end | |
def read_field_data | |
data = [] | |
@i2c.begin(ID) | |
@i2c.lwrite(REG_FIELD0) | |
@i2c.end(0) | |
@i2c.request(ID, LEN_FIELD) | |
LEN_FIELD.times do | |
data << @i2c.lread() | |
end | |
@adc_pres = (data[2] << 12) | (data[3] << 4) | (data[4] >> 4) | |
@adc_temp = (data[5] << 12) | (data[6] << 4) | (data[7] >> 4) | |
@adc_hum = (data[8] << 8) | data[9] | |
end | |
def calc_temp | |
var1 = (@adc_temp >> 3) - (@par_t1 << 1) | |
var2 = (var1 * @par_t2) >> 11 | |
var3 = ((((var1 >> 1) * (var1 >> 1)) >> 12) * (@par_t3 << 4)) >> 14 | |
@t_fine = var2 + var3 | |
@temp_comp = ((@t_fine * 5) + 128) >> 8 | |
return @temp_comp | |
end | |
def calc_pres | |
var1 = (@t_fine >> 1) - 64000 | |
var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * @par_p6) >> 2 | |
var2 = var2 + ((var1 * @par_p5) << 1) | |
var2 = (var2 >> 2) + (@par_p4 << 16) | |
var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * (@par_p3 << 5)) >> 3) + ((@par_p2 * var1) >> 1) | |
var1 = var1 >> 18 | |
var1 = ((32768 + var1) * @par_p1) >> 15 | |
press_comp = 1048576 - @adc_pres | |
press_comp = (press_comp - (var2 >> 12)) * 3125 | |
if press_comp >= (1 << 30) then | |
press_comp = (press_comp / var1) << 1 | |
else | |
press_comp = (press_comp << 1) / var1 | |
end | |
var1 = (@par_p9 * (((press_comp >> 3) * (press_comp >> 3)) >> 13)) >> 12 | |
var2 = ((press_comp >> 2) * @par_p8) >> 13 | |
var3 = ((press_comp >> 8) * (press_comp >> 8) * (press_comp >> 8) * @par_p10) >> 17 | |
press_comp = press_comp + ((var1 + var2 + var3 + (@par_p7 << 7)) >> 4) | |
return press_comp | |
end | |
def calc_hum | |
temp_scaled = @temp_comp | |
var1 = @adc_hum - (@par_h1 << 4) - (((temp_scaled * @par_h3) / 100) >> 1) | |
var2 = (@par_h2 * (((temp_scaled * @par_h4) / 100) + (((temp_scaled * ((temp_scaled * @par_h5) / 100)) >> 6) / 100) + (1 << 14))) >> 10 | |
var3 = var1 * var2 | |
var4 = ((@par_h6 << 7) + ((temp_scaled * @par_h7) / 100)) >> 4 | |
var5 = ((var3 >> 14) * (var3 >> 14)) >> 10 | |
var6 = (var4 * var5) >> 1 | |
comp_hum = (((var3 + var6) >> 10) * 1000) >> 12 | |
if comp_hum > 100000 | |
comp_hum = 100000 | |
elsif comp_hum < 0 | |
comp_hum = 0 | |
end | |
return comp_hum | |
end | |
end | |
bme680 = BME680.new | |
bme680.init | |
bme680.set_conf(5, 5, 5, 3) | |
5.times do | |
bme680.set_op_mode(1) | |
bme680.set_op_mode(0) | |
bme680.read_field_data | |
s = bme680.calc_temp.to_s | |
s[-2,0] = '.' | |
puts("temp: #{s} C") | |
s = bme680.calc_pres.to_s | |
s[-2,0] = '.' | |
puts("pres: #{s} hPa") | |
s = bme680.calc_hum.to_s | |
s[-3,0] = '.' | |
puts("hum: #{s} %") | |
puts | |
delay 1000 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment