天文屋のためのマイコン入門

2015年10月24日 (土)

「だれでも分かるマイコン入門」自動導入の実際

エリダヌスバブルの撮影ですっかり、間が開いてしまいました。自動導入の話を続けましょう。前回までに、LX200コマンドの説明が終わりました。ただLX200コマンドを理解しただけでは、まだ自動導入はできません。

実際にプログラムを作るとなると、難しい問題に直面します。たとえば、赤経座標で10°西に移動させることを考えましょう。

この場合、モーターを10°回せば良いだろうと考えると不十分です。日周運動のため、モーターが10°動いている間に、座標自体が西に回転してしまいます。

この問題を最もすっきり解決させる方法は速度の加算を使う方法です。たとえば導入速度を100倍とします。モーターを10°回転せるにはモーターを24秒間回せば良いのですが、24秒の日周運動分を加算しなければなりません。

そこで、実際には100倍ではなく101倍で回転させるのです。そうすると、日周運動の分も考慮されることになります。

この様子を図示すると以下のようになります。東に回転の場合は、もう説明するまでもないですね。

1510241
また、導入速度はいきなり100倍にするのではなく加速度的に速度を増していくと思います。このような場合でも常に+1した速度にしていけば問題ありません。

1510242

さて、これですべて解決というわけにはいきません。まだまだ考慮しなければならないことがあります。

ひとつは、回転を途中でキャンセルされた場合です。この場合でもキャンセルした位置の座標ををプログラムでしっかり把握しておかなければなりません。また、ホストからは常に現在の座標を返すようにコマンドが送られてきます。

したがって、プログラムは常にいま赤道儀が向いている方向の座標を計算し続けなればなりません。

具体的に言うと、先のグラフで、青い部分の面積が、座標上の位置の変化になります。(赤い部分を入れてはいけません)。つまりプログラムで一定間隔ごとに(たとえば10m秒ごと)青い部分の面積を計算していく必要があります。

正直、プログラミングの経験が少ない人の場合、上記プログラムを実装するのは難しいでしょう。しかし、モーターコントローラICの中には、座標の管理を自動でやってくれるものもあり、そのようなものを利用すれば、初心者でも簡単に実装することができます。

さて、実践編では上記のようなICを使って、実際にプログラムを組んでみましょう。お楽しみに。

| | コメント (0)

2015年10月10日 (土)

「誰でもわかるマイコン入門」LX200コマンドその3

それでは、LX200コマンドの残りを説明していきます。

:RC#
:RG#
:RM#
:RS#

これらのコマンドは導入速度を指定するコマンドです。このコマンド対する返答はいりません。具体的な速度の規定はありませんが、概ね次のような意味合いがあります。

:RC# センタリング用の速度ど移動(2番目に遅い)
:RG# ガイド用の速度で移動(一番遅い)
:RM# 導入用の速度で移動(2番目に早い)
:RS# 導入用の最高速度で移動(一番早い)

自動導入しか対応しないなら、これらのコマンドは無視してかまいません。オートガイドと自動導入に対応する、少なくとも2段階の速度に対応する必要があります。その場合はRC/RGはガイド用の速度に設定、RM/RSは自動導入用の速度にプログラムで設定する必要があります。

:Me#
:Mn#
:Ms#
:Mw#

これらのコマンドは、それぞれ東(Me)、北(Mn)、南(Ms)、西(Mw)に赤道儀を回転させる命令です。前回説明した:MS#コマンドは、赤道儀を目標天体まで回転させる命令でしたが、これらは、特に目標はなく、次に説明する停止コマンドを受け取るまで回転させます。

:Qe#
:Qn#
:Qs#
:Qw#
:Q#

これらは、前述した移動命令を停止させる命令です。最後のQは、すべての方向に対する停止命令です。
停止しているときにこれらの命令を受け取った場合や、たとえば西に移動しているときにQe命令を受け取った場合などの処理は仕様では規定されていないようなので、常識的な対応をすればよいと思います。

:U#

赤経赤緯座標の、高精度、低精度を切り替える命令です。高精度の場合は、

赤経 HH:MM:SS
赤緯  sDD*MM:SS

という書式になります。sは符号で+か-になります。低精度の場合は

赤経 HH:MM:T
赤緯 sDD*MM

となります。ここでTは1分の1/10になります。つまり6秒です。10秒でないので注意してください。高精度、低精度、どちらがデフォルトか、仕様からははっきりしません。

:SL~~~#

ホストからコントローラに時刻を設定するコマンドです。~~~の部分に時刻HH:MM:SSがきます。コントローラに時間を管理する機能がなければ、文字'1'を返して無視すればよいでしょう。

:GL#

このコマンドは、SLとは逆にホストに対して時刻をHH:MM:SSの形式で返してやります。コントローラがに時間を管理する機能がない場合は、適当な値を返すか、SLコマンドで受け取った文字列をそのまま返せばよいでしょう。

:SG~~~#
:GG#

ホストからコントローラにUTC時間に対する時差(日本の場合-9)をsHH.Hの形式で設定します。文字'1'を返して無視すればよいでしょう。GGは逆にコントローラからホストに返します。

:SS~~~#
:GS#

ホストからコントローラに地方恒星時をHH:MM:SSの形式で設定します。文字'1'を返して無視すればよいでしょう。GSは逆にコントローラからホストに返します。

:Sg~~~#
:Gg#

Sgはホストからコントローラに現在場所の東経をDDD:MMの形式で設定します。このコマンドを受け取ったら'1'を返します。Ggは逆です。

:St~~~#
:Gt#

Stはホストからコントローラに現在場所の北緯をsDD:MMの形式で設定します。sは北緯が+になる符号です。このコマンドを受け取ったら'1'を返します。Gtは逆です。

:GVP#

ホストからコントローラに製品名を問い合わせるコマンドです。適当な文字列を返してやればよいでしょう。

:GVF#

ホストからコントローラに製品のバージョンを問い合わせるコマンドです。適当な文字列を返してやればよいでしょう。

これらのコマンドに対応していれば、ほとんどの自動導入ソフトに対応できると思います。もちろん、ソフトによっては必要のないものもあります。実際にホストから受け取ったコマンドを表示させながら、対応していけばよいでしょう。

コマンドの説明はこれで終わりです。

次回は、自動導入アルゴリズムの大問題、モーター回転角の算出方法です。実はこれが難しい。

| | コメント (0)

2015年10月 4日 (日)

「誰でもわかるマイコン入門」LX200コマンドその2

LX200コマンド解説の2回目です。前回は、ホストからコントローラに現在の座標を問い合わせるコマンドを説明しました。

今日は、もうひとつ重要なコマンド、ホストからコントローラーに目標天体の座標を知らせるコマンドです。

座標を問い合わせるコマンドと目標天体の座標を知らせるコマンド、この2つのコマンドによって初めて自動導入が実現できます。

:Sr~~~#

このコマンドは、ターゲット天体の赤経座標をコントローラに送ります。書式はこのようになります。

:SrHH:MM:SS#

たとえば、赤経12h34m56sなら、

:Sr12:34:56#

となります。また低精度なら、次のような書式になります。

:SrHH:MM:T#

実際、プログラミングするときは、これらの文字列から数値に変換しなけれなりません。この時注意することは、ある程度柔軟性を持たせることです。たとえば、SrとHHの間に空白が入っていることを想定したり、区切り文字も':'コロンでないかもしれません。

いちおう、LX200コマンドでこれらの仕様は決まっていますが、ソフトによっては、かなり方言があり、きちきちに決めてしまうと、思わぬところでエラーが出てしまいます。

:Sr以降の文字列から角度に変換する関数を参考までに載せておきます。

=========================================================================
double GetLX200RaDegree(char *str)
{
int c;
int HH=0, MM=0, SS=0;
char buf[30];

while ((c = *str++) == ' ')
  ;
while (isdigit(c)) {
  HH = HH*10 + c - '0';
  c = *str++;
}
while (isdigit(c = *str++)) {
  MM = MM*10 + c - '0';
}
if (Lx200Preci == 0) {
  while (isdigit(c = *str++)) {
   SS = SS*10 + c - '0';
  }
}
else {
  if (isdigit(c = *str++)) {
   SS = 6*(c - '0');
  }
}
return 15.0 * HH + (15.0/60.0) * MM + (15.0/3600.0) * SS;
}
========================================================================

なお、コントローラはこのコマンドを正常に受け取ったなら、ホストに文字

"1"

を返してやります。

例 fputc('1', fp);

それでは、次に、赤緯の同様のコマンドを紹介します。

:Sd~~~#

書式は

:SdsDD*MM:SS

低精度は

:SdsDD*MM

ここでsは符号です。

たとえば、赤緯+12°34'56"は

:Sd+12*34*56

となります。

:Sd以降の文字列から角度に変換する関数は、

========================================================================
double GetLX200DecDegree(char *str)
{
int c;
int DD=0, MM=0, SS=0;
int sign = 1;
char buf[30];

while ((c = *str++) == ' ')
  ;
 
if (c == '+') {
  c = *str++;
}
else if (c == '-') {
  sign = -1;
  c = *str++;
}

while (isdigit(c)) {
  DD = DD*10 + c - '0';
  c = *str++;
}
while (isdigit(c = *str++)) {
  MM = MM*10 + c - '0';
}
if (c != # && c != 0) {
  while (isdigit(c = *str++)) {
   SS = SS*10 + c - '0';
  }
}
  return sign * ((double)DD + MM/60.0 + SS/3600.0);
}
=========================================================================

これも同様に正常にこのコマンドを受け取ったなら、ホストに'1'を返してやります。

fputc('1', fp);

さて、Sr/Sdコマンドはコントローラに対して、目標天体の座標を伝えるだけで、コントローラはこれだけでは何もしません。

次にホストから送られてくるコマンドが重要なのです。

:CM#

このコマンドは、同期のコマンドです。現在の座標を直近のSr/Sdコマンドで送られた座標に一致させます。

なお、このコマンドを受け取ったら、目標天体の名前を返しますが、名称はわからないので、次のように返してやります。

printf(fp, "Unkown name#");

:MS#

このコマンドは、望遠鏡も目標天体に向けるコマンドです。目標天体の座標は、直近のSr/Sdコマンドで送られた値です。

このコマンドを受け取ったら、文字'0'をホストに返してやります。

fputc('0', fp);

赤経座標の引き算

赤道儀を目標の座標に向けるには、赤経角度(RaDegree)、赤緯角度(DecDegree)について、目標座標から現在座標を引き算してやらなければなりません。

現在の角度を、(RaDegree, DecDegree)とします。目標天体の角度を(TarRaDegree, TarDecDegree)とします。

赤道儀を目標天体に向けるためには、以下の引き算をして回転角度を求めなければなりません。

TarRaDegree - RaDegree
TarDecDegree - DecDegree

ただ、ここで注意が必要です。赤緯角度は普通に引き算すれば良いのですが、赤経座標は注意が必要です。

それは、引き算結果を-180°から180°の間にしなければなりません。0°から360°ではだめです。なぜだめかは理由を考えてみてください。

TarRaDegree-RaDegreeの計算結果を-180°から180°の範囲にするための引き算関数を参考までに載せておきます。

=========================================================================
double RaSub(double ToDegree, double FromDegree) {
double diff = ToDegree - FromDegree;
double abs;
double sign;
if (diff >= 0) {
  abs = diff;
  sign = 1.0;
}
else {
  abs = -diff;
  sign = -1.0;
}
if (abs > 180.0) {
  return -1.0*sign*(360.0 - abs);
}
return diff;
}
=========================================================================

これで、赤経軸については、回転角度が計算できます。たとえば、10°という答えが得られたとします。しかし、モーターを10°回す間にも、星は動いていますから、その分も考慮しなければなりません。この問題についてはまたあとで、議論します。

さて、自動導入に最低限必要なコマンドを説明してきましたが、これだけでは、実際、自動導入ソフトと通信するとエラーが出ます。

最低限必要なコマンドをまだサポートしていないからです。

次回、最低限必要なコマンドを紹介します。

| | コメント (0)

2015年9月28日 (月)

「誰でもわかるマイコン入門」LX200コマンドその1

突然ですが、ブンブンさんのリクエストに答えて、「誰でもわかるマイコン入門」を一時復活し、LX200コマンドについて解説したいと思います。

LX200コマンドは、自動導入対応モータードライブを作るのに大切なコマンド体系です。これをマスターすれば、誰でも自動導入モータードライブが作れます。

前半は主にコマンドの説明、後半はmbedマイコンを使って、LX200コマンド解析機を作ってみたいと思います。

LX200コマンド自体は、テキストベースの簡単なコマンドで誰でも理解できます。しかし、実際に作ろうとすると、けっこう難しいところがあります。具体的には座標計算です。たとえば、赤経13hから12hに移動させる場合、1時間分なので、モーターを西に15度回転させればいいように思えますが、そう単純ではありません。モーターが動いている間にも星は動きますので、その分も考慮しなければなりません。そのへんの、実際に直面する問題にも解説をしていきます。

それでは、前置きはこのくらいにして、スタートです。

LX200コマンドとは
 LX200コマンドはミードの望遠鏡を制御するためのコマンド体系です。このコマンド体系は仕様が公表されていますので、これを真似すれば、ミードの望遠鏡に対応した自動導入ソフトを使って、自分のシステムも制御できるわけです。

 LX200コマンドは、RS232C通信(ボーレート9600bps)を使ってやり取りされます。RS232C通信はパソコンではすっかり影を潜めましたが、マイコンの世界では単純で分かりやすく、基本中の基本の通信方式となっています。

 またLX200コマンドはテキストベースなので、つまり文字列なので、画面に"Hello, World"を表示するような感覚でプログラミングができ、非常にわかりやすくなっています。マイコン入門の題材にしても良いくらいです。

 なお、LX200コマンドの正式な仕様書は、ぐぐれば、すぐ見つかるので、見ておいてください。

どんなコマンドがある?
 LX200コマンドにはさまざまなものがあります。自動導入に必要なもの以外にも、オートフォーカサーが使うコマンドや、時刻や場所に関するものなどさまざまです。すべてのコマンドに対応する必要はありません。どのコマンドに対応すればよいかは、自動導入ソフトによって異なりますが、だいたい相場は決まっています。

 したがって、本当に必要なコマンドのみ説明することとします。

ホストとコントローラ
 自動導入ソフトがのったパソコンをホストを言います。いっぽう、モータードライブの方をコントローラといいます。

 LX200コマンドは、ホストから、コントローラにコマンド(実際には文字列)を送ることによって成り立ちます。コマンドによっては、コントローラからホストに応答を返さないといけません。制御権はあくまでもホストの方にありますから、コントローラからホストの方へ何かを要求することはありません。一方向の命令体系です。

コマンドの実際
 それではどのようなコマンドがあるか見ていきましょう。

:GR#
 LX200コマンドはコロン(:)で始まり、シャープ(#)で終わるのが特徴です。大文字小文字は区別されます。このコマンドはもっとも基本的なコマンドで、ホストが、コントローラに対して、現在の赤経座標を知らせてくれという要求コマンドです。

 したがって、コントローラはこのコマンドを受け取ったら、次のような文字列を返してやる必要があります。

 12:34:56#

 この例では、赤経12時34分56秒です。一般に次のような書式で文字列を返してやります。

 HH:MM:SS#

 なお、LX200コマンドでは低精度の座標もサポートしていて、低精度の座標では

 HH:MM.T#

 Tは、分の1/10になります。したがって、先ほどの12時34分56秒を低精度で表せば、

 12:34.9#

 となります。多くの自動導入ソフトに対応させるには、両方の書式に対応しておくのが望ましいです。

:GD#
 このコマンドは、GRと同じく、現在の赤緯を返すコマンドです。たとえば赤緯12度34分56秒なら

 +12*34'56#

となります。書式は次のようになります。

 sDD*MM:SS#

sは符号で+か-です。赤道より北が+になるような座標です。南の場合はマイナスになります。

 低精度の場合は次のような書式になります。

 sDD*MM#

 SSの部分がありません。

 GR,GDコマンドの例でも分かるように、座標を管理するのはホスト側ではなく、コントローラ側になります。これはコントローラ側の負担の方が大きいことを意味します。

 コントローラ側では座標は一周360度の角度で保存しておいた方が便利です。そして必要に応じて、赤経、赤緯の座標に直すようにします。

プログラム例

 赤経軸の子午線からの角度をRaDegreeとします。(0~360度)、赤緯軸の赤道からの角度をDecDegreeとします。(-90度~+90度)

赤経座標への変換(コピペしてね)
=========================================================================
   if (!strcmp(CommandBuffer, ":GR#")) {
    int HH, MM, SS;
    double d;
    d = RaDegree;
    if (d >= 360.0) {
     d -= 360.0;
    }
    else if (d < 0) {
     d += 360.0;
    }
    if (d >= 360.0 || d < 0) {
     d = 180.0;
    }
    HH = d/15.0;
    d = d - 15.0*HH;
    MM = d*(60.0/15.0);
    d = d - MM/4.0;
    SS = d*(60.0*60.0/15.0);
    if (Lx200Preci == 0) { //精度
     printf("%02d:%02d:%02d#", HH, MM, SS);
    }
    else {
     printf("%02d:%02d.%01d#", HH, MM, SS/6);
    }
   }
==========================================================================

赤緯座標への変換
==========================================================================
   else if (!strcmp(CommandBuffer, ":GD#")) {
    int sign, DD, MM, SS;
    double d = DecBaseDegree;

    if (d >=0) {
     sign = '+';
    }
    else{
     sign = '-';
     d = -d;
    }
    DD = d;
    d = d - DD;
    MM = d*60.0;
    d = d - MM/60.0;
    SS = d*60.0*60.0;
     if (Lx200Preci == 0) {
      printf( "%c%02d*%02d\'%02d#", sign, DD, MM, SS);
     }
     else {
      printf("%c%02d*%02d#", sign, DD, MM);
     }
   }
==========================================================================

GR/GDコマンドはホストから頻繁に送られてきます。200msに一回とか、そのような頻度です。自動導入で、GOTO命令を発行すると、カーソルが目標に向かって動きますが、それはコントローラ側のこのような計算によるものです。

座標の更新
 コントローラが保持している天球上の角度(RaDegree、DecDegree)は、当然ですが、モータを動かせば値を更新しなければなりません。

 RaDegreeとDecDegreeの値をどのような方法で更新するかは、モータードライブシステムによって異なります。

 一番、正確な方法は、エンコーダー入力です。モーターがどれだけ回ったかではなく、実際にどれだけ赤道儀が動いたかを計測するのがエンコーダーです。赤道儀の手動にも対応できます。

 ただ、エンコーダー搭載の赤道儀はそうそうあるものではありません。自作となると、負担が大きいです。

 もう一つの方法はパルスを計測する方法です。モーターにどれだけパルスを送ったかを常に数えているのです。パルスモーターは回転角は正確にパルス数に比例しますので、パルスを計測すればモーターの回転角が分かります。
 マイコンによっては、1パルス送るごとに割り込みが入るものもありますので、そのような割り込みを使ってパルスを計測します。

 最後の方法は、時間を計測する方法です。モーターの回転速度(恒星時とか100倍とか)と動作時間が分かれば、そこから角度が計算できるはずです。

 たとえば、1秒ごとにかかるタイマー割り込みの中で、 モーターの速度を対恒星時でV倍とすると、

  RaDegree += (15.0/3600.0)*(V-1);

 となります。Vは日周運動と同じ方向は+、逆は-になります。-1してあるのは日周運動分をキャンセルするためです。

 この方法はあまり正確ではなく誤差も蓄積しますが、プログラム的には一番簡単な方法になります。

ちょっと長くなったので、今日はここまで。

 

 

| | コメント (5)

2015年4月 6日 (月)

「理想ポタ赤を作る」昨晩もテスト撮影

昨晩もちょっと晴れたのでテスト撮影に、、近所の空き地に行きました。

今回はちゃんと極軸望遠鏡のセンター出しをして、ギアの調整を固めで望みました。

ノータッチでどこまで撮れるかテストしました。筒はいつもどおりFS-60CBフラットナーです。

結果は。

Img_8444
露出3分ですが、やはり流れています。ただ、まぁ予想通りです。横方向のずれが、極軸のずれで、縦方向のずれはピリオディクモーションです。PMのずれは、撮影コマによって上にずれたり、下にずれてたり、ずれなかったり周期的に変わるので、間違えありません。PMはこんなもんです。

問題は極軸のずれです。ちゃんとセンター出ししてもこれだけずれます。(望遠鏡を向けた方向は極軸のずれが出やすい東方向)もっと追い込まないとだめですね。

まぁ焦点距離400mm近いですからね。しょうがないです。長焦点のノータッチがいかに難しいかわかると思います。

新しいポタ赤を出すというのに、星が流れた写真ばかしですみません。ただ、この「理想のポタ赤」は背伸びをしない赤道儀ということです。現実を直視した赤道儀というか。

明日晩は、私にとっては週末なので、寒冷地テストも含めて、八千穂高原に遠征に行こうと思います。ちょっと晴れそうです。

今度は、オートガイドのテストをしてきます。

| | コメント (0)

2015年2月17日 (火)

「誰でもわかるマイコン入門」文字列の切り分け

さて、前回はGPSから文字列データを受信して表示するところまでできました。

今日はこのデータを解析します。GPSモジュールから送られてくる文字列データは一般に、NMEAフォーマットです。このフォーマットの詳しい解説は

http://www.hiramine.com/physicalcomputing/general/gps_nmeaformat.html

などを参照してください。この文字列フォーマットを解析する便利なライブラリはたくさん出回っているのですが、いつも人さまの部品を利用していては勉強にならないので、今回は自前で作ってみます。

というのは、文字列の解析というのはプログラミングの基本中の基本です。これをマスターしないとプログラミングを勉強したことになりません。

それでは始めましょう。

まず、前回までにGpsInputという配列にNMEAフォーマットの文字列を格納しました。NMEAフォーマットはいくつかのパターンがあるのですが、先頭が$GPRMCというものだけを抽出すれば、日時、時刻、経度、緯度のすべてのデータが得られます。

そこで文字列の先頭6文字を比較して、それが$GPRMACに等しいときだけ、処理をするようにします。その時使う便利な命令が

strcmp(A, B)

これは文字列AとBを比較して等しいなら0の値を持ちます。このように値を持つ命令を関数と呼びます。ただし、例外的に値を持たない関数も存在します。

さて、この比較関数ですが、これは文字列全部を比較します。先頭のn文字だけ比較するには次の関数を使います。

strncmp(A, B, n)

したがって、先頭が$GPRMCに等しい場合だけ処理させるには、次のように記述します。

if (strncmp(GpsInput, "$GPRMC, 6) == 0) {

  ここに処理を書く

}

さて、これで$GPRMCだけ抽出することができます。$GPRMCのデータフォーマットを見るとデータがカンマ(,)で区切られていることがわかります。

したがって、次の課題は、このカンマで区切れた文字列を小分けにして、次の10個の配列に収めることです。

            char item1[20];
            char item2[20];
            char item3[20];
            char item4[20];
            char item5[20];
            char item6[20];
            char item7[20];
            char item8[20];
            char item9[20];
            char item10[20];

1502171ちょっと難しい話が続くので今日はここまで。

| | コメント (0)

2015年2月 9日 (月)

「誰でもわかるマイコン入門」GPSを付ける

前回までにグラフィック液晶を付けました。これだけでは面白くないので、今日はGPSモジュールを付けてみましょう。

使ったGPSモジュールは、またまたアイテンドーで、これ

http://www.aitendo.com/product/1007

早速、マイコンとつなげてみますが、ここでワンポイント知識。GPSモジュールはシリアル通信で通信します。パソコンなどのRS232Cと同じです。ただパソコンのRS232Cは電圧を上げていますが、これは3.3Vのままです。あまり距離を長くできません。また電圧が低い場合はRS232Cとは言いませんが、規格自体はRS232Cと同じです。

RS232Cは、送信(TX)と受信(RX)の2本の信号線で通信します。あとGNDを入れて計3本です。ただGPSモジュールは一方的にデータを送ってくるので、GPSモジュールか見て送信(TX)、(マイコン側から見れば受信(RX))の一本の線をつなげばOKです。それに電源が2本なので、計3本の配線が必要です。

それでは配線しましょう。こんな感じ。

1502091
手前黒い線がGND、赤い線が3.3V、青い線が(GPSから見れば)送信(TX)です。青い線はマイコンのP27につなぎます。

1502092

また、GPSモジュールの裏側はこのように配線してください。

1502093
配線がすんだら、プログラムです。プログラムは前回の液晶のデモプログラムを改造する形で行います。demo.cppをいったん白紙にし、次のようなプログラムを記述します。

-----------------------------------------------------------
#include "mbed.h"
#include "ILI9340_Driver.h"

Serial gps(p28, p27);

int main() {

    // create the display object
    ILI9340_Display tft = ILI9340_Display(p5, p6, p7, p24, p25, p26);

    // initialise the display
    tft.DispInit();
   
    gps.baud(4800);
    char GpsInput[256];

    while (1) {
        gps.gets(GpsInput, 255);
        tft.FillScreen(ILI9340_WHITE);
        tft.DrawString(GpsInput, 0, 100, 1, ILI9340_BLUE);
    }
}
------------------------------------------------------------

液晶以外の部分だけ説明しましょう。

Serial gps(p28, p27);
p28、p27をシリアル通信で使う。名前をgpsと名づける。p28は実際には使いません。また順番に注意してください。gps(p27, p28)と書いたらだめです。

gps.baud(4800);
シリアル通信のボーレートを4800に設定しています。

char GpsInput[256];
前回、変数というものを説明しました。これは連続した番地をもつ256個の変数を定義しています。配列といいます。文字列(文字の並び)を格納するために使われます。文字列は最後のデータが0でないといけないので、それを除外して255文字ま格納できます。

gps.gets(GpsInput, 255);
GPSから送られてくる文字列のデータを受信します。255というのは最大255文字です。受信した文字列は先ほどの配列に格納します。

tft.FillScreen(ILI9340_WHITE);
液晶に文字列を表示する前に、前の文字列をクリアするため、いったん全画面を白に塗りつぶします。

tft.DrawString(GpsInput, 0, 100, 1, ILI9340_BLUE);
受信した文字列を液晶に表示します。

さて、このプログラムをコンパイルして実行すると、液晶にチカチカ文字を表示されます。こうなれば正常です。

1502094
まだ、この文字列はなんのことかわかりませんね。次回はこの文字列を解析して、日付、時間、北緯、経度などを表示させてみます。それでは。

| | コメント (0)

2015年2月 2日 (月)

「誰でもわかるマイコン入門」グラフィックLCDを付ける

今日から、応用編です。

そろそろ何か表示器を付けたくなってきました。そこで、TFTカラーグラフィックLCDを付けてみます。

これです。2.2インチの小さいやつ。

1502021
買ったのは、アイテンドーというところ。

http://www.aitendo.com/product/7277

今日現在、在庫14個しかありません。早めに買っておいた方がいいかも。もしなくなったら、私がまとめて中国から購入しておきますので、コメント欄から問い合わせてみてください。

さて、早速、配線です。数が多いので、ちょっと大変ですが、間違わないように。結線表を書いておきます。

mbed---LCD
-----------------
GND --- GND
P5 --- SDI/MOSI
P6 --- SDO/MISO
P7 --- SCK
VOUT --- LED and VCC
P26 --- DC/RS
P25 --- RESET
P24 --- CS

1502022
それから、LCDの基板の裏側J1と書かれた部分(写真の青丸)を半田をもってショートさせてください。

1502023
これで完成です。

次に、プログラムですが、本来ならグラフィックLCDのプログラムは大変なのですが、ここがmbedの良いところ、他人のプログラムを簡単に拝借できちゃいます。

この方のプログラムを頂きます。

1502024
http://developer.mbed.org/users/dextorslabs/code/ILI9340_Driver/

画面右上の[Import Program]をクリックすれば、自分のページに取り込みます。取り込んだら、Demo.cppを開いてください。これがプログラムの一部です。

コンパイルして、mbedに保存し、リセットすれば動きまっす。簡単!!

1502025
さて、これを利用していろいろ作ってみましょう。

| | コメント (0)

2015年1月31日 (土)

「誰でもわかるマイコン入門」時間差シャッター分配器

さて、前回は、簡単なインターバルタイマーを作成しました。今日は、本来の目的であるシャッター分配器で改造します。まずシャッター入力用のコネクタを追加します。

1501311
一方をP5に、もう一方を3.3V Regulated Outにつなげます。これで、シャッターONのとき、マイコンに1が入力されます。

プログラムは以下にアップしました。

http://developer.mbed.org/users/Honmaka/code/IntervalShutter3/

プログラム解説です。

DigitalOut Camera1(p30);
p30をデジタル出力として使う、名前をCamera1と名づける

DigitalOut Camera2(p29);
p29をデジタル出力として使う、名前をCamera2と名づける
 
 
 

DigitalIn  Input(p5);
p5をデジタル入力として使う、名前をInputと名づける

int main() {
    Input.mode(PullDown);
Inputをプルダウンする(0Vにつなげる)これにスイッチが解放の場合、0になる

    int PreInput = 0;
整数型の変数をメモリからもらいPreInputと名づける。そして0に初期化する。

ここで変数という新しい概念が出てきました。プログラムでは入力したデータや計算したデータを保存したいことがよくあります。そのときメモリ領域からもらうメモリを変数といいます。変数の名前はプログラマが自由に付けられます。intは整数型を表します。他には小数点型のfloatなどもあります。また上記のようにある値で初期化することもできます。

PreInputという変数ですが、これは、定期的にスイッチの状態を入力するのですが、一回前の入力を保存しておくために使用します。なぜ、前の状態を保存するかと言うと、スイッチの変化を感知したいからです。

    int NowInput;
整数型の変数をメモリからもらいNowInputと名づける。NowInputが前回ではなく現在のスイッチ状態を保存しておきます。

    Camera1 = 0;
カメラ1のシャッターをOFFにします。

    Camera2 = 0;
カメラ2のシャッターをOFFにします。

    while(1) {
無限ループ繰り返し

        NowInput = Input;
スイッチの状態を入力します。

        if (NowInput != PreInput) {
もし、スイッチが前回とい違うならつまりOFF->ON、またはON->OFFなら次の処理をします。

            Camera1 = NowInput;
カメラ1のシャッターをONまたはOFFします。

            wait(1);
1秒待ちます。(時間差シャッター)

            Camera2 = NowInput;
カメラ2のシャッターをONまたはOFFします。

        }
if条件文はここで終わり

       PreInput = NowInput;
現在のスイッチの状態をPreInputに保存、次回のif条件判定で利用する
       

wait(0.1);
0.1秒まつ。あまり頻繁にスイッチの状態を連続して読み込みすると、スイッチの状態が変化したときのバタツキ(ON/OFFを頻繁に繰り返すこと)まで読み込んでしまうため、0.1秒間隔でスイッチの状態を読み込めば十分。
    }
}

さて、次回からは応用編に入ります。手始めにTFT液晶をつけてみます。お楽しみに。

| | コメント (0)

2015年1月29日 (木)

「誰でもわかるマイコン入門」フォトMOSリレーをマイコンで操作

前回、フォトMOSリレーを手動で作動させ、シャッターを切りました。

今日は、マイコンでシャッターを切ってみましょう。ということで、今日は簡単なインターバルシャッターを作ってみます。インターバル3秒、露出を1分を永遠に繰り返すという簡単な構成です。

まずは、ハードから、

1501274_2
フォトMOSリレーの1番ピンをマイコンのP30とP29に写真のようにつなぎます。そして2番ピンをGNDにつなげば、完成です。

プログラムは以下にアップしますが、説明の必要がないくらい簡単です。

http://developer.mbed.org/users/Honmaka/code/IntervalShutter/

次回はいよいよシャッター分配器です。それでは。

| | コメント (0)

より以前の記事一覧