計測実習
Back to index page
ブレッドボードとは,電子回路の実験や詩作をするための板です.(Wikipedia より)元々はもっと広い意味で使用されていましたが,近年では電子部品やジャンパ線を差し込むだけではんだ付けしないで回路を組める穴の開いたボードを指すようになりました.
種類はいろいろとありますが,今回は以下のものを使用します.

ボードの内部の配線は以下のようになっています.
写真両端の赤と青の線が通っている部分は回路素子に電源を供給するためのもので,縦方向に内部で全て繋がっています.通常赤の方に電源電圧をつなぎ,青の方をグラウンド(接地)します.右端と左端の穴は繋がっていません.
端子や素子を指すのは中央部分の穴になりますが,上下に表示されているABCDEの穴は全部内部でつながっています.一方,数字で書いてある1から30ですが,それぞれ独立しています.つまり,写真の横方向にのみ繋がっているということです.右と左のブロックも独立しています.
その結線の特性を活かして,通常以下のように端子や素子を配置します.

温度センサの端子は以下の図のようになっています.

結線は以下の図のようにします. 3 MΩ の抵抗はプルアップ抵抗と呼ばれるもので,開放時などの不定な電位を避けるために微小電流を流し続けるためのものです.

前回行った質量計測のためのロードセルと,室温の測定を同時に行うことを試してみます.また,計測データをリアルタイム表示することと,PCにデータを保存することも同時に行います.
温度の計測も測定ごとのばらつきが大きいので質量と同様平均値を取ります.Arduino IDEのプログラムは以下のものを使用します.
#include "HX711.h"
const int DT_PIN = 2;
const int SCK_PIN = 3;
HX711 scale;
int sensorValue;
double t_sum;
double vt;
double temp;
int i;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//Serial.println("start");
scale.begin(DT_PIN, SCK_PIN);
//Serial.print("read:");
//Serial.println(scale.read());
scale.set_scale();
scale.tare();
//Serial.print("calibrating ... ");
delay(5000);
//Serial.println(scale.get_units(10));
scale.set_scale(375.00);
scale.tare();
//Serial.print("read (calibrated): ");
//Serial.println(scale.get_units(10));
pinMode(A0, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print(scale.get_units(10) * 100 / 103.5, 1);
scale.power_down();
t_sum = 0;
for(i=1; i<=500; i++){
sensorValue = analogRead(A0);
t_sum += sensorValue;
delay(10);
}
scale.power_up();
vt = 5.0 * (t_sum / 500) / 1024.0;
temp = -123 * vt + 215;
Serial.print(",");
Serial.println(temp);
}
|
前回使用したものに温度計測の処理をつけ足したものですが,PCにデータ処理をする関係でキャリブレーション時に画面に表示していた文字列などは表示しないようコメントアウトしています.C言語系の言語なので, // により無効化しています.
解説



Python 側は以下のプログラムを使用します.
import sys
import serial
import datetime
import csv
import time
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.animation import PillowWriter
import queue
import threading
# シリアルポートの設定
ser = serial.Serial('COM3',9600) #ポートの情報を記入
# データキューの設定
data_queue = queue.Queue()
#max_len = 100 # 保持する最大データポイント数
# 現在の日付と時間を含むCSVファイル名の設定
start = time.time()
header = datetime.datetime.now().strftime('%Y%m%d-%H_%M_%S')
file_name = str(header) + '_data.csv'
# CSVファイルのヘッダーを書き込む
with open(file_name, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Time', 'Weight', 'Temperature'])
# データ受信
def read_from_serial():
while True:
value = ser.readline().decode('utf-8').rstrip('\n')
data = value.split(',')
d1 = float(data[0])
d2 = float(data[1])
data_queue.put((d1, d2))
print(f'{time.time() - start:.2f}, {d1}, {d2}')
# データ書き込み
def data_write():
start_time = time.time()
while True:
t = time.time() - start_time
if not data_queue.empty():
d1, d2 = data_queue.get()
with open(file_name, 'a', newline = '') as f:
write_data = csv.writer(f)
write_data.writerow([t, d1, d2])
yield t, d1, d2
time.sleep(5)
# グラフ設定
def graph():
ax1.set_xlim(0, 10)
ax1.set_ylim(0, 10)
ax2.set_ylim(0, 50)
del xdata[:]
del y1data[:]
del y2data[:]
line1.set_data(xdata, y1data)
line2.set_data(xdata, y2data)
return line1, line2
# 描画更新
def update(data):
t, d1, d2 = data
xdata.append(t)
y1data.append(d1)
y2data.append(d2)
# 長時間のデータ収集でもメモリ使用量を制御
#if len(xdata) > max_len:
# xdata.pop(0)
# y1data.pop(0)
# y2data.pop(0)
xmin, xmax = ax1.get_xlim()
if t >= xmax:
ax1.set_xlim(0, (t //10) * 10 + 10)
ax1.figure.canvas.draw()
line1.set_data(xdata, y1data)
line2.set_data(xdata, y2data)
return line1, line2
# シリアルポートからデータを読み取るスレッド
thread = threading.Thread(target=read_from_serial)
thread.daemon = True
thread.start()
# グラフ座標軸設定
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_xlabel('t [sec]')
ax1.set_ylabel('Weight [g]')
ax2 = ax1.twinx()
ax2.set_ylabel('Temperature [degree]')
l1 = 'Weight'
l2 = 'Temperature'
line1, = ax1.plot([], [], lw=2, color='r', label=l1)
line2, = ax2.plot([], [], lw=2, color='b', label=l2)
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1+h2, l1+l2)
ax1.grid()
xdata, y1data, y2data = [], [], []
# アニメーションをGIFとして保存
# gif_file = f'animation_{current_time}.gif'
ani = animation.FuncAnimation(fig, update, data_write, blit=True, interval=100,
repeat=False, init_func=graph, cache_frame_data=False)
# グラフを表示する
plt.tight_layout()
plt.show()
|
解説




測定がきちんとできているか,Arduino IDE用のプログラムを書きこんで,実際に動かしてみます.シリアルプロッタで測定値がちゃんと表示されるか,確認しましょう.
上の確認が終わったら,Arduino IDEを閉じます.そして,Python のプログラムを動かしてみましょう.
測定データは CSV 形式のデータとして保存されますので,中身を確認してみましょう.