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



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/denko/sensor/htu21d.rb', line 156

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
141
142
143
144
# 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
    # Calculate humidity and limit within 0-100 range.
    humidity = (raw_value.to_f / 524.288) - 6
    humidity = 0.0   if humidity < 0.0
    humidity = 100.0 if humidity > 100.0
    @reading[0] = :humidity
    @reading[1] = humidity
    @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



146
147
148
149
150
# File 'lib/denko/sensor/htu21d.rb', line 146

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