【ソフト】
試行錯誤しながら作ったソフトは以下のとおり。
- MAX6675からのデータ読み出しは、Adafruitのライブラリをそのまま利用し、周期を正確にするため、Timer2割り込みを使用した。
- I2Cの 7segment 4桁 LEDは、AdafruitのBackpack ライブラリをそのまま利用した。
- 温度制御VRからのAD値は 0から 1023なので、最大設定温度を 400℃にすべく、以下の計算式を使った。( t_max = vr * 150.0 / 750.0 + 200.0 )
- VRの値が32より小さい時は「OFF」とする。
- 熱電対の温度が設定温度に近づくにつれて、供給する電力を減らすことにより、オーバーシュートを減らす。(温度差90度以上:100%, 温度差60度以上: 87.5%, 温度差30度以上:50%, 温度差20度以上:37.5%, 温度差10度以上: 25%, 温度差5℃以上: 12.5%, 温度差5度以下: 電力供給を止める。 電力制限は、500msec毎にON/OFFすることによって実現する(8パターン)
- 電源供給中は、LEDのコロンマークを点灯させる
- OFF状態に於いて、コテ先温度の状況によって、LEDのドット表示を変化させる。(60℃以上:ドット4個点灯、50℃以上:3個点灯、40℃以上:2個点灯、40℃以下:1個点灯。)これによって、OFF状態においても、コテ先の温度が充分下がったかどうかを確認できるので安心感がある。(輝度も落とす)
最終的なコードは以下の通り
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | // // //  Soldering Iron Tip temperature controller // //  2016/9/17, // #include "Wire.h" #include "Adafruit_LEDBackpack.h" #include "max6675.h" #include "MsTimer2.h" #define TMR2_INT 500 MAX6675 TC1(A3, A2, A1); // = (CLK,CS,DO) , define pins for thermocouple1 Adafruit_7segment matrix = Adafruit_7segment(); #define SSR_PIN 3 #define VR_PIN  A0 bool isTimer2Int = false; int cnt8 = 0; // on-level          0,     1,    2,   3,    4,    5,    6,    7,    8 //                   0% 12.5%   25% 37.5%   50% 62.5%   75%  87.5% 100% int strength[9] = {0x00, 0x80, 0x88, 0x89, 0xaa, 0xab, 0xee, 0xfe, 0xff}; void timer2ISR() {   isTimer2Int = true; // ISR for Timer2   if (++cnt8 > 7) cnt8 = 0;   // for power control by 1/8 resolution } /****************************************     Setup *****************************************/ void setup() {   Serial.begin(115200); // 115200 baud   matrix.begin(0x70);   matrix.setBrightness(8);   matrix.clear();   digitalWrite(SSR_PIN, LOW);   pinMode(SSR_PIN, OUTPUT);   MsTimer2::set(TMR2_INT, timer2ISR);   MsTimer2::start(); } /**************************************************    Main Loop **************************************************/ void loop() {   double temp1;   double t_max, t_min, t_delta;   int vr;   int temp2;   int p_level;   if (isTimer2Int) {     isTimer2Int = false;     temp1 = TC1.readCelsius();     vr = analogRead(VR_PIN);     temp2 = (int)(temp1 * 10.0);     t_max = vr * 150.0 / 750.0 + 200.0; //max 400 degree when ADC = 1000     //   Serial.print(t_max, 1);     //   Serial.print(",");     Serial.println(temp1, 1);     t_delta = t_max - temp1; // if still need to up     if (vr < 32) {       digitalWrite(SSR_PIN, LOW); // power-off regardless to the temperature       display_off(temp1);     } else {       if (t_delta > 0) {         if (t_delta > 90.0) p_level = strength[8];      //100%         else if (t_delta > 60.0) p_level = strength[5]; //87.5%         else if (t_delta > 30.0) p_level = strength[4]; //50%         else if (t_delta > 20.0) p_level = strength[3]; //37.5%         else if (t_delta > 10.0) p_level = strength[2]; //25%         else if (t_delta > 5.0) p_level = strength[1];  //12.5%         else p_level = strength[0]; //0%  stop heating when it reaches to 5 degree below the target         if ((p_level >> cnt8) & 0x01) {           digitalWrite(SSR_PIN, HIGH);           matrix.drawColon(true);         } else {           digitalWrite(SSR_PIN, LOW);           matrix.drawColon(false);         }       } else {         digitalWrite(SSR_PIN, LOW);  // if temp1 is higher than target then off,         matrix.drawColon(false);       }       matrix.writeDigitNum(0, (temp2 / 1000), false);       matrix.writeDigitNum(1, (temp2 / 100) % 10, false);       matrix.writeDigitNum(3, (temp2 / 10) % 10, true);       matrix.writeDigitNum(4, temp2 % 10, false);       matrix.writeDisplay();     }   } } // //  display "OFF" on the LED display // void display_off(double t) {   matrix.setBrightness(2);   matrix.drawColon(false);   matrix.writeDigitRaw(0, 0); //blank   matrix.writeDigitRaw(1, 0); //blank   matrix.writeDigitRaw(3, 0); //blank   if (t > 60) matrix.writeDigitRaw(0, 0x80); //blank with dot.   if (t > 50) matrix.writeDigitRaw(1, 0x80); //blank with dot.   if (t > 40) matrix.writeDigitRaw(3, 0x80); //blank with dot.   matrix.writeDigitRaw(4, 0x80); //blank with dot.   matrix.writeDisplay(); } | 
このコードによる、温度制御結果のグラフはこんな感じ。(OFFから、350℃設定と、300℃設定でそれぞれ、ONした場合の約3分間、温度推移)
電源ONからほぼ30秒で設定温度に達したあと、若干のオーバーシュートはあるが、その後は安定して設定温度近辺で制御されていると言える。 一応、これで当初の目的は達成!!
という事で、このプロジェクトは、一旦ここで終了!!
