自作タブレットPC計画アップデートの詳細
GC3をアップデート。前回発注した基板はカーネルどころかブートローダにすら辿り着けなかったので次のプロトタイプを作ることにしました。開発はKiCadで行っています。
以下、詳細。
変更点
ピンヘッダだったuSDをソケットに変更。ソケットはアキバでもネットショップでも買えるものを採用しました。地味に使い回し効きそう。
基板外形を変更
電源層、グラウンド層の形状も変更
裏面にあった部品を可能な限り表に移動
LDOのTPS62250(600mA)をTPS62290(1A)に変更。600mAでは足りないかもということで同じシリーズの上位版を採用することにしました。
パワーインダクタの一部を村田製作所製LQHシリーズに変更
1.5v電源に電解コンデンサを追加 現実的に選択肢はPanasonicのFZシリーズくらいしかなさそうですが… その他の電解コンデンサもFZに切り替えます 気がつけば受動部品はほぼ全てパナか村田製に...だってめんどいんだもーん
メタルマスクも作ってもらうことにしました 前回サンプルで作って貰ったときにすごく便利だったので今回は部品ごとに開口率をカスタムしたデータを入稿して作ってもらうことにしました
部品のフットプリントはほぼ全て自作かカスタムしています。 ライブラリにあるものをそのまま使っているのはピンヘッダと0603Cと0603Rくらいです。
今回は見送ったもの
クリスタルはHS-49パッケージのままです 部品の中でこれだけ異様に大きいので変えようかとも思ったのですが今回は見送りました なんだかんだでHS-49の品種の多さ、扱いやすさはどうしても捨てられない クリスタルの下のグラウンドはコモングラウンドと分割するのが定石ですがそれも今回は見送っています
基板上部の巨大なヘッダはGPIOに見えますが実はHDMI信号用のヘッダです GPIOの引き出しはまだ行っていません
Flashも今は省略したままです 基板の左下の方、結構スペースに余裕がある感じですがそれはFlashを載せる可能性を考えてのことです
電源ICの周りのDCカット用のコンデンサは耐熱の関係上0805にしようかと思っていましたが思ったより熱に強そうだったので0603のままです
Arduinoでリフロー炉を作る(5) - ひとまず完成 -
Arduinoでリフロー炉を作る(4) - PIDライブラリ とチューニング-
PIDライブラリ
リフロー炉は普通PID制御を行います。
Arduino用PIDライブラリが公開されていたので今回はこれを利用させてもらうことにしました。
Arduino Playground - PIDLibrary
このライブラリに添付されているExamples/RelayOutput.inoを改造したものを試してみました。 しかしRelayOutput.inoにはtypoがある様子。
たぶん54行目の
if(Output < millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
は
if(Output > millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
の間違いじゃないかな?
さて、パラメータとかをサンプルのまま試してみた結果こうなりました。 目標値は100℃なのですが180℃までオーバーシュートした上に発振してますね。
パラメータのチューニング
PID制御には3つのパラメータが存在します。wikiの受け売りなのですが簡単に説明するとこんな感じです。
Ki : 操作量に対する比例ゲイン
Pi : 偏差(目標値と現在の出力値との差分)の時間積分に比例して入力量を変化させるゲイン。つまり偏差が存在する状態が長時間いた場合入力量の変化がおおきくなります。
Di : 出力値の急激な変化に応じて入力量を変化させるゲイン。
さて、なんとかして最適なKi Pi Diを導き出さなくてはなりません。 今回はジーグラ・ニコルスのステップ応答法でパラメータの算出を試みることにしました。 なんとなくしか理解できてない状態のまま書いているのでツッコミ大歓迎。wikiに書いてる手順をそのままやってるだけです。
手順1
まず第一ステップとしてオーブンの素の状態の出力特性を出します。
今回は Arduinoでリフロー炉を作る(3) - 実験 - - masahirosuzuka's blog でやった実験の結果が利用できますね。
この出力特性のうち、最も勾配が急激な部分に接戦を引き、傾きを出します。 今回は300から800あたりが最も急勾配に見えるのでそこをグラフに取り出し、近似線を追加します。
グラフが300から始まっているのでなんか不格好ですが
y = 0.3301x + 61.61
であることがわかりました。この傾き0.3301をRと置きます。
手順2
次にこの接線y = 0.3301x + 61.61と横軸が交わる時刻と入力を加えた時刻(今回は300と800の中点)の差分を出しこの時間をLとします。 計算したところ、L = 4.36sであることがわかりました。
手順3
手に入れたRとLを元に以下を適用します。
Ki | Pi | Di | |
---|---|---|---|
P制御 | 1/RL | ||
PI制御 | 0.9/RL | 3.3L | |
PID制御 | 1.2/RL | 2L | 0.5L |
今回の R=0.3301 L=4.36 を元に計算してみたところ、
Ki | Pi | Di |
---|---|---|
0.833775... | 8.72 | 2.18 |
という結果になりました。
おお!!それっぽい値が出てきたではないか!?(空想科学読本風に)
今回試してみたコードはこれ
#include <SPI.h> #include <PID_v1.h> //#include <LiquidCrystal.h> #define RELAYPIN 7 #define SLAVE 10 double SetPoint, Input, Output; unsigned long time = 0; int WindowSize = 5000; unsigned long windowStartTime; PID myPID(&Input, &Output, &SetPoint, 2, 5, 1, DIRECT); void setup() { windowStartTime = millis(); SetPoint = 100; myPID.SetOutputLimits(0, WindowSize); myPID.SetMode(AUTOMATIC); pinMode(RELAYPIN, OUTPUT); digitalWrite(RELAYPIN, LOW); pinMode(SLAVE, OUTPUT); digitalWrite(SLAVE, HIGH); Serial.begin(9600); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV4); SPI.setDataMode(SPI_MODE0); } void loop() { unsigned int thermocouple; // 14-Bit Thermocouple Temperature Data + 2-Bit unsigned int internal; // 12-Bit Internal Temperature Data + 4-Bit double disp; // display value //delay(100); digitalWrite(SLAVE, LOW); // Enable the chip thermocouple = (unsigned int)SPI.transfer(0x00) << 8; // Read high byte thermocouple thermocouple |= (unsigned int)SPI.transfer(0x00); // Read low byte thermocouple internal = (unsigned int)SPI.transfer(0x00) << 8; // Read high byte internal internal |= (unsigned int)SPI.transfer(0x00); // Read low byte internal digitalWrite(SLAVE, HIGH); // Disable the chip if ((thermocouple & 0x0001) != 0) { Serial.println("ERROR: "); } else { if ((thermocouple & 0x8000) == 0) { // above 0 Degrees Celsius disp = (thermocouple >> 2) * 0.25; } else { // below zero disp = (0x3fff - (thermocouple >> 2) + 1) * -0.25; } Input = disp; myPID.Compute(); if (millis() - windowStartTime > WindowSize) { windowStartTime += WindowSize; } int flag = 0; if (Output > millis() - windowStartTime) { flag = 1; digitalWrite(RELAYPIN, HIGH); } else { flag = 0; digitalWrite(RELAYPIN, LOW); } char str[16]; char temp[16]; char temp2[16]; sprintf(str, "%ld, %s, %s, %d", time, dtostrf(disp, 5, 2, temp), dtostrf(Output, 5, 2, temp2), flag); Serial.println(str); time++; } }
Arduinoでリフロー炉を作る(3) - 実験 -
熱電対のプローブを断線させてしまったようなので秋月で新しいものを買ってきました。400円なりー。
オーブン本体に手を入れる前に少し実験。
実験環境はこんな感じ。オーブンにどの程度の加温能力があるかを調べます。
実験の結果はこうなりました。横軸は時間なのですが目盛りが1進むたびに100ms経過しています。
0~850くらいまでがヒーターをオンにしている部分です。 かなりリニアに温度が上昇しているのがわかります。余裕で200℃以上加温できるのには正直驚きました。Pbフリーはんだにも対応できそうです。
冷却に難がありそうですがそこまでいうのは贅沢でしょう。いずれファンとかを追加してみようと思います。
実験に使ったスケッチはこれ。
#include <SPI.h> #define SLAVE 10 int time = 0; void setup() { pinMode(SLAVE, OUTPUT); digitalWrite(SLAVE, HIGH); Serial.begin(9600); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV4); SPI.setDataMode(SPI_MODE0); } void loop() { unsigned int thermocouple; // 14-Bit Thermocouple Temperature Data + 2-Bit unsigned int internal; // 12-Bit Internal Temperature Data + 4-Bit double disp; // display value delay(100); digitalWrite(SLAVE, LOW); // Enable the chip thermocouple = (unsigned int)SPI.transfer(0x00) << 8; // Read high byte thermocouple thermocouple |= (unsigned int)SPI.transfer(0x00); // Read low byte thermocouple internal = (unsigned int)SPI.transfer(0x00) << 8; // Read high byte internal internal |= (unsigned int)SPI.transfer(0x00); // Read low byte internal digitalWrite(SLAVE, HIGH); // Disable the chip if ((thermocouple & 0x0001) != 0) { Serial.println("ERROR: "); } else { if ((thermocouple & 0x8000) == 0) { // above 0 Degrees Celsius disp = (thermocouple >> 2) * 0.25; } else { // below zero disp = (0x3fff - (thermocouple >> 2) + 1) * -0.25; } char str[16]; char temp[16]; sprintf(str, "%d, %s", time, dtostrf(disp, 5, 2, temp)); Serial.println(str); time++; } }
スイッチサイエンスさんが公開しているサンプルスケッチを少し改造したものです。
Arduinoでリフロー炉を作る(2) - 部品の選定 -
昨日と今日でリフロー炉の部品を揃えました。
揃えたものがこれ
オーブントースター
オーブントースターはKoizumi製のKOS-1012/Wというものです。
全く何も考えずに安かったものを買っただけなのですが興味深いことにこのオーブンはヒーターとタイマーが独立しています。
上のヒーターのスイッチを切に合わせるとヒーターを強制的に止めることができます。これは安全装置として利用できそう。
KOIZUMI【切替機能付 1000Wハイパワー 食パン2枚焼き】オーブントースター ホワイト KOS-1012/W
- 出版社/メーカー: koizumi
- 発売日: 2013/10/02
- メディア: ホーム&キッチン
- この商品を含むブログを見る
Arduino
Arduinoはもともと手元にあったものでDuemilanove(イタリア語で2009の意味)と呼ばれているものです。 Unoとほぼ同じものです。
- 出版社/メーカー: スイッチサイエンス
- メディア: Personal Computers
- 購入: 2人 クリック: 15回
- この商品を含むブログを見る
SSR(ソリッドステート・リレー)
オーブンのヒーターをON/OFFするにはリレーが必要です。
ぶっちゃけ「パワーリレー」と呼ばれるものならばSSRでも機械式でもいいのですが今回は定番の秋月SSRキットを使ってみたいと思います。
250円で買えることもあり日本でリフロー炉を手作りしている人はだいたいこれを使っています。
ちなみに国外のブログではこれ↓を使った手作りリフロー炉をよく目にします。どちらでもほぼ同じようになるはずです。
K型熱電対モジュール
基板の温度は熱電対で計測します。
いろいろいじっているうちに断線してしまった…。
カプトンテープ
熱電対はカプトンテープで固定します。今回は200度まで耐えられるものを手に入れました。
しかし本来は260度まで耐えられる住友3M製の7141あたりを使います。個人で買えるんだろうか…?。
電線
ヒーターの線をながく引き回す必要性を考えて今回はVVFケーブルも用意しました。
Arduinoでリフロー炉を作る(1)
SMD部品の半田付けのためにリフロー炉を作ることにしました。
アメリカやヨーロッパではトースターを改造するのがポピュラーなようで改造キットまで普通に売っています。
日本だとホットプレートを利用したリフローも人気なようです。
実は私も当初ホットプレートリフローを試してみるつもりだったのですが細かな制御ができない様子。
今回は熱ストレスに弱い部品(SDRAMなど)を多用しているのでホットプレートではちょっと怖い。
後々プロトタイプづくりに使用できることも考えるとやはりここらでリフロー炉を作ってもいいのかな…ということで今回チャレンジしてみることにしました。
ぐぐると結構作例は簡単に見つかります。特に参考になったのはこれかな?
オーブントースターをリフローオーブン化してみた | スイッチサイエンス マガジン
いろいろ考えた結果シンプルにこんなかんじにすることにしました。
- 熱に強い熱電対センサを直接熱している基板に貼り付け、基板温度を測ります。
- 温度が目標に達している場合はヒーターをオフ、達していない場合はヒータをオンと言った具合にフィードバック制御を行います。
コントローラはもちろんみんなだいすきArduino ヒーターをオン・オフすると書きましたがヒーターには大きな電流が流れるため、ヒーターを直接つなぐとArduinoが壊れてしまいます。そこでヒーターの制御はリレー(SSR)を使います。これでArduinoとヒーターを絶縁したうえでヒーターを制御することができます。
シンプルですがこんなもんでしょうか?
図には最初からディスプレイがついていますがこれは温度センサ+SSRが完成してから追加しようかと思っています。
将来的には
- 複数温度プロファイルの保存
みたいなこともできたらいいですね。
自作タブレットPC計画実に久々のアップデート
自作タブレットPC計画ですが実は部品を変更しました。それもコアとなるSoCを変えてしまいました。TI Sitara AM335xからAllWinner A13に変更です。当然ピンアサインどころかパッケージ自体が違うので配線もやり直し、基板の名前もGC2からGC3に変えました。
■配線
■電源層