ひずみゲージ奮闘記 – 評価編(Round3)

ひずみ計測結果 電子工作
ひずみ計測結果

はじめに

 さて、今回はいよいよひずみゲージの評価編です。これが上手くいけば、長かった奮闘記も取り敢えず一段落、ということで。それでは今回もよろしくお願いいたします。

やること

 こんな感じ↓で釣り竿(カーボンロッド)にひずみゲージを貼り付けて、先端のオモリの重量を200gから3000gまで変化させて出力の値を確認しました。出力結果が線形になっていれば、何とか使えるかなっといったイメージです。

計測したもの

 今回計測する項目がこちらの3つになります。

  • ひずみゲージ出力(アンプ後)
  • オモリの重さ(200g ~ 3000g、200g間隔)
  • 先端のたわみ量

知りたいこと

 そんで、知りたいことがこちらの3つです。

  • 縦弾性係数(ヤング率):E
  • 応力:σ
  • 歪み:ε

 計測したものから知りたいことを求めるためにこちらの関係式たちを使います。

(ヤング率があらかじめ分かっていると良いんですけどねぇ。。カーボンパイプのヤング率は大体100GPaほどらしいですが、積層構成やプリプレグの種類でかなり変わってくると思うので難儀ですねぇ。まあ結果を楽しみにしましょう🍖)

計測結果

 まずこちらがひずみゲージセンサ出力の計測結果です。

 5分毎にオモリを200gづつ追加した際のセンサ出力結果です(横軸:時間[h:m:s]、縦軸:センサ出力)。ぱっと見では線形に変化していそうです(ホッ)。また5分間の平均を取って整理したものが下図になります。

 うん、いい感じですね。オレンジ線は最小二乗法を用いた回帰直線になります。Pythonの機械学習ライブラリであるScikit-learnを使って簡単な単回帰分析をしてみました。

単回帰分析とは

単回帰分析では、目的変数に対して1つの説明変数を用います。例えばある人の身長を体重から予測したい場合、身長を目的変数、体重を説明変数とします。体重が増えれば、身長も増えるという予測ができます。身長と体重の例を単回帰分析を用いて考えてみましょう。身長をyと体重をxとして以下の式を考えます。

y = ax + b

この式のa,bが分かれば、体重xを用いて身長yを予測することができます。このa,b回帰係数といいます。この回帰係数aが大きければ大きいほど、目的変数に及ぼす説明変数の影響が大きくなるとわかりますね。

決定係数 R2

回帰式の予測、説明力を評価するためには決定係数を考えます。決定係数とは、回帰式でどれだけ目的変数の動きを説明できているかを意味し、次のように表すことができます。

R2=Sr/Sy (R2:決定係数、Sr:回帰変動、Sy:全変動​​)

回帰変動とは回帰式が予測、説明できている目的変数の動き、全変動とは目的変数の動きを意味します。決定係数が高ければ高いほど、目的変数の動きを予測、説明できている良いモデルといえます。

https://avilen.co.jp/personal/knowledge-article/simple_linear_reg/

回帰係数、決定係数はそれぞれ以下になります。
モデル関数の回帰変数 w1: 0.669
モデル関数の切片 w2: 56.904
y= 0.669x + 56.904
決定係数 R^2: 0.9972

決定係数はほぼ1なので、今回のモデルは信頼しても良いでしょう。(モデルに依りますが、一般的には決定係数0.8以上が精度の高いモデルとされているそうです。)引用?

 では次に、たわみ量の計測結果も確認してみましょう。

 こちらもしっかり線形で決定係数もイイ感じですね。ありがとうございます。
モデル関数の回帰変数 w1: 0.084
モデル関数の切片 w2: 3.389
y= 0.084x + 3.389
決定係数 R^2: 0.9987

知りたいことの導出

 ではこれらの計測したものを使って、知りたいことを求めていきます。今回はアンプを含めたひずみゲージの妥当性の確認が目的なので、それなりの値が確認できればOKとします。

縦弾性係数(ヤング率):E

 縦弾性係数(ヤング率)は、55.0 [GPa]という結果になりました。まあ妥当な値かなと思います(下記表参照)。

JCM 日本複合材マーケットhttps://fukugouzai.com/master/products/composite/cfrp-pipe/

ひずみ:ε

 へぇー、て感じですね。ついでに1000gの荷重を加えた際の伸び量も出してみました。

応力:σ

 うん、まあこんなもんではないでしょうか。OK!

 上の値は1000gのオモリを加えた際の結果ですが、3000gの場合に応力は656.6[MPa]になります。下記表を参考にすると、破壊強度にかなり近かったかもしれませんね。むしろ破壊までしてしまった方がいいデータが採れたかもですね。

JCM 日本複合材マーケットhttps://fukugouzai.com/master/products/composite/cfrp-pipe/

まとめ

 というわけで、少し長くなってしまいましたが、ひとまずこれでひずみゲージ奮闘記は締めさせていただきたいと思います。まあ、それなりの計測システムは出来たのでしょうか。うん。課題はまだまだありますが。。残る課題としては、確実な温度補償と複数ゲージの同時計測などでしょうか。こちらは追々ゆっくりとやっていきたいと思います。

今回もご視聴いただきありがとうございました。ぜひチャンネル登録よろしくお願いいたします。

おまけメモ(Arduino, Pythonコード)

Arduino

/**
 *
 * HX711 library for Arduino - example file
 * https://github.com/bogde/HX711
 *
 * MIT License
 * (c) 2018 Bogdan Necula
 *
 *ひずみゲージ(L3M2R)用に改変、2024,
**/
#include "HX711.h"


// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 8;
const int LOADCELL_SCK_PIN = 9;


HX711 scale;

void setup() {
  Serial.begin(38400);
  Serial.println("HX711 Demo");

  Serial.println("Initializing the scale");

  // Initialize library with data output pin, clock input pin and gain factor.
  // Channel selection is made by passing the appropriate gain:
  // - With a gain factor of 64 or 128, channel A is selected
  // - With a gain factor of 32, channel B is selected
  // By omitting the gain factor parameter, the library
  // default "128" (Channel A) is used here.
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);

  Serial.println("Before setting up the scale:");
  Serial.print("read:");
  Serial.println(scale.read());			// print a raw reading from the ADC

  Serial.print("read average:");
  Serial.println(scale.read_average(100));  	// print the average of 20 readings from the ADC

  Serial.print("get value:");
  Serial.println(scale.get_value(20));		// print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units:");
  Serial.println(scale.get_units(20), 1);	// print the average of 5 readings from the ADC minus tare weight (not set) divided
						// by the SCALE parameter (not set yet)

  scale.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();				        // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read:");
  Serial.println(scale.read());                 // print a raw reading from the ADC

  Serial.print("read average:");
  Serial.println(scale.read_average(100));       // print the average of 20 readings from the ADC

  Serial.print("get value:");
  Serial.println(scale.get_value(20));		// print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units:");
  Serial.println(scale.get_units(20), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
						// by the SCALE parameter set with set_scale

  Serial.println("Readings(average(100)):");
}

void loop() {
  // Serial.print("one reading:\t");
  // Serial.print(scale.get_units(), 1);
  // Serial.print("\t| average:\t");
  Serial.print(scale.get_units(50), 1);
  Serial.print(",");

  // scale.power_down();			        // put the ADC in sleep mode
  // delay(10);
  // scale.power_up();

  // 温度センサ(LM35DZ)
  int  sensorValue = analogRead(A0);
  float voltage = sensorValue * (3.2 / 1023.0);

  Serial.println(voltage*100,1);
  
}

Python

import serial
import datetime

com = serial.Serial("COM3", 38400)

while True:
    val = str(com.readline().decode("utf-8").rstrip(None))
    date = datetime.datetime.now().strftime("%H:%M:%S")
    with open("240602_Calib_round3_1st.csv", "a") as f:
        print("{},{}".format(date, val), file=f)

コメント