羽根愛好家

Blog Airplane Photo Bird Photo About Contact

そして完成へ

2011年 12月 04日

 ハードウェアのほうはプログラムより先に出来てたのでした。

20111204_01.jpg20111204_02.jpg

 ケースは毎度おなじみ100均で調達。フタがないやつを買ったんで,そっちは余ってた透明アクリルパネル(1mm厚ぐらい)のを適当に貼り合わせて作りました。ちなみに天板にLCDを埋め込むことも考えたんですけど,夜露が怖い,LCDを取り外せるようにしておきたいなどの理由により,完全に収納してしまっています。ちなみにmbed本体も取り外せるにしてあります。ほかに何か思いついたら遊びたいし。
 
 最終形の回路図は↓な感じ。
20111204_03.jpg
 前回からの変更点としては,LCDのコントラスト調整に可変抵抗を組み込んだり,LCDバックライト(そもそも書き忘れてた)にスイッチとか明度調整の可変抵抗を入れたり,ニクロム線に並列してるLEDの抵抗値を上げて暗くしたり,スイッチ付けたり。

 スイッチは3個付けたんですけど,実基板にはp8に繋がる4個分の配線があって最初は付けてたんですけど,最終的には外しました。理由はp8の信号をmbedがどうしても読み取れないから。たぶんp8だけ壊れた気がする。心当たりもあるし(一度間違えてp8に12Vを入れてしまった/笑)。なので,1個をaltキーっぽい扱いにして,これを押しながらだとほかのスイッチが別動作をできるようにしています。まだ機能は割り当ててないっていうか,割り当てるべき機能も浮かばないけど。

 あと,スイッチにチャタリング対策のコンデンサも入ってるんですけど,容量足らなかったみたいでこれ入れても見事にチャタってくれてます。ソフトウェア側で対策うつってのも考えたんだけど,超簡単にwait入れようと思ったらwait中も割り込みは動くってmbedのhandbookに書いてあって,InterruptInだとたぶんアウト。一度押したらフラグ立てて,そのあとのNms以内の割り込みは無視する,みたいな感じにしなきゃダメなんだろなー。どうせ自分しか使わないものだし,運用でカバーできるものは後回し-。

 でも,いろいろ不満のある作りなのと,湿度センサはやっぱり付けたいので,作り直す可能性がなきにしもあらず。湿度センサは千石で売ってるこれとかちょっと気になってます。安いし。

 ま,とりあえずはフィールドでのテスト。今週は天気悪かったので,次の週末に。って次の週末は皆既月食ですね。楽しみだけど,すなわち満月だからヒーター使うほど長時間は出撃しない可能性大。つか月食なら自宅でも充分だし。

  • 雑感2011
|2011/12/04 18:12 |コメント(0)

とりあえずコーディング

2011年 11月 28日

 えっと,ざっくりと書いてみました。
 難しいというか,肝心なところは,ニクロム線に流す電力で使ってるPWM制御のデューティー比をどう変化させるかっていう部分。車は急に止まれない…じゃなくてニクロム線ヒーターは急に温度が下がったり,上がったりはしません。単純に「目標温度<現在温度ならデューティー比下げる,またはその逆」みたいな処理だと,どうしても目標温度との開きが大きい状態で推移してしまいます。で,センサーを読み取ったときに前回の読み取り結果との差から,現在の状態が上昇状態にあるのか下降状態にあるのかを記録しておいて,

現在の温度がターゲット温度より高い場合
→下降指示
 →下降中で温度差が大きい場合に大きく引き下げる
 →下降中で温度差が小さい場合には少し持ち上げる
 →上昇中に下降指示が出た場合は大きく引き下げる

現在の温度がターゲット温度より低い場合
→上昇指示
 →上昇中で温度差が大きい場合には大きく引き上げる
 →上昇中で温度差が小さい場合には少し引き下げる
 →下降中に上昇指示が出た場合は大きく引き上げる

という感じに,目標温度付近で足踏みさせるようなやり方を考えてみました。
 プログラムのほうは,↑の発想をそのまま条件分岐させただけっていうテキトー具合なんですが,まぁそこはそれで。もうちょっと美しいアルゴリズムがありそうなんだけど,ちゃっちゃっと作ってしまいたかったので,とりあえず書き切ることを優先しました。
 結果はまずまずで,この状態で家の中で試して見ると,目標温度±1℃以内の範囲で動いてくれてます。デューティー比を変化させるかどうかのルーチンを実行するインターバルや,デューティー比の変化量はざっくり設定してますが,悪くない設定っぽいです。もちろん,ベストかどうかは分からないですけど。
 あとは,屋外でレンズに巻いた状態だと違う結果になる可能性もあるんで,次はフィールドでテストして,必要なら調整しようと思ってます。一応,スイッチで目標温度を変えられるようにしてあるので,目標温度より大きく離れた位置で動きが止まるようなら,調整が終わるまでは目標温度を無理矢理引き上げ/引き下げてカバーしようとか思ってたりします。
 あと,ログ記録のための準備はしたんですが,ルーチンは書いてません。気が付いた方はえらい!(笑。あ,さらに,↓のコードで表示が乱れるのはウチのブログがデザインをちゃんとクロスプラットフォーム対応にしてないのが原因なので,気にしないでください。

 え? ハードウェアのほうはどうなったかって? 今度書きます。

#include "mbed.h" #include "TextLCD.h" #include "LinearTempSensor.h"

Serial pc(USBTX, USBRX);
TextLCD lcd(p24, p26, p27, p28, p29, p30, TextLCD::LCD16x2); // LCD(RS, E, DB4, DB5, DB6, DB7)
LinearTempSensor sensor[] = {p20,p19,p18}; // sensor([0][1]=heater, [2]=ambient)
PwmOut heat_pwm[] = {p22,p21};

InterruptIn sw[] = {p5, p6};
DigitalIn s_sw(p7);

Ticker sensor_timer, heater_timer, log_timer;

float target_temp = 35.0;
float Tav[3];
int current_direction[3];


// interrupt event - change target temperature
void switch0() {
  if(s_sw.read() == 1) {
    if(target_temp < 45) {
      target_temp += 0.5;
    }
    lcd.locate (10,1);
    lcd.printf ("%2.1f", target_temp);
  }
}
void switch1() {
  if(s_sw.read() == 1) {
    if(target_temp < 10) {
      target_temp -= 0.5;
    }
    lcd.locate (10,1);
    lcd.printf ("%2.1f", target_temp);
  }
}


// read temperature
void read_temp() {
  float Vout[3], previous_Tav[3];
  
  for(int i = 0; i < 3; i++) {
    previous_Tav[i] = Tav[i];
    Vout[i] = sensor[i].Sense();  // read sensor
    Tav[i]  = sensor[i].GetAverageTemp();  // calculate average temperature from 10 samples
    
    if((previous_Tav[i] - Tav[i]) > 0) {
      current_direction[i] = 0;
    } else {
      current_direction[i] = 1;
    }
  }
  
  // print temperature to LCD
  lcd.locate(2,0);
  lcd.printf("%2.1f", Tav[0]);
  lcd.locate(10,0);
  lcd.printf("%2.1f", Tav[1]);
  lcd.locate(2,1);
  lcd.printf("%2.1f", Tav[2]);
}


// change pwm duty cycle
void change_pwm_cycle(int heater_num, int recieve_direction) {
  float modified_cycle = heat_pwm[heater_num].read();
  float temp_difference = Tav[heater_num] - target_temp;
  
  if(temp_difference < 0) {
    temp_difference *= -1;
  }
  
  switch(recieve_direction) {
    case 0:
      if(current_direction[heater_num] == 0) {
        if(temp_difference > 5) {
          modified_cycle -= 0.2;
        } else if(temp_difference < 2) {
          modified_cycle += 0.05;
        }
      } else {
        modified_cycle -= 0.2;
      }
      break;

    case 1:
      if(current_direction[heater_num] == 1) {
        if(temp_difference > 5) {
          modified_cycle += 0.2;
        } else if(temp_difference < 2) {
          modified_cycle -= 0.05;
        }
      } else {
        modified_cycle += 0.2;
      }
      break;
    
    default:
      break;
  }
  
  if(modified_cycle < 0) {
    modified_cycle = 0;
  } else if(modified_cycle > 1) {
    modified_cycle = 1;
  }
  
  heat_pwm[heater_num].write(modified_cycle);
}


// control heater
void control_heater() {
  for(int i = 0; i < 2; i++) {
    if(Tav[i] > target_temp) {
      change_pwm_cycle(i ,0);
    } else if(Tav[i] < target_temp) {
      change_pwm_cycle(i, 1);
    } 
  }
  pc.printf("0:%1.3f 1:%1.3f \n",heat_pwm[0].read(), heat_pwm[1].read());
}


// main
int main() {
  // init LCD
  lcd.cls();         // clear LCD
  
  lcd.writeCommand(0x40);    // create Celsius symbol and write to CGRAM
  wait(0.000040f);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x14);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x06);
  lcd.writeData((int)0x09);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x09);
  lcd.writeData((int)0x06);
  wait(0.000040f);
  
  lcd.locate(0,0);   // print fixed char to LCD
  lcd.printf("1:");
  lcd.locate(8,0);
  lcd.printf("2:");
  lcd.locate(0,1);
  lcd.printf("a:");
  lcd.locate(8,1);
  lcd.printf("t:");
  
  lcd.locate(6,0);
  lcd.putc(0x00);
  lcd.locate(14,0);
  lcd.putc(0x00);
  lcd.locate(6,1);
  lcd.putc(0x00);
  lcd.locate(14,1);
  lcd.putc(0x00);
  
  lcd.locate(10,1);
  lcd.printf("%2.1f", target_temp);
  
  // set interrupt event
  sw[0].rise(&switch0);
  sw[1].rise(&switch1);
  
  // init PWM //
  heat_pwm[0].period_ms(10); // set pwm period 10ms=100Hz
  heat_pwm[1].period_ms(10);
  
  heat_pwm[0].write(1); //set default pwm duty cycle
  heat_pwm[1].write(1);  
  
  // read first temperature  
  read_temp();
  
  // set interval event
  sensor_timer.attach(&read_temp, 1);
  heater_timer.attach(&control_heater, 5);
}

 あー,貼り付けててピンときた。摂氏マイナスになったときのこと考えてないや,これ。LCDの桁数が足りない(笑。頑張って作ったけど,℃←を消すかな……。

  • 雑感2011
|2011/11/28 23:42 |コメント(0)

とりあえず温度センサー

2011年 11月 18日

 自信のない作業をやってるときは,間違いを早々にツっコんで頂いたほうがいいので,まめに更新します(笑。いろいろ調達して温度センサー部は一応動きました。とりあえず最新版の回路図。PWMコントロールの部分は部材は調達したけど,まだ作業してません。まずは温度センサーってことで。

20111118_00.jpg

 
 センサーは予定どおりMCP9700を使いまして,ニクロム線ヒーター×2に加えて,環境温度というか外気温を測定するセンサーを追加しておきました。まだ具体的には考えてなくて漠然とした最終形のイメージですけど,外気温を見てヒーターのターゲット温度を自動的に決めさせようかな,と突然思いついたので追加しました。本当は湿度計も付けたほうが良いのかも知れませんが,AnalogInはまだ余ってるんで追々考えます。でも湿度センサーってちょっとお高いんですよね……。
 あと,一応LCDも買いました。ヒーターコントローラに付けるかどうかは微妙ですけど,テストしてるときには便利~なので。
 誤差は何か大きくて,本当はちゃんと較正すべきっぽいんですけど,前もちょっと書いたように,レンズを痛めるほどの温度上昇や夜露を防げないほどの温度下降がなければニーズは満たせるんで,とりあえず2~3度の誤差は良いかなと思ってます。

20111118_01.jpg
20111118_02.jpg

 ソースは下な感じ。表示が一部崩れてるんですがブログ側の問題なので気にしないでください<直せよ。
 センサーの温度は,公開されてるライブラリをそのまま使ってラクさせてもらいました。感謝感謝。


#include "mbed.h"
#include "TextLCD.h"
#include "LinearTempSensor.h"

//Serial pc(USBTX, USBRX);
TextLCD lcd(p24, p26, p27, p28, p29, p30, TextLCD::LCD16x2); // LCD(RS, E, DB4, DB5, DB6, DB7)
LinearTempSensor sensor[]={p18,p19,p20}; // sensor([0]=ambient, [1][2]=heater

int main()
{
  float Vout[3], Tav[3];
  int i,j;
  
  lcd.cls();         // clear LCD
  
  lcd.writeCommand (0x40);    // create Celsius symbol and write to CGRAM
  wait(0.000040f);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x14);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x06);
  lcd.writeData((int)0x09);
  lcd.writeData((int)0x08);
  lcd.writeData((int)0x09);
  lcd.writeData((int)0x06);
  wait(0.000040f);
  
  lcd.locate(0,0);   // print fixed char to LCD
  lcd.printf("1:");
  lcd.locate(8,0);
  lcd.printf("2:");
  lcd.locate(0,1);
  lcd.printf("0:");
  lcd.locate(6,0);
  lcd.putc(0x00);
  lcd.locate(14,0);
  lcd.putc(0x00);
  lcd.locate(6,1);
  lcd.putc(0x00);
   
  for (i=0; i<500; i++)
  {
    for (j=0; j<3 ;j++)
    {
      Vout[j] = sensor[j].Sense();          // read sensor
      Tav[j]  = sensor[j].GetAverageTemp(); // calculate average temperature from 10 samples
    }
    
    lcd.locate(2,0);                        // print temperature to LCD
    lcd.printf("%2.1f", Tav[1]);
    lcd.locate(10,0);
    lcd.printf("%2.1f", Tav[2]);
    lcd.locate(2,1);
    lcd.printf("%2.1f", Tav[0]);
      
    //pc.printf("%f,%f  %f,%f  %f,%f\n", Tav[0],Vout[0], Tav[1],Vout[1], Tav[2],Vout[2]); //Debug
    
    wait(0.1);
  }
}

 で,このセンサーを3芯のステレオミニジャックで接続できるようにして,2個をニクロム線に固定。だいたい3mぐらい伸ばすので,ノイズが載らないか心配ですが,これはもう少し作業が進んでからテストします。

20111118_03.jpg
20111118_04.jpg

 えっ? しし座流星群ですか? 見に行ってません。

  • 雑感2011
|2011/11/18 17:27 |コメント(0)

次のプロジェクト

2011年 11月 15日

 えー,よく分かんないけどコンデンサが爆発しちゃった,たわわです。やっぱり原因は分かりませんが,とりあえずその話は後回し。

 こないだ書いた12Vの定電圧ユニットの入れ物を新調しました。前は100均で買ったポリプロピレンのケースを使ってたんですけど,PPはやっぱいろいろ接着が甘かったりして,気が付いたら基板がケース内で暴れたので,今度はスチロールのケースを100均で見つけて試してみました。
 一応,スチロール対応の接着剤とか使ってるんで今度は大丈夫っぽい感じ。乱暴に扱うと分かりませんが。ただフタが固定できないのと,ちょっと高さが足りなかったので,ホットボンドで嵩上げしたり,ベロクロテープ使ってフタを固定したりしてます。ケーブルは少しはみ出すけど,シガープラグのほうも収納できるんで実用上はOKかな,と。

20111115_01.jpg20111115_02.jpg

 
 これは現状の改善でしかないので,こないだチラッと書いた次の工作の話を少し。次の目標はレンズの結露防止ヒーターの工作です。最低条件は「12Vでニクロム線を暖める」だけだったんですけど,ただ暖めるだけだといろいろ怖い。やっぱヒーターコントローラは作らないといけないなーっと思ってたところで,いきなり気が向いて,温度ができるだけ一定になるようにPWM制御してみようかな,と決めました。
 といっても極端な温度上昇&下降がなければOKなんで,数秒ごとに温度をモニターして,ターゲット温度より低かったら強めに,高かったら弱める,ぐらいの制御しか考えてません。

 ということで,とりあえずニクロム線ヒーターの工作。これは大したことなくて,ホームセンターで買った0.26mmのニクロム線を,使ってない二線の電話線にグルグル巻いて,両端をそれぞれ異なるケーブルに接触させて引き出してるだけ。
 12Vで使ってる天体屋さんのニクロム線ヒーターをWebで探してみると,だいたい30~40Ωぐらいにしてる人が多い。僕は温度で制御するし,もう少し低い抵抗でもいいかなっと思って25Ωで作ってみたらやっぱり熱すぎたので,とりあえず30Ωを目標に作って,結果29Ωになりました(笑。2本作ったんだけど,2本とも同じぐらい。最終的には熱収縮テープを被せて,先っぽは3.5mmのDCプラグに引き出しています。

20111115_03.jpg20111115_04.jpg

 
 次に温度センサーと制御部。ここでmbedを使うっつーことです。明らかに役不足(正しい意味で)なんですけど,「ヒーターを作りたい」「眠らせてないでmbed使わなきゃ」っていう二つの欲求は別々に存在してて,それを一つにまとめて実行してるだけなんで,mbedを使うことも一つの目的なんです(キリッ
 それはともかく,コンデンサを爆発させたのは,mbedのVinにシガープラグから5Vを供給するのに,USB給電アダプタ使えばチョロイじゃん!ということで試したところだったのでした。目の前で爆発したのは初めての経験でちょっとトラウマになってるので,気持ちが落ち着いたら再挑戦してみます。もう1個同じアダプタがあるので。

 で,オームの法則すら怪しいレベルで電子回路に疎いワタクシなので,とりあえずサーミスタを使って温度を読み取る回路を作ってみることに。サーミスタは何年も使ってないPC用の温度モニターから切り取りました。サーミスタの型番とか分かんなかったんですけど,そっちの回路を見たらプルアップ抵抗っぽいのに10kΩのチップ抵抗が使ってあったんで,真似してみました。
 結果,数値は読み取れることを確認はできました。ただ,サーミスタで読み取った数値から温度へ換算する計算式でつまずいています。ってのがイマココ。なんですけど,もう面倒なんでリニアなサーミスタICを買おうと思ってます。上述のとおり,精度はそれほど求めないんで安いMCP9700で。LM35はたかーい。

20111115_05.jpg

 
 という感じで,次はPWM制御の実験なんですけど,mbedで使いやすそうなMOS-FETが手元にないんで,これを調達してからの実行になります。MCP9700も入手しないといけないし。
 とりあえず,ヒーターが出来たところで一応の目標を達成してしまっているという危険な状態なので,退路を断つために回路図なんてものを書いてみました。超トーシロが書いたものなのでいろいろ怪しいんで,誰もする人はいないと思うけどマネしないでください。そもそもまだ組んで動くことを確認したものじゃないんで(笑
 実際に組んでみてから確認しないといけないのは,3.3VoutとMCP9700の間にある抵抗が必要かどうか。普通のサーミスタ使う場合は差を見るのに必要なんですけど,MPC9700のデータシートに載ってるサンプル回路っぽいのを見ると抵抗入れてないんですよね。分からんです。
 あと,PWM制御用のMOS-FETのゲートのところにも抵抗入れてるんですけど,これ要らないかもなーと思ってます。あっても動くなら気分的には入れておきたいんですけど。
 「おいおい,ここおかしいぜ!」ってのがあったら,こっそりじゃなくていいので教えてください。

20111115_06.jpg

 
 あとは無駄にLCDパネルとか入れてみようかなーとか思ったりもするんですが,ニクロム線ヒーターが計算上一つで410mAちょっと使ってて,主鏡とガイド鏡の2本で830mAぐらい。バッテリが13Ahなんで,赤道儀のモーターにも同じバッテリ使うとなると(しっかり測ってませんけど)全部で1.5Aぐらいは見といたほうがいいかなーと思ってるので,いろいろ見積もって6時間ぐらいでバッテリ切れそうっすねーってことで,無駄な消費電力を避けたい気持ちもあります。
 しかし無駄にリッチなのが僕らしい気もするし,そもそもオートガイドに使ってるネットブックって寒い日だとバッテリ2本で5~6時間ぐらいしか持たないハズなので,もう5~6時間しか撮らない!と決めるとか,もう1個バッテリ買っちゃうとかでもOKな気がしていたり。
 え? プログラムですか? 温度さえ分かるようになれば,プログラムのほうはあまり心配してません。

  • 雑感2011
|2011/11/15 22:47 |コメント(2)

シャッター制御の手直し

2011年 11月 08日

 昨日の今日ではないけどそれにかなり近い感じで,新しいリレーボックスの改良。……改良というよりデバッグレベルではありますが。
 で,改良(と言い張る)版の基板と,ついでに撮り忘れてた裏面の写真を。前回のと見比べていただくと分かりますが,ダイオードを一つ追加しました。何のためのものかは書くのも恥ずかしいので(笑),シャッター制御回路部分の回路図を載せるだけにしておきます。
 ちなみに裏面に被膜ケーブル多用してるのは,配線を考えるのが面倒っていうわけでは……ちょっとあるんですけど,それ以上に信号の種類を整理する目的でやってるものです。赤・橙がRA+/-,黄・緑がDecl+/-,青がシャッターの制御を行うっていう風に分けてます。写真の下の方の黄色と白色のは何の意味もないんですけど。

20111108_01.jpg20111108_02.jpg20111108_03.jpg


 んな感じで,リレーボックスについてはこれで完成ってことにしたい感じ。次にやりたい電子工作も決まってて,構想だけは無駄に壮大なものが頭で出来てるんですけど,やり始めて別にこんな機能いらないよねってことで簡素化して,出来上がってみたら何の特徴もないものになると予想してます。とりあえずは構想に沿って長らく寝かせてしまったmbedの勉強から始めようと思ってますが,最終的にはたぶん使わない流れ(笑

  • 雑感2011
|2011/11/08 14:38 |コメント(0)
1  2  3  4  5  6  7  8  9  10  11 >Next

最近の記事

  • そして完成へ
  • とりあえずコーディング
  • とりあえず温度センサー
  • 次のプロジェクト
  • シャッター制御の手直し
  • 牛歩のごとく進展
  • 天体写真にはまってる話
  • えこぼんぼん
  • 世界一周から帰ってきた飛鳥II
  • いざ!セントレア!

カテゴリ

  • 日々雑感
    • 雑感2009 (28)
    • 雑感2010 (2)
    • 雑感2011 (9)
  • 飛行機 (26)
    • 成田 (9)
    • 国内 (6)
    • 海外 (13)
  • 自然散策 (1)
    • 鳥 (3)
  • 物欲 (1)
    • PC関連 (5)
    • カメラ (9)
  • 感想
    • テレビ (11)
    • 映画 (2)
    • 書籍 (1)
  • Web管理 (14)

アーカイブ

タグ

  • 天体
  • DHC-8
  • ANA
  • ship
  • B787
  • Test
  • ヘリコプター
  • F14
  • Korean Air
  • United Airlines
  • 成田空港
  • Qantas
  • A340
  • Air India
  • Air Canada
  • More

検索

このブログについて

  • 購読する このブログを購読
Powered by
Movable Type 4.25
  and
This site is powered by CMS Designer.
Creative Commons 2.1 by-nc copyright(c) 2002-2009 tawawa-s.com. some rights reserved.