2018年11月25日
ガスガン内蔵ヒーター制御装置を作る その4
ヒーター制御装置の実装をします。


マイコンボードは更に小型のものを使います。
Digisparkというマイコンボードの互換機で
マイコンの仕様についてはこちら。
このマイコンを使うときは、こちらの手順にしたがって開発環境を インストールする必要があります。
ただ、不具合があるようなのでインストールパッケージ定義をこちらのものに変更してください。
プログラムは入出力関係を少し変更する必要があります。


アナログ入力に干渉するため、
マイコンボードについているツェナーダイオードを取り外しています。

前回試した回路に取り付けて問題ないか確認しました。

実装する回路図はこちら。
ヒューズと電源スイッチ、プログラムを書き込むときに回路を切り離すスイッチを追加しました。



これをケースの中に入れて完成です。
最終的なプログラムはこちら。
稼働時間を少しでも延ばすため、
ヒーター稼動時と待機時で電圧下限値を変えてあります。

使うときはベルトに取り付けたラジオポーチに入れて使います。


マイコンボードは更に小型のものを使います。
Digisparkというマイコンボードの互換機で
マイコンの仕様についてはこちら。
このマイコンを使うときは、こちらの手順にしたがって開発環境を インストールする必要があります。
ただ、不具合があるようなのでインストールパッケージ定義をこちらのものに変更してください。
プログラムは入出力関係を少し変更する必要があります。
//ヒーター制御プログラムテスト(Digispark用)
//入出力ピンの名称変更
#define HEATER 0 //ヒーター制御出力
#define Temp_Input A1 //サーミスタ入力
#define Val_Input A2 //電圧測定入力
#define LED 1 //マイコンLED
//定数の宣言
const int V_R1 = 1000; //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000; //電圧測定GND側抵抗値(Ω)
const int B = 4100; //サーミスタB定数
const long T_R1 = 10000; //サーミスタ基準抵抗値[Ω]
const long T_R2 = 10000; //サーミスタバランス抵抗[Ω]
const int T0 = 298; //サーミスタ基準温度[K]
const int Limit_Val = 740; //測定電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400; //正常温度閾値[℃×10]
const int L_Temp = 280; //温度下限値[℃×10]
const int H_Temp = 300; //温度上限値[℃×10]
//変数の宣言
float Vcc = 0; //基準電圧[V]
int Val = 0; //測定電圧[V×100]
int Temp = 0; //測定温度[℃×10]
void setup () {
//入出力ピンの設定
pinMode(HEATER, OUTPUT);
pinMode(LED, OUTPUT);
}
void loop () {
Vcc = cpuVcc(); //基準電圧の取得
Temp = GetTemp(analogRead(Temp_Input)); //温度の取得
Val = GetVal(analogRead(Val_Input)); //電圧を取得
while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){ //測定温度が正常な範囲内から外れると
digitalWrite(HEATER, LOW); //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
while (Val < Limit_Val) { //測定電圧が下限値を下回るとヒーターをオフにし、
digitalWrite(HEATER, LOW); //マイコンLEDが長い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(1000);
}
if (Temp <= L_Temp) { //測定温度が下限値以下になると
digitalWrite(HEATER, HIGH); //ヒーターをオンにする
}
if (Temp >= H_Temp) { //測定温度が上限値以上になると
digitalWrite(HEATER, LOW); //ヒーターをオフにする
}
delay(100); //0.1s待つ
}
//センサーの値から温度を計算
float GetTemp (int raw) {
float V_R2 ;
float R ;
float t;
V_R2 = raw * Vcc / 1.024; //バランス抵抗の消費電圧を算出
R = Vcc * 1000.0 / V_R2 * T_R2 - T_R2; //サーミスタの抵抗値を算出
t = (1000 / (1 / (0.001 * T0) + log(R / T_R1) * 1000 / B) - 273); //温度の計算
return (int)(t * 10.0); //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A) {
float V;
V = A * Vcc / 1024.0 / V_R2 * (V_R1 + V_R2); //電圧の計算
return (int)(V * 100.0); //100倍して整数にする
}
float cpuVcc() { // 電源電圧(AVCC)測定関数
long sum = 0;
adcSetup(0x0C); // Vref=Vcc, input=internal1.1V
for (int n = 0; n < 10; n++) {
sum = sum + adc(); // adcの値を読んで積分
}
return (1.1 * 10240.0) / sum; // 電圧を計算して戻り値にする
}
void adcSetup(byte data) { // ADコンバーターの設定
ADMUX = data; // ADC Multiplexer Select Reg.
ADCSRA |= ( 1 << ADEN); // ADC イネーブル
ADCSRA |= 0x07; // AD変換クロック CK/128
delayMicroseconds (500); // 安定するまで待つ
}
unsigned int adc() { // ADCの値を読む
unsigned int dL, dH;
ADCSRA |= ( 1 << ADSC); // AD変換開始
while (ADCSRA & ( 1 << ADSC) ) { // 変換完了待ち
}
dL = ADCL; // LSB側読み出し
dH = ADCH; // MSB側
return dL | (dH << 8); // 10ビットに合成した値を返す
}


アナログ入力に干渉するため、
マイコンボードについているツェナーダイオードを取り外しています。

前回試した回路に取り付けて問題ないか確認しました。
実装する回路図はこちら。
ヒューズと電源スイッチ、プログラムを書き込むときに回路を切り離すスイッチを追加しました。



これをケースの中に入れて完成です。
最終的なプログラムはこちら。
//ヒーター制御プログラムVer.1.00(Digispark用)
//入出力ピンの名称変更=================================================================
#define HEATER 0 //ヒーター制御出力
#define Temp_Input A1 //サーミスタ入力
#define Val_Input A2 //電圧測定入力
#define LED 1 //マイコンLED
//定数の宣言===========================================================================
const int V_R1 = 1000; //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000; //電圧測定GND側抵抗値(Ω)
const int B = 4100; //サーミスタB定数
const long T_R1 = 10000; //サーミスタ基準抵抗値[Ω]
const long T_R2 = 10000; //サーミスタバランス抵抗[Ω]
const int T0 = 298; //サーミスタ基準温度[K]
const int Limit_Val_S = 740; //待機時電圧下限値[V×100]
const int Limit_Val_M = 730; //稼働時電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400; //正常温度閾値[℃×10]
const int L_Temp = 280; //温度下限値[℃×10]
const int H_Temp = 300; //温度上限値[℃×10]
//変数の宣言===========================================================================
float Vcc = 0; //基準電圧[V]
int Val = 0; //測定電圧[V×100]
int Temp = 0; //測定温度[℃×10]
bool Battry_Low = false; //オートカット用変数
bool Heater_sw = LOW; //ヒータースイッチ
//セットアップ=========================================================================
void setup () {
//入出力ピンの設定=====================================================================
pinMode(HEATER, OUTPUT);
pinMode(LED, OUTPUT);
//起動処理============================================================================
digitalWrite(HEATER, LOW);
digitalWrite(LED, LOW);
}
//メインプログラム=====================================================================
void loop () {
//各センサーの数値を取得===============================================================
Vcc = cpuVcc(); //基準電圧の取得
Temp = GetTemp(analogRead(Temp_Input)); //温度の取得
Val = GetVal(analogRead(Val_Input)); //電圧を取得
//温度異常セーフティ処理===============================================================
while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){ //測定温度が正常な範囲内から外れると
digitalWrite(HEATER, LOW); //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
//オートカット判定=====================================================================
switch(Heater_sw == HIGH){
case true:
if (Val < Limit_Val_M){ //ヒーターがオンの時、稼働時下限値以下の時、
Battry_Low = true; //変数Battry_Lowをtrueにする
}
break;
default:
if (Val < Limit_Val_S){ //ヒーターがオフの時、待機時下限値以下の時、
Battry_Low = true; //変数Battry_Lowをtrueにする
}
}
//オートカット処理=====================================================================
while (Battry_Low == true){ //変数Battry_Lowをtrueの時、ヒーターをオフにし、
digitalWrite(HEATER, LOW); //マイコンLEDが長い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(1000);
}
//ヒーター制御処理=====================================================================
if (Temp <= L_Temp) { //測定温度が下限値以下になると
Heater_sw = HIGH; //ヒーターをオンにする
}
if (Temp >= H_Temp) { //測定温度が上限値以上になると
Heater_sw = LOW; //ヒーターをオフにする
}
digitalWrite(HEATER,Heater_sw);
delay(100); //0.1s待つ
}
//センサーの値から温度を計算===========================================================
float GetTemp (int raw) {
float V_R2 ;
float R ;
float t;
V_R2 = raw * Vcc / 1.024; //バランス抵抗の消費電圧を算出
R = Vcc * 1000.0 / V_R2 * T_R2 - T_R2; //サーミスタの抵抗値を算出
t = (1000 / (1 / (0.001 * T0) + log(R / T_R1) * 1000 / B) - 273); //温度の計算
return (int)(t * 10.0); //10倍にして整数にする
}
//センサーの値から電圧を計算===========================================================
int GetVal(int A) {
float V;
V = A * Vcc / 1024.00 / V_R2 * (V_R1 + V_R2); //電圧の計算
return (int)(V * 100.0); //100倍して整数にする
}
//電源電圧(AVCC)測定関数===============================================================
float cpuVcc() {
long sum = 0;
adcSetup(0x0C); // Vref=Vcc, input=internal1.1V
for (int n = 0; n < 10; n++) {
sum = sum + adc(); // adcの値を読んで積分
}
return (1.1 * 10240.0) / sum; // 電圧を計算して戻り値にする
}
//ADコンバーターの設定===================================================
void adcSetup(byte data) {
ADMUX = data; // ADC Multiplexer Select Reg.
ADCSRA |= ( 1 << ADEN); // ADC イネーブル
ADCSRA |= 0x07; // AD変換クロック CK/128
delayMicroseconds (500); // 安定するまで待つ
}
//ADCの値を読む==========================================================
unsigned int adc() {
unsigned int dL, dH;
ADCSRA |= ( 1 << ADSC); // AD変換開始
while (ADCSRA & ( 1 << ADSC) ) { // 変換完了待ち
}
dL = ADCL; // LSB側読み出し
dH = ADCH; // MSB側
return dL | (dH << 8); // 10ビットに合成した値を返す
}
稼働時間を少しでも延ばすため、
ヒーター稼動時と待機時で電圧下限値を変えてあります。

使うときはベルトに取り付けたラジオポーチに入れて使います。
2018年11月11日
ガスガン内蔵ヒーター制御装置を作る その3
2018年11月10日
ガスガン内蔵ヒーター制御装置を作る その2
ヒーター制御装置の回路とプログラムを作っていきます。
まずテスト用の回路図を作成しました。

NTCサーミスタを使った分圧回路で温度を検知し、FETでヒーターのオン・オフを行います。
バッテリーの電圧は固定抵抗を使った分圧回路を用いて検知します。

これをブレッドボード上で組み立て、テストを行います。
プログラムの方は、まず温度と電圧を読み取り、シリアルモニタに表示するプログラムを作成しました。
以上のプログラムを書き込み、バッテリーを接続後、シリアルモニタを表示すると下のように表示します。
(このプログラムを使う際、マイコンVINの接続を切っておかないと、バッテリー電圧が高く表示されてしまいます。)

うまく表示できたら、今度はヒーターを動かしてみます。

プログラムは以下の通り。
まずテスト用の回路図を作成しました。
NTCサーミスタを使った分圧回路で温度を検知し、FETでヒーターのオン・オフを行います。
バッテリーの電圧は固定抵抗を使った分圧回路を用いて検知します。

これをブレッドボード上で組み立て、テストを行います。
プログラムの方は、まず温度と電圧を読み取り、シリアルモニタに表示するプログラムを作成しました。
//ヒーター制御入力テスト用
//定数の宣言
const int V_R1 = 1000;     //電圧測定VIN側抵抗値[Ω]
const int V_R2 = 1000;     //電圧測定GND側抵抗値[Ω]
const int B = 4100     //サーミスタB定数
const int T_R0 = 10000;     //サーミスタ基準抵抗値[Ω]
const int T_R1 = 10000;     //バランス抵抗[Ω]
const int T0 = 298;     //サーミスタ基準温度[K]
//変数の宣言
float Vcc = 0;     //基準電圧[V]
int Val = 0;     //測定電圧[V×100]
int Temp = 0;     //測定温度[℃×10]
void setup () {
Serial.begin(9600);     // 9600 bpsで接続
Serial.println("READ_START");     // 最初に1度だけ Start を表示
void loop () {
Vcc = cpuVcc();      //基準電圧の取得
Temp = GetTemp(analogRead(A0));     //温度の取得
Val = GetVal(analogRead(A1));      //電圧を取得
Serial.print("Vcc=");     //基準電圧の表示
Serial.print(Vcc);
Serial.print(" TEMP=");     //温度の表示
Serial.print(Temp);
Serial.print(" V=");     //電圧の表示
Serial.println(Val);
delay(50);     // 0.05s 待つ
}
//センサーの値から温度を計算
float GetTemp (int raw){
float V_R0 ;
float R ;
float t;
V_R0 = raw * Vcc / 1.024;     //回路内抵抗の消費電圧を算出
R = Vcc * 1000.0 / V_R0 * T_R1 - T_R1;     //サーミスタの抵抗値を算出
t = (1000 / (1 / (0.001 * T0)+log(R / T_R0)*1000 / B) - 273);     //温度の計算
return(int)(t * 10.0);     //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A){
float V;
V = A * Vcc / 1024.0 /V_R2 * (V_R1 + V_R2);     //電圧の計算
return(int)(V * 100.0);     //100倍して整数にする
}
float cpuVcc(){     // 電源電圧(AVCC)測定関数
long sum=0;
adcSetup(0x4E);     // Vref=AVcc, input=internal1.1V
for(int n=0; n < 10; n++){
sum = sum + adc();     // adcの値を読んで積分
}
return (1.1 * 10240.0)/ sum;     // 電圧を計算して戻り値にする
}
void adcSetup(byte data){     // ADコンバーターの設定
ADMUX = data;     // ADC Multiplexer Select Reg.
ADCSRA |= ( 1 << ADEN);     // ADC イネーブル
ADCSRA |= 0x07;     // AD変換クロック CK/128
delayMicroseconds (500);     // 安定するまで待つ
}
unsigned int adc(){     // ADCの値を読む
unsigned int dL, dH;
ADCSRA |= ( 1 << ADSC);     // AD変換開始
while(ADCSRA & ( 1 << ADSC) ){     // 変換完了待ち
}
dL = ADCL;     // LSB側読み出し
dH = ADCH;      // MSB側
return dL | (dH << 8);     // 10ビットに合成した値を返す
}
以上のプログラムを書き込み、バッテリーを接続後、シリアルモニタを表示すると下のように表示します。
(このプログラムを使う際、マイコンVINの接続を切っておかないと、バッテリー電圧が高く表示されてしまいます。)

うまく表示できたら、今度はヒーターを動かしてみます。

プログラムは以下の通り。
//ヒーター制御プログラムテスト
//入出力ピンの名称変更
#define HEATER 2     //ヒーター制御出力
#define Temp_Input A0     //サーミスタ入力
#define Val_Input A1     //電圧測定入力
#define LED 13     //マイコンLED
//定数の宣言
const int V_R1 = 1000;     //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000;     //電圧測定GND側抵抗値(Ω)
const int B = 4100;     //サーミスタB定数
const int T_R0 = 10000;     //サーミスタ基準抵抗値[Ω]
const int T_R1 = 10000;     //サーミスタバランス抵抗値[Ω]
const int T0 = 298;     //サーミスタ基準温度[K]
const int Limit_Val = 740;     //測定電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400;     //正常温度閾値[℃×10]
const int L_Temp = 280;     //温度下限値[℃×10]
const int H_Temp = 300;     //温度上限値[℃×10]
//変数の宣言
float Vcc = 0;     //マイコン電源電圧[V]
int Val = 0;     //測定電圧[V×100]
int Temp = 0;     //測定温度[℃×10]
void setup () {
//入出力ピンの設定
pinMode(HEATER, OUTPUT);
pinMode(LED, OUTPUT);
delay(1000);     //電源投入時1s待つ
}
void loop () {
Vcc = cpuVcc();     //マイコン電源電圧の取得
Temp = GetTemp(analogRead(Temp_Input));     //温度の取得
Val = GetVal(analogRead(Val_Input));      //電圧を取得
while (Val < Limit_Val) {     //測定電圧が下限値を下回るとヒーターをオフにし、
digitalWrite(HEATER, LOW);     //マイコンLEDが長い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(1000);
}
while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){     //測定温度が正常な範囲内から外れると
digitalWrite(HEATER, LOW);     //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
digitalWrite(13, LOW);
if (Temp <= L_Temp) {     //測定温度が下限値以下になると
digitalWrite(HEATER, HIGH);     //ヒーターをオンにする
}
if (Temp >= H_Temp) {     //測定温度が上限値以上になると
digitalWrite(HEATER, LOW);     //ヒーターをオフにする
}
delay(100);     //0.1s待つ
}
//センサーの値から温度を計算
float GetTemp (int raw) {
float V_R0 ;
float R ;
float t;
V_R0 = raw * Vcc / 1.024;     //バランス抵抗の消費電圧を算出
R = Vcc * 1000.0 / V_R0 * T_R1 - T_R1;     //サーミスタの抵抗値を算出
t = (1000 / (1 / (0.001 * T0) + log(R / T_R0) * 1000 / B) - 273);     //温度の計算
return (int)(t * 10.0);     //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A) {
float V;
V = A * Vcc / 1024.0 / V_R2 * (V_R1 + V_R2);     //電圧の計算
return (int)(V * 100.0);     //100倍して整数にする
}
float cpuVcc() {     // 電源電圧(AVCC)測定関数
long sum = 0;
adcSetup(0x4E);     // Vref=AVcc, input=internal1.1V
for (int n = 0; n < 10; n++) {
sum = sum + adc();     // adcの値を読んで積分
}
return (1.1 * 10240.0) / sum;     // 電圧を計算して戻り値にする
}
void adcSetup(byte data) {     // ADコンバーターの設定
ADMUX = data;     // ADC Multiplexer Select Reg.
ADCSRA |= ( 1 << ADEN);     // ADC イネーブル
ADCSRA |= 0x07;     // AD変換クロック CK/128
delayMicroseconds (500);     // 安定するまで待つ
}
unsigned int adc() {     // ADCの値を読む
unsigned int dL, dH;
ADCSRA |= ( 1 << ADSC);     // AD変換開始
while (ADCSRA & ( 1 << ADSC) ) {     // 変換完了待ち
}
dL = ADCL;     // LSB側読み出し
dH = ADCH;     // MSB側
return dL | (dH << 8);     // 10ビットに合成した値を返す
}
プログラムの動きとしては、
電源接続後、1秒待ってから動作開始。
↓
温度、電圧の取得。
↓
電圧が下限値(7.4V)を下回ると無限ループで停止、LEDを1秒間隔、0.1秒点灯させる。
↓
温度が異常な値(40℃を超え、-20℃を下回る)を示すと無限ループで停止、LEDを0.1秒間隔、0.1秒点灯させる。
↓
温度が下限値(28℃)以下になるとヒーターをオンにする。
↓
温度が上限値(30℃)以上になるとヒーターをオフにする。
↓
以下繰り返し。
テストの結果うまくいったので、次からは実装を行います。
2018年11月10日
ガスガン内蔵ヒーター制御装置を作る その1
以前、このようなものを作りましたが、
問題があり、改良することにしました。
問題点としては、
1.モバイルバッテリーを使用しているので準備に手間と資金がかかる。
2.電圧が5Vでは25℃前後の保温が精一杯。
これらを解決するため、電動ガン用の7.4V LiPoバッテリーを使用したいと思いますが、
これの問題点として、
1.現状のままLiPoバッテリーを繋ぐと非常に高温となり危険。
2.バッテリーが過放電してしまい使用不能になってしまう。
これを解決するためヒーターの制御装置を作ることにしました。

初めはこのような既存の温度センサースイッチとオートカットを使うつもりでしたが、
この回路は動作電圧が12Vで、扱いが難しく頓挫していましたが、
いいものを見つけたのでそれを使います。


Amazonで売っていたマイコンボードです。
Arduino Nanoというマイコンボードの互換機で、
7V~12Vで動作するので7.4V LiPoバッテリーで使うことが出来ます。
これにセンサー類を取り付け、プログラムを書き込めばヒーターの制御装置を作ることが出来ます。

先ほどの温度センサースイッチと比べてとても小型です。
プログラムを書き込むにはArduino IDEという物が必要です。
こちらからダウンロードできます(英語のページ)。
インストール方法などの詳細はこちらから 互換機をそのままPCに接続しても認識しないので、CH340Gというドライバが必要です。
こちらからダウンロードできます(中国語のページ)。

とりあえずLEDを光らせることは出来たので、これから制御回路やプログラムを作っていきます。
問題があり、改良することにしました。
問題点としては、
1.モバイルバッテリーを使用しているので準備に手間と資金がかかる。
2.電圧が5Vでは25℃前後の保温が精一杯。
これらを解決するため、電動ガン用の7.4V LiPoバッテリーを使用したいと思いますが、
これの問題点として、
1.現状のままLiPoバッテリーを繋ぐと非常に高温となり危険。
2.バッテリーが過放電してしまい使用不能になってしまう。
これを解決するためヒーターの制御装置を作ることにしました。

初めはこのような既存の温度センサースイッチとオートカットを使うつもりでしたが、
この回路は動作電圧が12Vで、扱いが難しく頓挫していましたが、
いいものを見つけたのでそれを使います。


Amazonで売っていたマイコンボードです。
Arduino Nanoというマイコンボードの互換機で、
7V~12Vで動作するので7.4V LiPoバッテリーで使うことが出来ます。
これにセンサー類を取り付け、プログラムを書き込めばヒーターの制御装置を作ることが出来ます。

先ほどの温度センサースイッチと比べてとても小型です。
プログラムを書き込むにはArduino IDEという物が必要です。
こちらからダウンロードできます(英語のページ)。
インストール方法などの詳細はこちらから 互換機をそのままPCに接続しても認識しないので、CH340Gというドライバが必要です。
こちらからダウンロードできます(中国語のページ)。

とりあえずLEDを光らせることは出来たので、これから制御回路やプログラムを作っていきます。
2018年11月06日
10月28日、熊本FRONT LINE BATTLE FIELDにて
10月28日に熊本FRONT LINE BATTLE FIELDに行って来ました。
この日はハロウィンイベントがあったのでコスプレした人が多かったです。









この日はハロウィンイベントがあったのでコスプレした人が多かったです。









