レビューメディア「ジグソー」

自分で作って身の回りのちょっとした不便を解決しよう。夢を叶えるマイコンボード。


今回は、Intel Quark SoC X1000を搭載した「インテルGalileo開発ボード」を用いた試作機のレビューです。


1.はじめに
試作機レビューのためGalileo自体についての説明は簡単に済ませます。

・Galileoって?
 Intelが作ったArduinoの互換ボード。

・Arduinoとは?
 マイコン。オープンソースハードウェア。フィジカルコンピューティング。プロトタイピング。
Arduinoについて調べるとカタカナ文字がいろいろ出てくる。
私の認識はこんな感じ。
「Arduinoボードとちょっとしたプログラムだけで、
実際に光る、動く、測る、ができるモノを手軽に作れる環境」
LED点滅
LED点滅

プログラム、というとPCの中の処理(計算やらゲームやら)を差す印象が強いが、
たったこれだけのプログラムで、現実にLEDが光る。
ここにワクワク感を覚える人はきっと手に取ってしまうプロダクトです。

・GalileoとArduinoの違いは。
オープンソースハードウェアなArduinoは数々の互換機/派生機がでているが、
Intelが満を持して発売したGalileoは一般的なArduinoとはちょっと趣向が違う。
 Arduino・・・マイコンの使い勝手を良くしたもの
 Galileo・・・パソコンにArduino端子をくっ付けたもの
ぱっと見、マザーボードのよう
ぱっと見、マザーボードのよう

心臓部はPentium(x86)互換のSoC「Quark X1000」(400MHz)
Quark X1000
Quark X1000

メモリ256MB、フラッシュ8MB、SRAM512KB(SoC内に統合)
外観にしろスペックにしろパソコンそのもの。
入出力端子も揃ってます
入出力端子も揃ってます

そのはずで内部ではLinuxが動いており、Arduinoはその中でエミュレートされる形。
所謂パソコンと違いがあるとすれば、ディスプレイ出力が無いところ。
そのCPUスペックから一般的なArduinoに比べ内部計算は非常に早い。
反面、Arduinoの特長でもあるIOピン(GPIO)を使った場合の処理速度が遅い。
GPIO 出力の周波数は約230 Hz。
ミリやマイクロの世界を扱うIO処理は苦手。
Arduino的に使うには内部/外部(IOピン)の速度が逆転していることに注意が必要です。


2.試作機の構想
細かい数値はともかく、実際触りながらArduinoの流儀にならったご都合主義的プロトタイピングを考案しました。

試作機案「湿度自動調節機構付ドライボックスの自作」
完成イメージ
完成イメージ

カメラの保管に使われる防湿庫やドライボックスは湿度を一定に保つ機構があるが、
両者の違いは湿度管理が自動か手動かということ。
ドライボックスは乾燥剤を入れ、自分で湿度を確認して
必要に応じて乾燥剤を入れ替えたり乾燥処理をしたりする。
これを自動化すれば、防湿庫と同等の機能を有するドライボックスができるのでは?
というのが今回の試作アイデア。

装置のイメージ。
ドライボックス内部湿度を湿度センサーで監視し湿度を一定に保つ。
乾燥剤はシリカゲル。
温めれば再度乾燥剤として使えるので、ヒーターと抱き合わせて使う。
シリカゲルはドライボックスの外に配置し、フラップを上下2か所に配置。
通常は下フラップを解放し、吸湿。
シリカゲルが弱ってきたら上フラップ解放&ヒーターONしてシリカゲルから湿気を追い出す。

Galileoが担う役割は以下の三つ。
・湿度監視
・内外フラップ制御
・シリカゲルヒーター制御

フラップとヒーターを制御する上で、湿度の値とその変化をトリガーにしたい。
考えられる状況とそのイメージは次のようなもの。


通常使用状態では、下フラップを開放しシリカゲルで除湿を続ける。
この状態から変化する可能性が三つ。
(a).シリカゲルが弱ってきた場合
 シリカゲルが弱ればただの箱。徐々に湿度は上昇し、雰囲気に習う。
(b).カメラを取り出した場合
 カメラを取り出せば、急激に湿度が上がるはず。
 ただし、シリカゲルの効果があるので、その後は元の乾燥状態に戻る。
(c).湿度が予想以上に低下した場合
 シリカゲルの能力が高く、予想以上に湿度を下がりすぎる。

湿度を監視し、以下の3条件を制御するシステム構築が今回の課題。
(a). 『緩やかな湿度上昇 = ヒーターON、上フラップ開、下フラップ閉』
(b). 『急激な湿度上昇&その後の湿度低下 = 制御せず(上フラップ閉、下フラップ開のまま)』
(c). 『基準湿度より湿度低下 = 上フラップ閉、下フラップ閉』


以上のイメージを元に今回の使用部品を選定した。
キモとなる部品は次の四つ。
①湿度センサー :湿度センサユニット丸型 / CHS-UGR  TDK製
 非常に優秀な湿度センサー。
 回路一体型で電源を接続するだけで、湿度が電圧値で取り出せる。
 ただ、ちょっと高い。


②除湿ユニット:東洋リビング モバイルドライ 除湿ユニット MD-2
 名前にあるようにモバイルできる除湿ユニット。
 ヒーターを内蔵しておりAC電源に繋げば乾燥できる。



③サーボモータ:GWSサーボ PICO/STD/F(フタバ)
 フラップ制御用のモータ。
 トルクがどのくらい必要か不明なので検証しながら場合によっては変更。



④ソリッドステートリレー(以下SSR):ソリッド・ステート・リレー(SSR)キット 25A(20A)タイプ
 除湿ユニットがAC電源のため、SSRでON/OFFを制御する。
 秋月のキットは便利ですね。



3.制御式の検討
まずは、ボックス内に湿度センサーを配置し、湿度データを確認してみた。
テープで実装。
テープで実装。

ドライボックス上蓋の天面にGalileo、底面に湿度センサーを仮で配置。
上蓋はドリルで穴を開けて、センサーと接続。

この状態で湿度のモニタリングを開始。
データは1min毎に掃き出し、300ポイント分を配列に保存した(=300分=5時間)。
尚、今回選定した湿度センサーの公証精度は±5%RH。
読み値のままでいくと、レンジ10%RHの測定誤差が発生してしまう。
測定誤差によるバラツキを抑えるため、同時に移動平均のデータも取るようにした。
このデータをグラフ化したものが次のグラフとなる。
湿度推移
湿度推移

移動平均の区間はいろいろ検討してみたが、5ポイント(5min)平均で良いと判断。
前後ポイントとの誤差は1%RH程度であり、比較用の計算に支障ないレベルである。

左のグラフはシリカゲルを入れないで密封したパターン。
構想時に予想した 「 (a).シリカゲルが弱ってきた場合 」がまさにこれ。
40%RHから徐々に湿度が上昇している。
3%RH/300minの傾きが得られる。
周辺環境湿度もそれほど高くない(45RH程度)為と考えられる。作ったの冬場だし。

右のグラフは蓋解放状態から、シリカゲルを入れて放置したパターン。
構想時に予想した 「 (b).カメラを取り出した場合 」の再現。
湿度を周辺環境になじませるべく解放から開始しているが、周辺環境でも43%RH程度。
そこから30minかけて一度38%RHまで低下し、40%RH付近で均衡が取れる。
ここから、5%RH/30minの傾きが得られた。
この傾きが線形近似できるとするならば、
湿度が60%RHで均衡に掛かる時間は60min程度、
湿度が70%RHなら120minと考えられる。
シリカゲルによる乾燥が正常に働けば、このような右肩下がりのグラフとなる。

その後、24h続けてデータをモニタリングしていったが、40%からほとんど変化なし。
構想時に予測した「(c).湿度が予想以上に低下した場合」はあまり気にしなくてよさそうだ。

・湿度計算式は5ポイント平均の移動平均を使用
・シリカゲル乾燥による湿度は40%RH程度で均衡
・「 (a).シリカゲルが弱ってきた場合 」の湿度上昇は緩やか、2%RH/300
・「 (b).カメラを取り出した場合 」からの回復は急峻、5%RH/30min
カメラの保管環境として最適な湿度は、とgoogle先生に聞くと40~50%RH程度らしい。

 実計測結果を踏まえ、シリカゲルが弱った場合とカメラを取り出した場合の切り分けを行う。
計算に使う値は、30分毎の5点移動平均データ10点で行いt(1)~t(10)、以下の条件で判断する。
 ①t(10)が湿度50%RHを超えたとき
 ②t(1)~t(8)のうち、4ポイント以上湿度45%RHを超えたとき
これら2条件がすべて正の場合のみ、シリカゲルが弱ったと判断しヒーターONの処理を行う。
それぞれの条件を設定した経緯は以下。
①は直近の湿度測定が50%を超えたときなので説明は省略。
②は以下の湿度変化の予測グラフを比較しながら検討した。
湿度変化予測
湿度変化予測

第一にシリカゲルが弱った場合のデータから回帰直線を求める。
R=0.0061t+b  ・・・式(1)
湿度:R、時間:t、0minの時間(定数):b
この式を基本とするが、外気湿度が低い状態の傾きのため、傾き2倍、4倍となった場合も考慮する。
これが左グラフ。
対して、カメラを取り出したときは急な温度変化となる。
こちらも予測される状態として、蓋の複数回解放やヒーター乾燥後の状態等を考慮して4水準のグラフで検討。
第一の条件で直近の湿度は50%RH以上であることが前提なので、
t(10)と念の為t(9)を省いた8点のグラフの形から判断する。
ここで、シリカゲルが弱った場合の変化が緩やかである事を考慮して、
突発的な湿度上昇と段階的な湿度上昇を切り分ける。
その方法として、4ポイント以上湿度45%RHを超えたときとした。

4.フローチャート
前項までで検討した状況をフローチャートにまとめてみた。
フローチャート
フローチャート

このフローチャートをもとに、スケッチ(プログラム)を作成。
試作機Ver1.0用に載せてあるスケッチは末尾にそのまま転記してあります。

5.実装
工作は主にドライボックス天板に対し行う。
センサー部
センサー部

センサーはドライボックス内部に入れる。
もともと一体型センサーでカバーはあるものの、配線基板もあるため、上にカバーを付けた。
脱臭剤ケース利用
脱臭剤ケース利用

カバーは脱臭剤のケースを分割し利用。
ボックス天板裏に配置。
ボックス天板裏に配置。

ボックス天板裏に設置した。

GalileoボードとSSR/各入出力端子中継用の基板を天板手前に配置。

基盤にはACアダプタ端子をつけ、ここから給電。
サーボモータを使用しているので、Galileo経由だと壊す可能性があるため、
逆にこの基盤からvccピン経由でGalileoに給電している。

基盤の空きスペースは今後の拡張用として残してある。

天板奥には除湿ユニットボックスを配置する。
除湿ユニットボックス内部は 除湿ユニット MD-2を中心にフラップ制御用のサーボモータを配置。
除湿ユニットとサーボモータ
除湿ユニットとサーボモータ

除湿ユニットはコンセント直刺し型なので延長コードを使って外部のSSRに接続する。
この除湿ユニットボックスを配置するドライボックス天板にもサーボモータを設置して、
ドライボックス-除湿ユニットボックスのフラップ制御を行う。
天板裏サーボモータ
天板裏サーボモータ


フラップは当初サーボで昇降させる蓋を想定していたが、
サーボモータのトルクの関係上、可能な限り軽量なものにする必要があった。
このため、プラ板とシリコンマットを接着したものつくり、自重で蓋として締まるようなものとした。
クローズ状態
クローズ状態

オープン状態
オープン状態

サーボモータはただ持ち上げるだけ。
機構としては非常に簡単ながら、自重とシリコンマットの弾性で締まるので最低限の密閉性は確保できそうだ。

全体像
試作機Ver1.0の外観写真。
正面から
正面から

側面から
側面から


6.おわりに
以上のプロトタイピングで、「湿度自動調節機構付ドライボックスの自作」として完成である。
今後の展望としては
・密閉性の向上
・梅雨~夏場の雰囲気をもとにした湿度判定式の見直し
・低消費電力化
が見込まれる。
スケッチ(プログラム)にも無駄が多いことは承知の上で今後のデータ取りを見こし300点データ測定等を残している。

今回はGalileoのレビューを通して、いろいろな勉強になった。
良い機会を頂き、ZIGSOW運営事務局殿、Intel殿に感謝しております。






#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Servo.h>
#include <TimerOne.h>

Servo serv1;//サーボのインスタンス
Servo serv2;//サーボのインスタンス
int deg;
volatile int state1 = HIGH;//下フラップ制御機構
volatile int state2 = LOW;//上フラップ制御機構
volatile const float VCC = 5.64; //電源電圧(実測値)
//float vref = 1100; //内部基準電圧
volatile unsigned int humarray[300]; //湿度用配列生成
volatile unsigned int humave[296]; //湿度平均用配列生成
volatile int state = HIGH;
/////////////////////////////////////////////////////動作検証用////////////////////////////////////////////////////////////////////
volatile byte dummyno = 1;//dummy
volatile unsigned int humdummy1[11] = {4000,4018,4036,4054,4073,4091,4109,4128,4146,4164,4183}; //動作検証用配列生成 no_action
volatile unsigned int humdummy2[11] = {4820,4838,4856,4874,4893,4911,4929,4948,4966,4984,5003}; //動作検証用配列生成 f_dry
volatile unsigned int humdummy3[11] = {5500,5000,4500,4000,4000,4000,4000,4000,4000,4000,5000}; //動作検証用配列生成 no_action
volatile unsigned int humdummy4[11] = {2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000}; //動作検証用配列生成 alloff
/////////////////////////////////////////////////////動作検証用////////////////////////////////////////////////////////////////////

void setup () {
serv1.attach(9); //デジピン8をサーボ1
serv2.attach(10); //デジピン9をサーボ2
pinMode(12,OUTPUT); //LED1 12ピン
pinMode(13,OUTPUT); //LED2 13ピン
// attachInterrupt(2,pressed0,CHANGE); //デジピン2を割り込み0押したとき処理
analogReadResolution(12);//アナログリードの分解能指定12ビット
int humini = analogRead(0); //湿度配列の初期化
for(int i=0;i<300;i++){
humarray[i]=(VCC/4096)*humini/0.01*100;//10mv/℃で割って2桁繰り上げ
humave[i]=(VCC/4096)*humini/0.01*100;//10mv/℃で割って2桁繰り上げ
}

Timer1.initialize();//タイマー初期化
// Timer1.attachInterrupt(keisoku, 1000000*60);//x×1s毎にタイマー割り込み

Timer1.attachInterrupt(keisoku, 1000000*2);//x×1s毎にタイマー割り込み

}

void loop () {
serv1.write(state1*89+1);//0度か179度か
serv2.write(state2*89+1);//0度か179度か
// 本業:10Hz で点滅
digitalWrite(13, HIGH);
delay(700);
digitalWrite(13, LOW);
delay(300);
}

void keisoku () {//タイマー割り込み
//湿度データ読み取り、配列格納
int indata=analogRead(0);
humarray[299]= (VCC/4096)*indata/0.01*100;//10mv/℃で割って2桁繰り上げ
// humave[295] = (humarray[298]+humarray[297]+humarray[296]+humarray[295]+humarray[294])/5;//5点移動平均計算、代入

/////////////////////////////////////////////////////動作検証用////////////////////////////////////////////////////////////////////
switch(dummyno){
case 1:
for(int q=0;q<=10;q++){
humave[q*29] = humdummy1[q];
}
break;
case 2:
for(int q=0;q<=10;q++){
humave[q*29] = humdummy2[q];
}
break;
case 3:
for(int q=0;q<=10;q++){
humave[q*29] = humdummy3[q];
}
break;
case 4:
for(int q=0;q<=10;q++){
humave[q*29] = humdummy4[q];
}
break;
}
/////////////////////////////////////////////////////動作検証用////////////////////////////////////////////////////////////////////


//表示。後でLCDに置き換えるかも。
for(int t=0;t<=10;t++){
Serial.print(humave[t*29]);
Serial.print(",");
}
Serial.println(",");
//////////////////////////////比較式を入れる//////////////////////////////////////////
if(humave[290] > 5000){//湿度平均295ポイント目が湿度50%を超えていた場合
byte cntu = 0;//45%RH以上のポイント数カウント用変数
for(int i=0;i<=10;i++){
if(humave[i*29]>4500){//humave[i*29]が45%以上ならcntuを1増やす
cntu++;
}
}
if(cntu >= 4 ){
f_dry();
}
}

else if(humave[290] < 3500){//湿度が35%を下回った場合
alloff();//オールオフ実行
}

else{//湿度が35~50%RHのとき
Serial.println("no_action");
}//何もしない

////////////////////////////比較終了/////////////////////////////
//湿度配列の一マスずらし
for(int t=0;t<299;t++){
humarray[t]=humarray[t+1];
}
//湿度平均配列の一マスずらし
for(int t=0;t<295;t++){
humave[t]=humave[t+1];
}
if(dummyno<4){
dummyno =dummyno+1;
}else{
dummyno =1;
}
}

//乾燥状態
void f_dry(){
Serial.println("f_dry");
state1=!state1;//サーボ1の位相反転 蓋〆
state2=!state2;//サーボ1の位相反転 蓋開
delay(1000*5);//5秒待ち

digitalWrite(12, HIGH);//SSR ON
// delay(1000*60*60*3);//3時間待ち
delay(1000*2);//テスト用2秒待ち
digitalWrite(12, LOW);//SSR OFF
// delay(1000*60);//60秒待ち
delay(1000*1);//テスト用1秒待ち

state1=!state1;//サーボ1の位相反転 蓋〆
state2=!state2;//サーボ1の位相反転 蓋開

int humini = analogRead(0); //湿度配列の初期化
for(int i=0;i<300;i++){
humarray[i]=4400;//10mv/℃で割って2桁繰り上げ
humave[i]=4400;//10mv/℃で割って2桁繰り上げ
}
}

//低湿状態
void alloff(){
Serial.println("alloff");
state1=!state1;//サーボ1の位相反転 蓋〆
//delay(1000*60*30);//30分待ち
delay(1000*5);//5秒待ち
state1=!state1;//サーボ1の位相反転 蓋開
delay(1000*5);//5秒待ち

int humini = analogRead(0); //湿度配列の初期化
for(int i=0;i<300;i++){
humarray[i]=(VCC/4096)*humini/0.01*100;//10mv/℃で割って2桁繰り上げ
humave[i]=(VCC/4096)*humini/0.01*100;//10mv/℃で割って2桁繰り上げ
}
}

コメント (12)

  • しばさん

    2014/03/07

    レビュー+試作機の完全開発お疲れ様です!!
  • CLWさん

    2014/03/07

    レビューお疲れ様でした。
    実用的なものをやったんですね。
    なかなかいいと思います。…今後の参考にします。
  • Manyaさん

    2014/03/07

    >しばさん
    コメントありがとうございます。

    中間報告までにある程度形にしてしまいたい、
    ということで何とか形にはなりました^^
    今後もアップデートしていきたいですね。
他9件のコメントを表示

ZIGSOWにログインするとコメントやこのアイテムを持っているユーザー全員に質問できます。

YouTube の動画を挿入

YouTube の URL または動画の ID を入力してください

動画の ID が取得できません。ID もしくは URL を正しく入力してください。

ニコニコ動画の動画を挿入

ニコニコ動画の URL または動画の ID を入力してください

動画の ID が取得できません。ID もしくは URL を正しく入力してください。

ZIGSOWリンク挿入

検索対象とキーワードを入力してください

    外部リンクを挿入

    リンク先の URL とタイトルを入力してください

    URL を正しく入力してください。

    画像を挿入(最大サイズ20MB)

    画像を選択してください

    ファイルサイズが20MBを超えています

    別の画像を追加

    ほかのユーザーのレビュー

    ZIGSOW にログイン

    ZIGSOW会員登録(無料)はこちらから