dht11 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6b8274fbb226d6dae7fdce8db8fc7da92bcb97cca882e45d68b44099bccd0444
4
+ data.tar.gz: d17b2ecbfccd406a3d3f04b9a3aa2be9c8ae9f11965f4ef08935ec7f368b2f1b
5
+ SHA512:
6
+ metadata.gz: 5dd86c4913b85e5f0e6cdfbfe08d51ad4cc8cb1d9f5452809e0a4b629cebb979eca7029ec635daed28a641ca64a7bc433c21bc21062029cef0d85975890476af
7
+ data.tar.gz: ccf498800bace1ed69451035f82e6350df6022b8524c4fbdffb286b67c74699fca20a0e3b5c537ab1b72d56c9112ff5890e143c4fca4dd4690aa4c99cbe4cb42
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dht11.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
8
+ gem "rpi_gpio"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # DHT11
2
+
3
+ Ruby conversion of [DHT11 Python library](https://github.com/szazo/DHT11_Python) which depends only on [rpi_gpio](https://github.com/ClockVapor/rpi_gpio).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'dht11'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install dht11
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'dht11'
25
+
26
+ dht = DHT11::Sensor.new(26) # BCM numbering
27
+ result = dht.read
28
+ puts "Temperature: #{result.temperature}, Humidity: #{result.humidity}"
29
+ ```
30
+
31
+ You can also try running the binary as:
32
+
33
+ $ bundle exec bin/dht11
34
+
35
+ ## Development
36
+
37
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
38
+
39
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
40
+
41
+ ## Contributing
42
+
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tankenta/dht11.
44
+
45
+
46
+ ## License
47
+
48
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dht11"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/dht11 ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
4
+ require "dht11"
5
+ require "dht11/app"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/dht11.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ require_relative 'lib/dht11/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "dht11"
5
+ spec.version = DHT11::VERSION
6
+ spec.authors = ["Kenta Hirayama"]
7
+ spec.email = ["hkenta112@gmail.com"]
8
+
9
+ spec.summary = %q{Ruby conversion of DHT11 Python library which depends only on rpi_gpio.}
10
+ spec.homepage = "https://github.com/tankenta/dht11"
11
+ spec.license = "MIT"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "rpi_gpio"
26
+ end
data/lib/dht11.rb ADDED
@@ -0,0 +1,167 @@
1
+ require "rpi_gpio"
2
+
3
+ require "dht11/version"
4
+ require "dht11/result"
5
+
6
+ module DHT11
7
+ module Level
8
+ HIGH = true
9
+ LOW = false
10
+ end
11
+
12
+ module State
13
+ INITIAL_PULL_DOWN = :initial_pull_down
14
+ INITIAL_PULL_UP = :initial_pull_up
15
+ DATA_FIRST_PULL_DOWN = :data_first_pull_down
16
+ DATA_PULL_UP = :data_pull_up
17
+ DATA_PULL_DOWN = :data_pull_down
18
+ end
19
+
20
+ class Sensor
21
+ def initialize(pin, tries: 10, interval: 0.1)
22
+ @pin = pin
23
+ @tries = tries
24
+ @interval = interval
25
+ RPi::GPIO.set_numbering(:bcm)
26
+ end
27
+
28
+ def read
29
+ @tries.times do
30
+ @last_result = read_once
31
+ return @last_result if @last_result.valid?
32
+ sleep @interval
33
+ end
34
+ @last_result
35
+ end
36
+
37
+ def read_once
38
+ send_initial_signal
39
+ raw_inputs = collect_raw_input
40
+ periods = parse_inputs_into_pull_up_periods(raw_inputs)
41
+ if periods.length != 40
42
+ return Result.new(Err::MISSING_DATA, Float::NAN, Float::NAN)
43
+ end
44
+ bits = calculate_bits(periods)
45
+ bytes = bits_to_bytes(bits)
46
+ checksum = calculate_checksum(bytes)
47
+ if bytes[4] != checksum
48
+ return Result.new(Err::CRC, Float::NAN, Float::NAN)
49
+ end
50
+
51
+ temperature = bytes_to_temperature(bytes).to_f
52
+ humidity = bytes_to_humidity(bytes).to_f
53
+ Result.new(Err::NO_ERROR, temperature, humidity)
54
+ end
55
+
56
+ private
57
+
58
+ def send_and_sleep(output, sleep_second)
59
+ if output == Level::HIGH
60
+ RPi::GPIO.set_high(@pin)
61
+ else
62
+ RPi::GPIO.set_low(@pin)
63
+ end
64
+ sleep sleep_second
65
+ end
66
+
67
+ def send_initial_signal
68
+ RPi::GPIO.setup(@pin, as: :output)
69
+ send_and_sleep(Level::HIGH, 0.05)
70
+ send_and_sleep(Level::LOW, 0.02)
71
+ end
72
+
73
+ def collect_raw_input
74
+ RPi::GPIO.setup(@pin, as: :input, pull: :up)
75
+ max_unchanged_count = 100
76
+ unchanged_count = 0
77
+ last_input = -1
78
+ raw_inputs = []
79
+
80
+ while unchanged_count < max_unchanged_count
81
+ current_input = RPi::GPIO.high?(@pin)
82
+ raw_inputs.push(current_input)
83
+ if last_input == current_input
84
+ unchanged_count += 1
85
+ else
86
+ unchanged_count = 0
87
+ last_input = current_input
88
+ end
89
+ end
90
+ raw_inputs
91
+ end
92
+
93
+ def parse_inputs_into_pull_up_periods(raw_inputs)
94
+ state = State::INITIAL_PULL_DOWN
95
+ periods = []
96
+ period = 0
97
+
98
+ raw_inputs.each do |input|
99
+ period += 1
100
+ case state
101
+ when State::INITIAL_PULL_DOWN
102
+ if input == Level::LOW
103
+ state = State::INITIAL_PULL_UP
104
+ end
105
+ when State::INITIAL_PULL_UP
106
+ if input == Level::HIGH
107
+ state = State::DATA_FIRST_PULL_DOWN
108
+ end
109
+ when State::DATA_FIRST_PULL_DOWN
110
+ if input == Level::LOW
111
+ state = State::DATA_PULL_UP
112
+ end
113
+ when State::DATA_PULL_UP
114
+ if input == Level::HIGH
115
+ period = 0
116
+ state = State::DATA_PULL_DOWN
117
+ end
118
+ when State::DATA_PULL_DOWN
119
+ if input == Level::LOW
120
+ periods.push(period)
121
+ state = State::DATA_PULL_UP
122
+ end
123
+ end
124
+ end
125
+ return periods
126
+ end
127
+
128
+ def calculate_bits(pull_up_periods)
129
+ shortest_period = pull_up_periods.min()
130
+ longest_period = pull_up_periods.max()
131
+ halfway = shortest_period + (longest_period - shortest_period)/2r
132
+ bits = []
133
+ pull_up_periods.each do |period|
134
+ bit = period > halfway
135
+ bits.push(bit)
136
+ end
137
+ bits
138
+ end
139
+
140
+ def bits_to_bytes(bits)
141
+ bytes = []
142
+ byte = 0
143
+
144
+ bits.each_with_index do |bit, i|
145
+ byte = byte << 1
146
+ byte = byte | (bit ? 1 : 0)
147
+ if (i + 1) % 8 == 0
148
+ bytes.push(byte)
149
+ byte = 0
150
+ end
151
+ end
152
+ bytes
153
+ end
154
+
155
+ def calculate_checksum(bytes)
156
+ bytes.slice(0..3).sum & 255
157
+ end
158
+
159
+ def bytes_to_temperature(bytes)
160
+ bytes[2]
161
+ end
162
+
163
+ def bytes_to_humidity(bytes)
164
+ bytes[0]
165
+ end
166
+ end
167
+ end
data/lib/dht11/app.rb ADDED
@@ -0,0 +1,16 @@
1
+ module DHT11
2
+ class App
3
+ DEFAULT_PIN_BCM = 26
4
+
5
+ def run!
6
+ dht = Sensor.new(DEFAULT_PIN_BCM)
7
+ loop do
8
+ result = dht.read
9
+ puts "Temperature: #{result.temperature}, Humidity: #{result.humidity}"
10
+ sleep 2
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ DHT11::App.new.run!
@@ -0,0 +1,30 @@
1
+ module DHT11
2
+ module Err
3
+ NO_ERROR = :NO_ERROR
4
+ MISSING_DATA = :MISSING_DATA
5
+ CRC = :CRC
6
+ end
7
+
8
+ class Result
9
+ attr_reader :temperature, :humidity, :error_code
10
+
11
+ def initialize(error_code, temperature, humidity)
12
+ @error_code = error_code
13
+ @temperature = temperature
14
+ @humidity = humidity
15
+ end
16
+
17
+ def valid?
18
+ @error_code == Err::NO_ERROR
19
+ end
20
+
21
+ def temperature_f
22
+ return Float::NAN if @temperature.nan?
23
+ (@temperature * 9/5) + 32
24
+ end
25
+
26
+ alias_method :temp_f, :temperature_f
27
+ alias :temp :temperature
28
+ alias :hum :humidity
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module DHT11
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dht11
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kenta Hirayama
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-08-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rpi_gpio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ - hkenta112@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - Gemfile
36
+ - LICENSE.txt
37
+ - README.md
38
+ - Rakefile
39
+ - bin/console
40
+ - bin/dht11
41
+ - bin/setup
42
+ - dht11.gemspec
43
+ - lib/dht11.rb
44
+ - lib/dht11/app.rb
45
+ - lib/dht11/result.rb
46
+ - lib/dht11/version.rb
47
+ homepage: https://github.com/tankenta/dht11
48
+ licenses:
49
+ - MIT
50
+ metadata:
51
+ homepage_uri: https://github.com/tankenta/dht11
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 2.3.0
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubygems_version: 3.0.6
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: Ruby conversion of DHT11 Python library which depends only on rpi_gpio.
71
+ test_files: []