Class: Denko::Sensor::HTU21D

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

Constant Summary collapse

I2C_ADDRESS =
0x40
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},
}

Constants included from Behaviors::Lifecycle

Behaviors::Lifecycle::CALLBACK_METHODS

Constants included from Behaviors::Reader

Behaviors::Reader::READ_WAIT_TIME

Constants included from I2C::Peripheral

I2C::Peripheral::I2C_FREQUENCY, I2C::Peripheral::I2C_REPEATED_START

Instance Attribute Summary

Attributes included from Behaviors::Threaded

#interrupts_enabled, #thread

Attributes included from I2C::Peripheral

#i2c_frequency, #i2c_repeated_start

Attributes included from Behaviors::Component

#board, #params

Instance Method Summary collapse

Methods included from HumidityHelper

#humidity

Methods included from TemperatureHelper

#temperature, #temperature_f, #temperature_k

Methods included from Behaviors::Lifecycle

included

Methods included from Behaviors::Poller

#poll, #poll_using, #stop

Methods included from Behaviors::Threaded

#enable_interrupts, included, #mruby_thread_check, #stop, #stop_thread, #threaded, #threaded_loop

Methods included from Behaviors::Reader

#read_busy?, #read_nb, #read_raw, #read_using, #update

Methods included from Behaviors::Callbacks

#add_callback, #callbacks, #remove_callback, #update

Methods included from I2C::Peripheral

#address, #i2c_default, #i2c_read, #i2c_read_raw, #i2c_write

Methods included from Behaviors::BusPeripheralAddressed

#address

Methods included from Behaviors::BusPeripheral

#atomically

Methods included from Behaviors::Component

#initialize, #micro_delay

Instance Method Details

#_readObject



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

def _read
  _read_temperature
  _read_humidity
end

#_read_humidityObject



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

def _read_humidity
  i2c_read(3, register: READ_HUMIDITY_BLOCKING)
end

#_read_temperatureObject



107
108
109
# File 'lib/denko/sensor/htu21d.rb', line 107

def _read_temperature
  i2c_read(3, register: READ_TEMPERATURE_BLOCKING)
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



59
60
61
62
# File 'lib/denko/sensor/htu21d.rb', line 59

def heater_off
  @config &= ~HEATER_MASK
  write_config
end

#heater_off?Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/denko/sensor/htu21d.rb', line 50

def heater_off?
  !heater_on?
end

#heater_onObject



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

def heater_on
  @config |= HEATER_MASK
  write_config
end

#heater_on?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/denko/sensor/htu21d.rb', line 46

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

#humidity_resolutionObject



92
93
94
# File 'lib/denko/sensor/htu21d.rb', line 92

def humidity_resolution
  resolution[:humidity]
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
# 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]
  return { error: 'CRC failure' } unless calculate_crc(raw_value) == bytes[2]

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

  # Bit 1 of LS byte 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[:humidity] = humidity
  else
    reading[:temperature] = (175.72 * raw_value.to_f / 65536) - 46.8
  end

  return nil unless (reading[:temperature] && reading[:humidity])

  reading
end

#read(*args, **kwargs, &block) ⇒ Object

Workaround for :read callbacks getting automatically removed on first reading.



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

def read(*args, **kwargs, &block)
  read_using(self.method(:_read_temperature), *args, **kwargs)
  read_using(self.method(:_read_humidity), *args, **kwargs, &block)
end

#readingObject



33
34
35
# File 'lib/denko/sensor/htu21d.rb', line 33

def reading
  @reading ||= { temperature: nil, humidity: nil }
end

#resetObject



37
38
39
40
# File 'lib/denko/sensor/htu21d.rb', line 37

def reset
  i2c_write [SOFT_RESET]
  sleep 0.015
end

#resolutionObject

Raises:

  • (StandardError)


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

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)


75
76
77
78
79
80
# File 'lib/denko/sensor/htu21d.rb', line 75

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

#stateObject



29
30
31
# File 'lib/denko/sensor/htu21d.rb', line 29

def state
  @state ||= { temperature: nil, humidity: nil }
end

#temperature_resolutionObject



88
89
90
# File 'lib/denko/sensor/htu21d.rb', line 88

def temperature_resolution
  resolution[:temperature]
end

#update_state(reading) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/denko/sensor/htu21d.rb', line 139

def update_state(reading)
  @state_mutex.lock
  @state[:temperature] = reading[:temperature]
  @state[:humidity]    = reading[:humidity]
  @state_mutex.unlock

  # Reset so pre_callback_filter can check for both values.
  reading[:temperature] = nil
  reading[:humidity]    = nil

  @state
end

#write_configObject



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

def write_config
  i2c_write [WRITE_CONFIG, @config]
end