2018年11月10日

ガスガン内蔵ヒーター制御装置を作る その2

ヒーター制御装置の回路とプログラムを作っていきます。

まずテスト用の回路図を作成しました。

ガスガン内蔵ヒーター制御装置を作る その2

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

ガスガン内蔵ヒーター制御装置を作る その2

これをブレッドボード上で組み立て、テストを行います。

プログラムの方は、まず温度と電圧を読み取り、シリアルモニタに表示するプログラムを作成しました。

//ヒーター制御入力テスト用
//定数の宣言
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の接続を切っておかないと、バッテリー電圧が高く表示されてしまいます。)
ガスガン内蔵ヒーター制御装置を作る その2

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

ガスガン内蔵ヒーター制御装置を作る その2

プログラムは以下の通り。

//ヒーター制御プログラムテスト
//入出力ピンの名称変更
#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℃)以上になるとヒーターをオフにする。

以下繰り返し。

テストの結果うまくいったので、次からは実装を行います。



同じカテゴリー(エアガン)の記事画像
クエーサ ジェルブラスターのエアガン化(改造編その1)
クエーサ ジェルブラスターのエアガン化(検証編)
M14カービンカスタム
側面吸気ピストンヘッドの自作
ARES SOC SLR 分解
ARES SOC SLR(中古品)
同じカテゴリー(エアガン)の記事
 クエーサ ジェルブラスターのエアガン化(改造編その1) (2023-02-01 23:33)
 クエーサ ジェルブラスターのエアガン化(検証編) (2022-12-30 22:33)
 M14カービンカスタム (2022-06-26 20:51)
 側面吸気ピストンヘッドの自作 (2022-06-22 00:10)
 ARES SOC SLR 分解 (2019-06-14 23:54)
 ARES SOC SLR(中古品) (2019-06-11 22:26)
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。