class DHT11::Sensor
Public Class Methods
new(pin, tries: 10, interval: 0.1)
click to toggle source
# File lib/dht11.rb, line 21 def initialize(pin, tries: 10, interval: 0.1) @pin = pin @tries = tries @interval = interval RPi::GPIO.set_numbering(:bcm) end
Public Instance Methods
read()
click to toggle source
# File lib/dht11.rb, line 28 def read @tries.times do @last_result = read_once return @last_result if @last_result.valid? sleep @interval end @last_result end
read_once()
click to toggle source
# File lib/dht11.rb, line 37 def read_once send_initial_signal raw_inputs = collect_raw_input periods = parse_inputs_into_pull_up_periods(raw_inputs) if periods.length != 40 return Result.new(Err::MISSING_DATA, Float::NAN, Float::NAN) end bits = calculate_bits(periods) bytes = bits_to_bytes(bits) checksum = calculate_checksum(bytes) if bytes[4] != checksum return Result.new(Err::CRC, Float::NAN, Float::NAN) end temperature = bytes_to_temperature(bytes).to_f humidity = bytes_to_humidity(bytes).to_f Result.new(Err::NO_ERROR, temperature, humidity) end
Private Instance Methods
bits_to_bytes(bits)
click to toggle source
# File lib/dht11.rb, line 140 def bits_to_bytes(bits) bytes = [] byte = 0 bits.each_with_index do |bit, i| byte = byte << 1 byte = byte | (bit ? 1 : 0) if (i + 1) % 8 == 0 bytes.push(byte) byte = 0 end end bytes end
bytes_to_humidity(bytes)
click to toggle source
# File lib/dht11.rb, line 163 def bytes_to_humidity(bytes) bytes[0] end
bytes_to_temperature(bytes)
click to toggle source
# File lib/dht11.rb, line 159 def bytes_to_temperature(bytes) bytes[2] end
calculate_bits(pull_up_periods)
click to toggle source
# File lib/dht11.rb, line 128 def calculate_bits(pull_up_periods) shortest_period = pull_up_periods.min() longest_period = pull_up_periods.max() halfway = shortest_period + (longest_period - shortest_period)/2r bits = [] pull_up_periods.each do |period| bit = period > halfway bits.push(bit) end bits end
calculate_checksum(bytes)
click to toggle source
# File lib/dht11.rb, line 155 def calculate_checksum(bytes) bytes.slice(0..3).sum & 255 end
collect_raw_input()
click to toggle source
# File lib/dht11.rb, line 73 def collect_raw_input RPi::GPIO.setup(@pin, as: :input, pull: :up) max_unchanged_count = 100 unchanged_count = 0 last_input = -1 raw_inputs = [] while unchanged_count < max_unchanged_count current_input = RPi::GPIO.high?(@pin) raw_inputs.push(current_input) if last_input == current_input unchanged_count += 1 else unchanged_count = 0 last_input = current_input end end raw_inputs end
parse_inputs_into_pull_up_periods(raw_inputs)
click to toggle source
# File lib/dht11.rb, line 93 def parse_inputs_into_pull_up_periods(raw_inputs) state = State::INITIAL_PULL_DOWN periods = [] period = 0 raw_inputs.each do |input| period += 1 case state when State::INITIAL_PULL_DOWN if input == Level::LOW state = State::INITIAL_PULL_UP end when State::INITIAL_PULL_UP if input == Level::HIGH state = State::DATA_FIRST_PULL_DOWN end when State::DATA_FIRST_PULL_DOWN if input == Level::LOW state = State::DATA_PULL_UP end when State::DATA_PULL_UP if input == Level::HIGH period = 0 state = State::DATA_PULL_DOWN end when State::DATA_PULL_DOWN if input == Level::LOW periods.push(period) state = State::DATA_PULL_UP end end end return periods end
send_and_sleep(output, sleep_second)
click to toggle source
# File lib/dht11.rb, line 58 def send_and_sleep(output, sleep_second) if output == Level::HIGH RPi::GPIO.set_high(@pin) else RPi::GPIO.set_low(@pin) end sleep sleep_second end
send_initial_signal()
click to toggle source
# File lib/dht11.rb, line 67 def send_initial_signal RPi::GPIO.setup(@pin, as: :output) send_and_sleep(Level::HIGH, 0.05) send_and_sleep(Level::LOW, 0.02) end