はじめに
実オブジェクトの状態に関する実情報をリアルタイムで取得できるため、システムの分析と合成の次の段階である制御オブジェクトの動的特性の数学的モデリングに合理的に進むことができます。
この出版物は、測定情報をさらに処理するためにコンピューティング環境に信号をリモート送信することで、技術的パラメーターである温度を測定するシステムの実装で利用可能なプロジェクトについて説明しています。
このプロジェクトは、Arduinoソフトウェア開発環境を構成する多くの互換モジュールと無料のPythonツールを備えたArduinoプラットフォームに基づいたプロトタイピングハードウェアに基づいています。
温度測定回路
温度測定回路は、マイクロプロセッサコントローラを使用した1ワイヤインターフェースで制御されるDS18B20(Maxim Integrated)のプライマリデジタル測定トランスデューサで構成されています-Arduino Pro MiniプラットフォームのAtmega328(5V 16MHz(Microchip))。
DS18B20からの測定情報の出力信号は、1線式インターフェースを介してマイクロコントローラーのデジタル入力に供給され、処理され、-55から+ 125°Cの範囲の測定温度値のASCII文字列に変換され、標準シリアルインターフェースを介してTTL-USBコンバーターを介して、さらなるソフトウェア処理のためにコンピューターに入ります:
![](https://habrastorage.org/webt/wo/th/wo/wothwouu7e0ylpqvu1pmq84x7to.png)
測定サブシステム
測定サブシステムは、Arduino Nano V3プラットフォームに基づいています。
![](https://habrastorage.org/webt/7p/0v/pk/7p0vpklodiq3krcsllshmyk387i.png)
このソフトウェアは、Arduino Software統合開発環境のライブラリマネージャーを介して接続できるOneWireライブラリを使用して、Webサイト[1]に提示されている例に基づいています。
#include <OneWire.h> // OneWire DS18B20 Temperature Example // http://www.pjrc.com/teensy/td_libs_OneWire.html // The DallasTemperature library can do all this work for you! // http://milesburton.com/Dallas_Temperature_Control_Library // Data DS18B20 7- // Arduino OneWire ds(7); void setup(void) { Serial.begin(9600); } void loop(void) { byte i; byte present = 0; byte type_s = 0; byte data[12]; byte addr[8]; float celsius; ds.search(addr); ds.reset(); ds.select(addr); ds.write(0x44, 1); delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; celsius = (float)raw / 16.0; Serial.println(celsius); }
コントローラーファームウェアアップグレードプログラムのデバッグとテストの後、測定サブシステムのコンポーネントと要素のインストール、およびケースのアセンブリに進みます。
![](https://habrastorage.org/webt/so/8w/p1/so8wp1rxmfxlrq6_hpai5rsphk0.png)
ケースを最小化する条件では、Arduino Pro Miniプラットフォームを使用します。 測定情報を処理および表示するためのサブシステムのハードウェアは、コンピューターのUSBポートを介して実行されます。
「加速曲線」とそのグラフィカルな実装を処理するためのPythonインターフェイス
測定情報を処理してオペレーターに提示するためのサブシステムによって解決される主なタスク:
- USBポートを介した仮想COMポートの管理とポーリング。 ここではpySerialライブラリ関数が使用されます。
- オペレーターとのインタラクティブな相互作用; ここで、必要な測定数とシリアルポート番号を入力します(MS Windows OSのデバイスマネージャーで確認します)。 ポート番号が正しく入力され、他のプログラムによって占有されていない場合、技術パラメータの現在の測定値がコンソールとグラフィックウィンドウに表示されます。 測定の終了時に、コンソールには測定時間の長さ、センサーのポーリング期間、および測定結果を含むテーブルのあるtxtファイルの場所が表示され、測定値、日付、時間、実験番号、およびセンサーのポーリング期間のグラフがグラフィカルウィンドウに表示されます。
- 測定結果の自動記録。 ここでは、スクリプトを含むフォルダー内のディスク上に、実験カウンターとして使用される符号なし整数を含むファイルcount.txtが必要です。 以降の各実験では、カウンターが1ずつ増加し、実験結果の表とともにファイル名にカウンター値が追加されます。
プログラムリスト:
import numpy as np import matplotlib.pyplot as plt import serial from drawnow import drawnow import datetime, time # def cur_graf(): plt.title("DS18B20") plt.ylim( 20, 40 ) plt.plot(nw, lw1, "r.-") plt.ylabel(r'$, \degree $') plt.xlabel(r'$ \ $') plt.grid(True) # def all_graf(): plt.close() plt.figure() plt.title("DS18B20\n" + str(count_v) + "- " + "(" + now.strftime("%d-%m-%Y %H:%M") + ")") plt.plot( n, l1, "r-") plt.ylabel(r'$, \degree $') plt.xlabel(r'$ \ $' + '; ( : {:.6f}, c)'.format(Ts)) plt.grid(True) plt.show() # # str_m = input(" : ") m = eval(str_m) # mw = 16 # ser = serial.Serial() ser.baudrate = 9600 port_num = input(" : ") ser.port = 'COM' + port_num ser # try: ser.open() ser.is_open print(" : " + ser.portstr) except serial.SerialException: print(" : " + ser.portstr) raise SystemExit(1) # l1 = [] # t1 = [] lw1 = [] # n = [] # nw = [] # # filename = 'count.txt' in_file = open(filename,"r") count = in_file.read() count_v = eval(count) + 1 in_file.close() in_file = open(filename,"w") count = str(count_v) in_file.write(count) in_file.close() filename = count + '_' + filename out_file = open(filename,"w") # print("\n :\n") print("n - ;") print("T - , . ;") print("\n \n") print('{0}{1}\n'.format('n'.rjust(4),'T'.rjust(10))) # # # # i = 0 while i < m: n.append(i) nw.append(n[i]) if i >= mw: nw.pop(0) line1 = ser.readline().decode('utf-8')[:-2] t1.append(time.time()) if line1: l1.append(eval(line1)) lw1.append(l1[i]) if i >= mw: lw1.pop(0) print('{0:4d} {1:10.2f}'.format(n[i],l1[i])) drawnow(cur_graf) i += 1 # ser.close() ser.is_open #time_tm -= time_t0 time_tm = t1[m - 1] - t1[0] print("\n : {0:.3f}, c".format(time_tm)) Ts = time_tm / (m - 1) print("\n : {0:.6f}, c".format(Ts)) # print("\n {}\n".format(filename)) for i in np.arange(0,len(n),1): count = str(n[i]) + "\t" + str(l1[i]) + "\n" out_file.write(count) # out_file.close() out_file.closed # now = datetime.datetime.now() # all_graf() end = input("\n Ctrl-C, ")
取得するもの:
測定数を入力:256
シリアルポート番号を入力:3
接続先:COM3
パラメータ:
nは測定番号です。
T-温度、度 C;
温度の測定値
n T
0 24.75
1 24.75
2 24.75
3 24.75
4 24.75
5 24.75
6 24.75
……………。
![](https://habrastorage.org/webt/ad/fk/ty/adfktyhdo6x0dorpunthvskqago.png)
伝達関数を取得し、モデルの妥当性を評価するためのPythonインターフェイス
この問題を解決するには、モデルに微分が含まれておらず、関係に従って提案された解法が時間座標の変化を意味しないため、数値法を使用できます。 さらに、次のリストに従って3次スプライン補間を適用します。
温度制御チャネル上のオブジェクトの伝達関数の決定
# -*- coding: utf8 -*- import matplotlib.pyplot as plt import time start = time.time() from scipy.interpolate import splev, splrep import scipy.integrate as spint import numpy as np from scipy.integrate import quad xx =np.array(np.arange(0,230,1)) yy1 =np.array([ 24.87, 25.06, 25.31, 25.5, 25.81, 26.06, 26.37, 26.62, 26.87, 27.12, 27.44, 27.69, 27.87, 28.12, 28.31, 28.56, 28.75, 28.94, 29.12, 29.31, 29.5, 29.69, 29.81, 30.0, 30.12, 30.25, 30.37, 30.56, 30.69, 30.81, 30.87, 31.0, 31.12, 31.25, 31.31, 31.44, 31.5, 31.62, 31.69, 31.81, 31.87, 31.94, 32.06, 32.13, 32.19, 32.25, 32.31, 32.38, 32.44, 32.5, 32.56, 32.63, 32.69, 32.75, 32.75, 32.81, 32.88, 32.94, 32.94, 33.0, 33.06, 33.13, 33.13, 33.19, 33.25, 33.25, 33.31, 33.31, 33.38, 33.38, 33.44, 33.44, 33.5, 33.5, 33.56, 33.56, 33.56, 33.63, 33.63, 33.69, 33.69, 33.69, 33.75, 33.75, 33.81, 33.81, 33.81, 33.88, 33.88, 33.88, 33.88, 33.94, 33.94, 33.94, 34.0, 34.0, 34.0, 34.0, 34.06, 34.06, 34.06, 34.06, 34.06, 34.13, 34.13, 34.13, 34.13, 34.13, 34.19, 34.19, 34.19, 34.19, 34.19, 34.25, 34.25, 34.25, 34.25, 34.25, 34.25, 34.31, 34.31, 34.31, 34.31, 34.31, 34.31, 34.31, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.63, 34.56, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.69, 34.63, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.75, 34.69, 34.75, 34.69, 34.69, 34.75, 34.75, 34.75, 34.75, 34.75]) yy2=yy1-24.87# yy=yy2/max(yy2)# """ """ def h(x): spl = splrep(xx , yy ) return splev(x, spl) """ (6)""" S1=(spint.quad(lambda x:1-h(x),xx[0],xx[len(xx)-1])[0]) S2=(spint.quad(lambda x:(1-h(x))*(S1-x),xx[0],xx[len(xx)-1])[0]) S3=(spint.quad(lambda x:(1-h(x))*(S2-S1*x+(1/2)*x**2),xx[0],xx[len(xx)-1])[0]) S4=(spint.quad(lambda x:(1-h(x))*(S3-S2*x+S1*(1/2)*x**2-(1/6)*x**3),xx[0],xx[len(xx)-1])[0]) """ """ b1=-S4/S3 a1=b1+S1 a2=b1*S1+S2 a3=b1*S2+S3 """ """ def ff(x,t): j=(-1)**0.5 return (2/np.pi)*( ((b1*x*j+1)*np.e**(-25*x)/(a3*(x*j)**3+a2*(x*j)**2+a1*x*j+1)).real)*(np.sin(x*t)/x) y=np.array([round(quad(lambda x: ff(x,t),0, 0.6)[0],2) for t in xx]) """ """ k=round(1-sum([(yy[i]-y[i])**2 for i in np.arange(0,len(yy)-1,1)])/sum([(yy[i])**2 for i in np.arange(0,len(yy)-1,1)]),5) stop = time.time() print (" :",round(stop-start,3)) plt.title(' .\n : %s'%k) plt.plot(xx, yy,label='W=(%s*p+1)/(%s*p**3+%s*p**2+%s*p+1)'%(round(b1,1),round(a3,1),round(a2,1),round(a1,1))) plt.legend(loc='best') plt.grid(True) plt.show()
取得するもの:
プログラム実行時間:1.144
![](https://habrastorage.org/webt/7b/s8/de/7bs8deqvchdopfs8t15eds9ayzi.png)
オブジェクトの伝達関数(ヒーター付きの容量)は、「加速曲線」(0.97)に十分に対応して得られました。
結論
温度センサーとPythonインターフェイスを備えたArduinoコントローラーは、温度制御チャネルを介して制御オブジェクトを動的に識別するために開発およびテストされました。
リンク:
1. OneWireライブラリ