/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // // This fragment driver code was derived from the Adafruit BME Library // https://github.com/adafruit/Adafruit_BME280_Library // Copyright (c) 2015, Limor Fried & Kevin Townsend for Adafruit Industries // All rights reserved. // The Adafruit BME Library is subject to the conditions and disclaimer: // https://github.com/adafruit/Adafruit_BME280_Library/blob/master/LICENSE // // To utilize a BME280 sensor, use the Toitware driver included in the SDK // https://libs.toit.io/drivers/bme280/library-summary // import binary import serial class BME280x: static BME280_ADDRESS ::= 0x77 static BME280_ADDRESS_ALTERNATE ::= 0x76 static BME280_REGISTER_DIG_T1 ::= 0x88 static BME280_REGISTER_DIG_T2 ::= 0x8A static BME280_REGISTER_DIG_T3 ::= 0x8C static BME280_REGISTER_CHIPID ::= 0xD0 static BME280_REGISTER_VERSION ::= 0xD1 static BME280_REGISTER_SOFTRESET ::= 0xE0 static BME280_REGISTER_CONTROLHUMID ::= 0xF2 static BME280_REGISTER_STATUS ::= 0xF3 static BME280_REGISTER_CONTROL ::= 0xF4 static BME280_REGISTER_CONFIG ::= 0xF5 static BME280_REGISTER_TEMPDATA ::= 0xFA static REG_DEFAULT_ADDRESS_ ::= 0x00 calib_dig_T1 := null calib_dig_T2 := null calib_dig_T3 := null registers_/serial.Registers constructor device/serial.Device: registers_ = device.registers on: sensorID_ := registers_.read_u8 BME280_REGISTER_CHIPID if sensorID_ != 0x60: throw "INVALID_CHIP" registers_.write_u8 BME280_REGISTER_SOFTRESET 0xB6 sleep --ms=10 while isReadingCalibration: sleep --ms=10 readCoefficients setSampling sleep --ms=100 off: isReadingCalibration -> bool: rStatus := registers_.read_u8 BME280_REGISTER_STATUS return (rStatus & (1 << 0)) != 0 readCoefficients: calib_dig_T1 = registers_.read_u16_le BME280_REGISTER_DIG_T1 calib_dig_T2 = registers_.read_i16_le BME280_REGISTER_DIG_T2 calib_dig_T3 = registers_.read_i16_le BME280_REGISTER_DIG_T3 setSampling: setSampling Sensor_Mode.MODE_NORMAL Sensor_Sampling.SAMPLING_X16 Sensor_Sampling.SAMPLING_X16 Sensor_Sampling.SAMPLING_X16 Sensor_Filter.FILTER_OFF Standby_Duration.STANDBY_MS_0_5 --lines setSampling mode/Sensor_Mode -> none tempSampling/Sensor_Sampling pressSampling/Sensor_Sampling humSampling/Sensor_Sampling filter/Sensor_Filter standby_duration/Standby_Duration --lines: measurementRegistor := Control_Measurement tempSampling pressSampling mode humidityRegistor := Control_Humidity humSampling configurationRegistor := Configuration standby_duration filter // making sure sensor is in sleep mode before setting configuration // as it otherwise may be ignored registers_.write_u8 BME280_REGISTER_CONTROL Sensor_Mode.MODE_SLEEP.x // you must make sure to also set REGISTER_CONTROL after setting the // CONTROLHUMID register, otherwise the values won't be applied (see // DS 5.4.3) registers_.write_u8 BME280_REGISTER_CONTROLHUMID humidityRegistor.x registers_.write_u8 BME280_REGISTER_CONFIG configurationRegistor.x registers_.write_u8 BME280_REGISTER_CONTROL measurementRegistor.x read_temperature -> float: adc_T := registers_.read_u24_be BME280_REGISTER_TEMPDATA if adc_T == 0x800000: // value in case temp measurement was disabled return float.NAN adc_T >>= 4 // var1 = ((((adc_T >> 3) - ((int32_t)_bme280_calib.dig_T1 << 1))) * ((int32_t)_bme280_calib.dig_T2)) >> 11; var1 := (((adc_T >> 3) - (calib_dig_T1 << 1)) * (calib_dig_T2)) >> 11; // var2 = (((((adc_T >> 4) - ((int32_t)_bme280_calib.dig_T1)) * ((adc_T >> 4) - ((int32_t)_bme280_calib.dig_T1))) >> 12) * ((int32_t)_bme280_calib.dig_T3)) >> 14; var2 := (((((adc_T >> 4) - calib_dig_T1) * ((adc_T >> 4) - calib_dig_T1)) >> 12) * calib_dig_T3) >> 14; t_fine := var1 + var2 + 0 // t_fine_adjust // not supported in this sample code T := (t_fine * 5 + 128) >> 8; return T / 100.0; class Sensor_Mode: x/int constructor .x: constructor.MODE_SLEEP: return Sensor_Mode 0x0b00 constructor.MODE_FORCED: return Sensor_Mode 0x0b01 constructor.MODE_NORMAL: return Sensor_Mode 0x0b11 class Sensor_Sampling: x/int constructor .x: constructor.SAMPLING_NONE: return Sensor_Sampling 0x0b000 constructor.SAMPLING_X1: return Sensor_Sampling 0x0b001 constructor.SAMPLING_X2: return Sensor_Sampling 0x0b010 constructor.SAMPLING_X4: return Sensor_Sampling 0x0b011 constructor.SAMPLING_X8: return Sensor_Sampling 0x0b100 constructor.SAMPLING_X16: return Sensor_Sampling 0x0b101 class Sensor_Filter: x/int constructor .x: constructor.FILTER_OFF: return Sensor_Filter 0x0b000 constructor.FILTER_X2: return Sensor_Filter 0x0b001 constructor.FILTER_X4: return Sensor_Filter 0x0b010 constructor.FILTER_X8: return Sensor_Filter 0x0b011 constructor.FILTER_X16: return Sensor_Filter 0x0b100 class Standby_Duration: x/int constructor .x: constructor.STANDBY_MS_0_5: return Standby_Duration 0x0b000 constructor.STANDBY_MS_10: return Standby_Duration 0x0b110 constructor.STANDBY_MS_20: return Standby_Duration 0x0b111 constructor.STANDBY_MS_62_5: return Standby_Duration 0x0b001 constructor.STANDBY_MS_125: return Standby_Duration 0x0b010 constructor.STANDBY_MS_250: return Standby_Duration 0x0b011 constructor.STANDBY_MS_500: return Standby_Duration 0x0b100 constructor.STANDBY_MS_1000: return Standby_Duration 0x0b101 class Control_Measurement: osrs_t/Sensor_Sampling osrs_p/Sensor_Sampling mode/Sensor_Mode constructor .osrs_t .osrs_p .mode: x -> int: return (osrs_t.x << 5) | (osrs_p.x << 2) | mode.x class Control_Humidity: osrs_h/Sensor_Sampling constructor .osrs_h: none_ ::= 5 // unused, don't set x -> int: return osrs_h.x class Configuration: t_sb/Standby_Duration filter/Sensor_Filter constructor .t_sb .filter: none_ ::= 1 // unused, don't set spi3w_en_ ::= 1 // unused, don't set x -> int: return (t_sb.x << 5) | (filter.x << 2) | spi3w_en_