max31865 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +6 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +65 -0
- data/Rakefile +6 -0
- data/bin/console +21 -0
- data/bin/setup +8 -0
- data/lib/max31865.rb +160 -0
- data/lib/max31865/version.rb +3 -0
- data/max31865.gemspec +28 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6650202e6b271c41a4f1356c3df2102442c93cd8f355d44c748dc73a460310dc
|
4
|
+
data.tar.gz: c23a50da188f3b31979d991f0ff7767c61a0e437c2cbf454ea80fc695b3c6b61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 646d1d5d29079cbb6935f2dedae557a7d4963e7e62455a9fdd8c18818a0ae16c7f900e29e0516bdf09d929b73a6c7599201d84d4d3393b483ac0575b3950c5dd
|
7
|
+
data.tar.gz: d6bc5d85c7c99e2abed7059993b78fb75abc75db7e2a171cee575ce9952a471590489c806e26771e75bbc834f4093513983624f2469d32789dc4bfe18eea031c
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Marcos Piccinini
|
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,65 @@
|
|
1
|
+
# MAX31865
|
2
|
+
|
3
|
+
MAX31865 - Precision RTD (PT-100) Digital Converter with Linearization
|
4
|
+
|
5
|
+
Ruby SPI interface using PiPiper
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'max31865'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install max31865
|
23
|
+
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
m = MAX31865.new(chip = 0, type = :k, clock = 2_000_000)
|
28
|
+
|
29
|
+
m.config # Must be run once (shutdown resets chip)
|
30
|
+
|
31
|
+
m.read # [Cold Junction Temp, Thermocouple Temp] Floats in celsius
|
32
|
+
|
33
|
+
|
34
|
+
## Raspberry v3
|
35
|
+
|
36
|
+
To enable SPI on the Rpi, on `/boot/config.txt`:
|
37
|
+
|
38
|
+
dtparam=spi=on
|
39
|
+
|
40
|
+
|
41
|
+
## Development
|
42
|
+
|
43
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
44
|
+
Then, run `rake spec` to run the tests. You can also run `bin/console`
|
45
|
+
for an interactive prompt that will allow you to experiment.
|
46
|
+
|
47
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
48
|
+
To release a new version, update the version number in `version.rb`,
|
49
|
+
and then run `bundle exec rake release`, which will create a git tag
|
50
|
+
for the version, push git commits and tags, and push the `.gem`
|
51
|
+
file to [rubygems.org](https://rubygems.org).
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nofxx/max31865.
|
56
|
+
This project is intended to be a safe, welcoming space for collaboration,
|
57
|
+
and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
58
|
+
|
59
|
+
## License
|
60
|
+
|
61
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
62
|
+
|
63
|
+
## Code of Conduct
|
64
|
+
|
65
|
+
Everyone interacting in the MAX31865 project’s codebases and issue trackers is expected to follow the [code of conduct](https://github.com/nofxx/max31865/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'max31865'
|
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__)
|
15
|
+
|
16
|
+
m = MAX31865.new
|
17
|
+
m.read_fault
|
18
|
+
m.config
|
19
|
+
loop do
|
20
|
+
m.read_all
|
21
|
+
end
|
data/bin/setup
ADDED
data/lib/max31865.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'max31865/version'
|
2
|
+
require 'pi_piper'
|
3
|
+
|
4
|
+
#
|
5
|
+
# MAX31865
|
6
|
+
#
|
7
|
+
# Thanks to https://github.com/steve71/MAX31865/blob/master/max31865.py
|
8
|
+
class MAX31865
|
9
|
+
attr_accessor :chip, :clock, :wires, :hz
|
10
|
+
|
11
|
+
# Read registers
|
12
|
+
READ_REG = [0, 8].freeze
|
13
|
+
R_REF = 430.0 # Reference Resistor
|
14
|
+
R0 = 100.0 # Resistance at 0 degC for 400ohm R_Ref
|
15
|
+
A = 0.00390830
|
16
|
+
B = -0.000000577500
|
17
|
+
# C = -4.18301e-12 # for -200 <= T <= 0 (degC)
|
18
|
+
C = -0.00000000000418301
|
19
|
+
# C = 0 # for 0 <= T <= 850 (degC)
|
20
|
+
|
21
|
+
CHIPS = {
|
22
|
+
0 => PiPiper::Spi::CHIP_SELECT_0,
|
23
|
+
1 => PiPiper::Spi::CHIP_SELECT_1,
|
24
|
+
2 => PiPiper::Spi::CHIP_SELECT_BOTH,
|
25
|
+
3 => PiPiper::Spi::CHIP_SELECT_NONE
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
FAULTS = {
|
29
|
+
0x80 => 'High threshold limit (Cable fault/open)',
|
30
|
+
0x40 => 'Low threshold limit (Cable fault/short)',
|
31
|
+
0x04 => 'Overvoltage or Undervoltage Error',
|
32
|
+
0x01 => 'RTD Open-Circuit Fault'
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
def initialize(chip = 0, clock = 2_000_000)
|
36
|
+
@chip = CHIPS[chip]
|
37
|
+
@clock = clock
|
38
|
+
end
|
39
|
+
|
40
|
+
def spi_work
|
41
|
+
PiPiper::Spi.begin do |spi|
|
42
|
+
# Set cpol, cpha
|
43
|
+
PiPiper::Spi.set_mode(1, 1)
|
44
|
+
|
45
|
+
# Setup the chip select behavior
|
46
|
+
spi.chip_select_active_low(true)
|
47
|
+
|
48
|
+
# Set the bit order to MSB
|
49
|
+
spi.bit_order PiPiper::Spi::MSBFIRST
|
50
|
+
|
51
|
+
# Set the clock divider to get a clock speed of 2MHz
|
52
|
+
spi.clock clock
|
53
|
+
|
54
|
+
spi.chip_select(chip) do
|
55
|
+
yield spi
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Run once config
|
62
|
+
#
|
63
|
+
#
|
64
|
+
# Optionally set samples
|
65
|
+
#
|
66
|
+
# 0x8x to specify 'write register value'
|
67
|
+
# 0xx0 to specify 'configuration register'
|
68
|
+
#
|
69
|
+
#
|
70
|
+
# Config Register
|
71
|
+
# ---------------
|
72
|
+
# bit 7 : Vbias -> 1 (ON)
|
73
|
+
# bit 6 : Conversion Mode -> 0 (MANUAL)
|
74
|
+
# bit 5 : 1-shot ->1 (ON)
|
75
|
+
# bit 4 : 3-wire select -> 1 (3 wire config)
|
76
|
+
# bit 3-2: fault detection cycle -> 0 (none)
|
77
|
+
# bit 1 : fault status clear -> 1 (clear any fault)
|
78
|
+
# bit 0 : 50/60 Hz filter select -> 0 (60Hz)
|
79
|
+
#
|
80
|
+
# 0b11010010 or 0xD2 for continuous auto conversion
|
81
|
+
# at 60Hz (faster conversion)
|
82
|
+
# 0b10110010 = 0xB2
|
83
|
+
def config(byte = 0xB2)
|
84
|
+
spi_work do |spi|
|
85
|
+
spi.write(0x80, byte)
|
86
|
+
end
|
87
|
+
sleep 0.2 # give it 200ms for conversion
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Read temperature!
|
92
|
+
#
|
93
|
+
def read
|
94
|
+
spi_work do |spi|
|
95
|
+
read_temp(spi.write(Array.new(8, 0x01)))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
#
|
102
|
+
# Callendar-Van Dusen equation
|
103
|
+
# Res_RTD = Res0 * (1 + a*T + b*T**2 + c*(T-100)*T**3)
|
104
|
+
# Res_RTD = Res0 + a*Res0*T + b*Res0*T**2 # c = 0
|
105
|
+
# (c*Res0)T**4 - (c*Res0)*100*T**3
|
106
|
+
# + (b*Res0)*T**2 + (a*Res0)*T + (Res0 - Res_RTD) = 0
|
107
|
+
#
|
108
|
+
# quadratic formula:
|
109
|
+
# for 0 <= T <= 850 (degC)
|
110
|
+
#
|
111
|
+
def callendar_van_dusen(rtd)
|
112
|
+
temp = -(A * R0) +
|
113
|
+
Math.sqrt(A * A * R0 * R0 - 4 * (B * R0) * (R0 - rtd))
|
114
|
+
temp /= (2 * (B * R0))
|
115
|
+
# temp_line = (rtd_adc_code / 32.0) - 256.0
|
116
|
+
# puts "Straight Line Approx. Temp: #{temp_line}C"
|
117
|
+
# removing numpy.roots will greatly speed things up
|
118
|
+
# temp_C_numpy = numpy.roots([c*R0, -c*R0*100, b*R0, a*R0, (R0 - rtd)])
|
119
|
+
# temp_C_numpy = abs(temp_C_numpy[-1])
|
120
|
+
# print "Solving Full Callendar-Van Dusen using numpy: %f" % temp_C_numpy
|
121
|
+
# use straight line approximation if less than 0
|
122
|
+
# Can also use python lib numpy to solve cubic
|
123
|
+
temp < 0 ? (rtd_adc_code / 32) - 256 : temp
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Read temperature
|
128
|
+
#
|
129
|
+
def read_temp(raw)
|
130
|
+
read_fault(raw[7])
|
131
|
+
rtd_msb, rtd_lsb = raw[1], raw[2]
|
132
|
+
rtd_adc_code = ((rtd_msb << 8) | rtd_lsb) >> 1
|
133
|
+
|
134
|
+
puts "RTD ADC Code: #{rtd_adc_code}"
|
135
|
+
rtd = (rtd_adc_code * R_REF) / 32_768.0 # PT100 Resistance
|
136
|
+
temp = callendar_van_dusen(rtd)
|
137
|
+
puts "PT100 Resistance: #{rtd} ohms"
|
138
|
+
puts "Callendar-Van Dusen Temp (degC > 0): #{temp}C"
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Read register faults
|
143
|
+
#
|
144
|
+
# 10 Mohm resistor is on breakout board to help detect cable faults
|
145
|
+
#
|
146
|
+
# bit 7: RTD High Threshold / cable fault open
|
147
|
+
# bit 6: RTD Low Threshold / cable fault short
|
148
|
+
# bit 5: REFIN- > 0.85 x VBias -> must be requested
|
149
|
+
# bit 4: REFIN- < 0.85 x VBias (FORCE- open) -> must be requested
|
150
|
+
# bit 3: RTDIN- < 0.85 x VBias (FORCE- open) -> must be requested
|
151
|
+
# bit 2: Overvoltage / undervoltage fault
|
152
|
+
# bits 1,0 don't care
|
153
|
+
# print "Status byte: #{status}"
|
154
|
+
#
|
155
|
+
def read_fault(byte)
|
156
|
+
FAULTS.each do |code, fault|
|
157
|
+
raise fault if byte & code == 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/max31865.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'max31865/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'max31865'
|
7
|
+
spec.version = MAX31865::VERSION
|
8
|
+
spec.authors = ['Marcos Piccinini']
|
9
|
+
spec.email = ['x@nofxx.com']
|
10
|
+
|
11
|
+
spec.summary = %q{Read temperatures from MAX31865 Thermocouple.}
|
12
|
+
spec.description = %q{PiPiper based wrapper for MAX31865 SPI Interface.}
|
13
|
+
spec.homepage = 'https://github.com/nofxx/max31865'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = 'exe'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_dependency 'pi_piper', '~> 2.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: max31865
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcos Piccinini
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pi_piper
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3'
|
69
|
+
description: PiPiper based wrapper for MAX31865 SPI Interface.
|
70
|
+
email:
|
71
|
+
- x@nofxx.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
|
+
- CODE_OF_CONDUCT.md
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- bin/console
|
85
|
+
- bin/setup
|
86
|
+
- lib/max31865.rb
|
87
|
+
- lib/max31865/version.rb
|
88
|
+
- max31865.gemspec
|
89
|
+
homepage: https://github.com/nofxx/max31865
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.7.6
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Read temperatures from MAX31865 Thermocouple.
|
113
|
+
test_files: []
|