Class: Denko::Sensor::HTU21D

Inherits:
Object
  • Object
show all
Includes:
Behaviors::Reader, I2C::Peripheral
Defined in:
lib/denko/sensor/htu21d.rb

Constant Summary collapse

SOFT_RESET =

Commands

0xFE
WRITE_CONFIG =
0xE6
READ_TEMPERATURE_BLOCKING =
0xE3
READ_HUMIDITY_BLOCKING =
0xE5
CONFIG_DEFAULT =

Config values

0b00000011
HEATER_MASK =
0b00000100
RESOLUTION_MASK =
0b10000001
RESOLUTIONS =

Only 4 resolution combinations are available. Set by giving a bitmask from the datasheet:

{
  0x00 => {temperature: 14, humidity: 12},
  0x01 => {temperature: 12, humidity: 8},
  0x80 => {temperature: 13, humidity: 10},
  0x81 => {temperature: 11, humidity: 11},
}

Instance Attribute Summary collapse

Attributes included from Behaviors::Callbacks

#callback_mutex

Attributes included from I2C::Peripheral

#i2c_frequency, #i2c_repeated_start

Attributes included from Behaviors::BusPeripheral

#address

Attributes included from Behaviors::Component

#board

Instance Method Summary collapse

Methods included from Behaviors::Reader

#_read, #read, #read_using, #wait_for_read

Methods included from Behaviors::Callbacks

#add_callback, #callbacks, #initialize, #remove_callback, #update

Methods included from Behaviors::State

#initialize, #state

Methods included from I2C::Peripheral

#i2c_read, #i2c_write

Methods included from Behaviors::BusPeripheral

#atomically

Methods included from Behaviors::Component

#initialize, #micro_delay

Instance Attribute Details

#humidityObject (readonly)

Returns the value of attribute humidity.



18
19
20
# File 'lib/denko/sensor/htu21d.rb', line 18

def humidity
  @humidity
end

#temperatureObject (readonly)

Returns the value of attribute temperature.



18
19
20
# File 'lib/denko/sensor/htu21d.rb', line 18

def temperature
  @temperature
end

Instance Method Details

#[](key) ⇒ Object



95
96
97
98
99
# File 'lib/denko/sensor/htu21d.rb', line 95

def [](key)
  @state_mutex.synchronize do
    return @state[key]
  end
end

#after_initialize(options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/denko/sensor/htu21d.rb', line 25

def after_initialize(options={})
  super(options)

  # Avoid repeated memory allocation for callback data and state.
  @reading   = [:temperatue, 0.0]
  self.state = { temperature: nil, humidity: nil }
  @mutex     = Mutex.new

  # Temperature and humidity objects, to treat this like 2 sensors.
  @temperature = Temperature.new(self)
  @humidity    = Humidity.new(self)

  @config = CONFIG_DEFAULT
  reset
  heater_off
end

#before_initialize(options = {}) ⇒ Object



20
21
22
23
# File 'lib/denko/sensor/htu21d.rb', line 20

def before_initialize(options={})
  @i2c_address = 0x40
  super(options)
end

#calculate_crc(value) ⇒ Object

CRC calculation adapted from offical driver, found here: github.com/TEConnectivity/HTU21D_Generic_C_Driver/blob/master/htu21d.c#L275



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/denko/sensor/htu21d.rb', line 152

def calculate_crc(value)
  polynomial = 0x988000   # x^8 + x^5 + x^4 + 1
  msb        = 0x800000
  mask       = 0xFF8000
  result     = value << 8 # Pad right with length of output CRC

  while msb != 0x80
    result = ((result ^ polynomial) & mask) | (result & ~mask) if (result & msb !=0)
    msb        >>= 1
    mask       >>= 1
    polynomial >>= 1
  end
  result
end

#heater_offObject



66
67
68
69
# File 'lib/denko/sensor/htu21d.rb', line 66

def heater_off
  @config &= ~HEATER_MASK
  write_config
end

#heater_off?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/denko/sensor/htu21d.rb', line 57

def heater_off?
  !heater_on?
end

#heater_onObject



61
62
63
64
# File 'lib/denko/sensor/htu21d.rb', line 61

def heater_on
  @config |= HEATER_MASK
  write_config
end

#heater_on?Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/denko/sensor/htu21d.rb', line 53

def heater_on?
  (@config & HEATER_MASK) > 0
end

#pre_callback_filter(bytes) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/denko/sensor/htu21d.rb', line 115

def pre_callback_filter(bytes)
  # Raw value is first 2 bytes big-endian.
  raw_value = (bytes[0] << 8) | bytes[1]

  # Quietly ignore readings with bad CRC.
  unless calculate_crc(raw_value) == bytes[2]
    @humidity.update(nil)
    @temperature.update(nil)
    return nil
  end

  # Lowest 2 bits must be zeroed before conversion.
  raw_value = raw_value & 0xFFFC

  # Bit 1 of LSB determines type of reading; 0 for temperature, 1 for humidity.
  if (bytes[1] & 0b00000010) > 0
    @reading[0] = :humidity
    @reading[1] = (raw_value.to_f / 524.288) - 6
    @humidity.update(@reading[1])
  else
    @reading[0] = :temperature
    @reading[1] = (175.72 * raw_value.to_f / 65536) - 46.8
    @temperature.update(@reading[1])
  end
  @reading
end

#read_humidityObject



108
109
110
111
112
113
# File 'lib/denko/sensor/htu21d.rb', line 108

def read_humidity
  @mutex.synchronize do
    result = read_using -> { i2c_read(READ_HUMIDITY_BLOCKING, 3) }
    result[1] if result
  end
end

#read_temperatureObject



101
102
103
104
105
106
# File 'lib/denko/sensor/htu21d.rb', line 101

def read_temperature
  @mutex.synchronize do
    result = read_using -> { i2c_read(READ_TEMPERATURE_BLOCKING, 3) }
    result[1] if result
  end
end

#resetObject



42
43
44
45
# File 'lib/denko/sensor/htu21d.rb', line 42

def reset
  i2c_write [SOFT_RESET]
  sleep 0.015
end

#resolutionObject

Raises:

  • (StandardError)


89
90
91
92
93
# File 'lib/denko/sensor/htu21d.rb', line 89

def resolution
  resolution_bits = @config & RESOLUTION_MASK
  raise StandardError, "cannot get resolution from config register: #{@config}" unless RESOLUTIONS[resolution_bits]
  RESOLUTIONS[resolution_bits]
end

#resolution=(setting) ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
86
87
# File 'lib/denko/sensor/htu21d.rb', line 82

def resolution=(setting)
  raise ArgumentError, "wrong resolution setting given: #{mask}" unless RESOLUTIONS.keys.include? setting
  @config &= ~RESOLUTION_MASK
  @config |= setting
  write_config
end

#update_state(reading) ⇒ Object



142
143
144
145
146
# File 'lib/denko/sensor/htu21d.rb', line 142

def update_state(reading)
  @state_mutex.synchronize do
    @state[reading[0]] = reading[1]
  end
end

#write_configObject



47
48
49
50
51
# File 'lib/denko/sensor/htu21d.rb', line 47

def write_config
  @mutex.synchronize do
    i2c_write [WRITE_CONFIG, @config]
  end
end