2015/12/23 7M4MON
缶コーヒーをユニバーサル基板にあてがって、大きさはBタイプに決めました。
Bサイズの穴数は縦36、横27個なので、これをVISIOに配置します。
缶コーヒーの直径や抵抗の大きさを測って、周囲に抵抗が16本並ぶように検討しました。
要求は
が必須条件です。さらに
という条件も追加しておきます。
サーミスタは入手性の関係で10kΩ@25℃のNTCです。B係数は3435Kなので、
抵抗値は
R = 10*EXP(3435*(1/(TEMP+273)-1/(25+273)))
で求められます。
データシートにも書いてありますが、100℃で約1kΩ、60℃で約3kΩです。
逆に温度は
TEMP = =1/(LN(R/10)/3435+(1/(25+273)))-273
で求められます。
そこから分圧抵抗を変えて変化率を求めると
3.3kΩ付近の時に最も25℃と100℃の差が大きくなります。(0.519くらい)
この値から出力電圧と温度の関係を求めます。
ちゃんと計算すれば、たぶん計算式を導くことは可能ですが、面倒なので近似式をエクセルに出してもらいます。
サーミスタからの出力電圧が求まりましたので、設定範囲を検討します。
設定に用いるボリュームは10kΩのBカーブに決めました。
①ボリュームの両端に抵抗をぶら下げて、ボリュームの中点から電圧を取った時は2.2k、4.7kがいい感じです。
②片方の抵抗をボリュームの中点からぶら下げた時は1k、4.7kがいい感じです。
比較すると…

②の方が適温付近を細かく設定できて良い感じです。
という訳で抵抗値が求まりました。
実際に動かして温度を測定しました。
| 'METEX M-6000Mというテスターの読み取り文字列から、値を返すクラス。 | |
| 'https://github.com/ruimo/m6000m/blob/master/data.rb | |
| 'の移植。 | |
| Public Class METEX | |
| #Region "table" | |
| 'テーブルを定義。初期化子を使っているので.netFrameWork4.0(VS2010)以降対応。 | |
| '移植元は「0x3b => :voltage,」のようにbyte型から変換していたので、 | |
| '文字列→文字配列→文字コード変換すると素直に引用だと思う。 | |
| 'とりあえず書きなおすのが面倒なので、Asc(string)は使う方向。 | |
| Dim function_table As New Dictionary(Of Integer, String) From { _ | |
| {&H3B, "voltage"}, _ | |
| {&H3D, "microAmpere"}, _ | |
| {&H3F, "milliAmpere"}, _ | |
| {&H30, "autoAmpere"}, _ | |
| {&H39, "manualAmpere"}, _ | |
| {&H33, "resistance"}, _ | |
| {&H35, "continuity"}, _ | |
| {&H31, "diode"}, _ | |
| {&H32, "frequency"}, _ | |
| {&H36, "capacity"}, _ | |
| {&H34, "temperature"}, _ | |
| {&H3E, "adp0"}, _ | |
| {&H3C, "adp1"}, _ | |
| {&H38, "adp2"}, _ | |
| {&H3A, "adp3"} _ | |
| } | |
| Dim range_voltage_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-3"}, _ | |
| {&H31, "E-2"}, _ | |
| {&H32, "E-1"}, _ | |
| {&H33, "E-0"}, _ | |
| {&H34, "E-4"} _ | |
| } | |
| Dim range_micro_ampere_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-7"}, _ | |
| {&H31, "E-6"} _ | |
| } | |
| Dim range_milli_ampere_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-5"}, _ | |
| {&H31, "E-4"} _ | |
| } | |
| Dim range_auto_ampere_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-3"}, _ | |
| {&H31, "E-2"} _ | |
| } | |
| Dim range_manual_ampere_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-2"} _ | |
| } | |
| Dim range_resistance_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-1"}, _ | |
| {&H31, "E-0"}, _ | |
| {&H32, "E+1"}, _ | |
| {&H33, "E+2"}, _ | |
| {&H34, "E+3"}, _ | |
| {&H35, "E+4"} _ | |
| } | |
| Dim range_freq_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E+0"}, _ | |
| {&H31, "E+1"}, _ | |
| {&H32, "E+2"}, _ | |
| {&H33, "E+3"}, _ | |
| {&H34, "E+4"} _ | |
| } | |
| Dim range_capacity_table As New Dictionary(Of Integer, String) From { _ | |
| {&H30, "E-12"}, _ | |
| {&H31, "E-11"}, _ | |
| {&H32, "E-10"}, _ | |
| {&H33, "E-9"}, _ | |
| {&H34, "E-8"}, _ | |
| {&H35, "E-7"}, _ | |
| {&H36, "E-6"} _ | |
| } | |
| #End Region | |
| Function MetexConvert(ByVal strReadData As String) As String | |
| Dim powerNumber As String = "" | |
| Dim measUnit As String = "" | |
| Dim polSign As String = "+" | |
| Dim optionStr As String = "" | |
| Dim rangeDictionaryInt As Integer = Asc(strReadData.Substring(0)) | |
| Dim statusBit As Integer = Asc(strReadData.Substring(6)) | |
| Try | |
| Select Case function_table(Asc(strReadData.Substring(5))) | |
| Case "voltage" | |
| powerNumber = range_voltage_table(rangeDictionaryInt) | |
| measUnit = "V" | |
| Case "microAmpere" | |
| powerNumber = range_micro_ampere_table(rangeDictionaryInt) | |
| measUnit = "A" | |
| Case "milliAmpere" | |
| powerNumber = range_milli_ampere_table(rangeDictionaryInt) | |
| measUnit = "A" | |
| Case "autoAmpere" | |
| powerNumber = range_auto_ampere_table(rangeDictionaryInt) | |
| measUnit = "A" | |
| Case "manualAmpere" | |
| powerNumber = range_manual_ampere_table(rangeDictionaryInt) | |
| measUnit = "A" | |
| Case "resistance" | |
| powerNumber = range_resistance_table(rangeDictionaryInt) | |
| measUnit = "Ω" | |
| Case "continuity" '導通チェック | |
| measUnit = "Ω" | |
| powerNumber = "E-1" | |
| Case "diode" | |
| measUnit = "V" | |
| powerNumber = "E-3" | |
| Case "frequency" | |
| powerNumber = range_freq_table(rangeDictionaryInt) | |
| measUnit = "Hz" | |
| Case "capacity" | |
| powerNumber = range_capacity_table(rangeDictionaryInt) | |
| measUnit = "F" | |
| Case "temperature" | |
| If statusBit And &H8 Then 'Judgle | |
| measUnit = "℃" | |
| Else | |
| measUnit = "F" | |
| End If | |
| Case "adp0" | |
| measUnit = "Lux" '照度センサ | |
| Case "adp1" | |
| measUnit = "dB" '騒音計 | |
| powerNumber = "E-1" | |
| Case Else | |
| measUnit = "unknown" | |
| End Select | |
| If statusBit And &H4 Then 'sign | |
| polSign = "-" | |
| Else | |
| polSign = "+" | |
| End If | |
| If statusBit And &H1 Then 'OL | |
| polSign = "#" | |
| End If | |
| Dim optionBit As Integer = Asc(strReadData.Substring(7)) | |
| If optionBit And &H8 Then 'HOLD | |
| optionStr = optionStr & ",HOLD" | |
| End If | |
| If optionBit And &H4 Then 'MAX | |
| optionStr = optionStr & ",MAX" | |
| End If | |
| If optionBit And &H2 Then 'MIN | |
| optionStr = optionStr & ",MIN" | |
| End If | |
| Dim option2Bit As Integer = Asc(strReadData.Substring(8)) | |
| If option2Bit And &H8 Then 'DC | |
| optionStr = optionStr & ",DC" | |
| End If | |
| If option2Bit And &H4 Then 'AC | |
| optionStr = optionStr & ",AC" | |
| End If | |
| If option2Bit And &H2 Then 'AUTO | |
| optionStr = optionStr & ",AUTO" | |
| Else | |
| optionStr = optionStr & ",MANUAL" | |
| End If | |
| Catch ex As Exception | |
| measUnit = "Exception" | |
| End Try | |
| Return polSign & strReadData.Substring(1, 4) & powerNumber & "," & measUnit & optionStr | |
| End Function | |
| End Class | |

まだまだ温度上昇に余裕があります。
適温になったコーヒーを振っても缶の表面温度はそれほど下がりませんでした。
ヒーターが下にあるので中で対流してるのかな?
気になるFETの損失ですが、触れてみた感じ放熱板なしでも大丈夫っぽいです。
(けど一応、付けられるようにもしておいた)
結構かかっちゃいました…
自販機とスーパーの価格差は50円くらいなので60本温めれば元が取れるかな?
最初考えた回路図は↓