2011年3月23日水曜日

LEDバーサライタ続き

前回の続きです。

予想だにしない問題というのは、
「文字を選択できるようにするなら、どの文字を選択しているか解らなければならない」
ということ。

当たり前っちゃ当たり前ですね(笑)

フルLEDボードなら見ながら変更できますけど、バーサライタ(英語ではpersistence of visionと言うらしい)は
振らないと文字を表現できないので、どの文字を選択しているかは振ってみるまで解りません。

さすがにこれはダメだろ…。ということで文字選択は出来ないようにするかも。
その場合、簡単に書き換えが出きるようにICソケットか何かで着脱を簡単にしておこうかと思います。

文字選択を実装するならLCDとかで表示用のシステムを作らなければいけないし…。
ちょっと技術的にきついかなー。まだ2つ以上のマイコン同士の通信は出来ないので。
ポートが足りない…(´д`)

というわけでまずは概観から。


まだ割り込み関連を理解していないため、表示素子だけになっております。
前回バーサライタのLED増やしただけバージョンですね。

ここからたぶん4ピン(PD2)を使用しない方向で修正すると思うので
主にPORTCとPORTBで構成されることになるかと思います。
(割り込み処理がPD2を使う関係でPORTDが制限される)


割り込み処理とは、プログラムの実行中に割り込みの条件が起こることによって
一旦、そのプログラムを中断して割り込みプログラムを優先的に実行するシステムです。

AVRなどのマイコンは割り込み処理が定義されていて、
それにしたがって記述するだけで割り込み処理が実現できます。
(といってもこれがなかなか資料が無くて…^^;)

この割り込み処理でボタンを押している間はLEDの表示順序を反対にする
(双方向で表示が出来る)ようになり(し)ます。


まだプログラムも実験段階でとりあえず関数ポインタが使えるようになったくらいなので
実装は4月上旬かなー(遅い)。

それにしてもPD2を割り込みに使うとなるとプログラムの書き換えが面倒そうだな…。

そんな感じで再評価版も準備を始めています。
当たらしい物も何か作りたい…。でもアイデアが…orz。

だれかメンバー募集(ぇ
いや結構マジで

2011年3月20日日曜日

LEDバーサライタ再評価

前回のバーサライタでは、

・一方にしか文字が表示できない
・文字をあらかじめ決めておかなければならない
・文字が小さいので遠くから読みづらい
(バーサライタは遠くからの方がよく見えると感じたので)


などの問題があると感じました。
今回はそれをできるだけ改善する方向でいきたいと思っています。

まずは表示方法。
前回はLEDを縦に1列9個でしたが、今回は18個と倍に増やすつもりです。

5mmLEDを使っているので9個だと感覚1mmでも、
(5+1)*9=54mm
なのでたいした大きさではありませんでしたが、
倍に増やすことで表示サイズを108mmまで大きくすることができます。

108mmというとかなり遠くからも見えると思うので、大きいだけで暗くならないように
LEDも赤色に変えることにします。
最近手に入ったから使ってみようと思っただけなのは内緒。


大きくなったからと言って文字を書き換えるのも面倒なので出力はひとつでいきます。
つまり従来と同じ9ピンで18個を点灯させる予定です。

ここで問題になってくるのがマイコンからの出力可能電流で、
AVRの情報みてないですけどPICが±20mAらしいので同等かなーと。

今回LEDを10mA程度で使おうと思っているので、ちょっとオーバー気味かなと思い、
トランジスタを使うことにします。みんな大好き2SC1815!
まだ評価してないですけど、どうせスイッチング動作なので
あんまり気にしないでいいかなーと。(甘い?)


その次にプログラムのスケッチ(と言うと用語的には間違っているかも)。
いうなればアルゴリズムテスト用プログラムです。

今回は動的に表示するのが目標なのでそこを重点的に。

どうやら「関数ポインタ」とかいうので処理できるようです。
関数ポインタは関数に対するポインタでありアドレスを指し示し~なんて言っても
解る人には解るし、解らない人には解りません。

まあ今までのだと関数名(aとかbとか)を直接記入しないといけない
(=書き込み機で書き換えなければいけない)でしたが、関数ポインタを使うことで
関数をポインタの中に格納できます。(=プログラム中で選択できる)


たとえばA_writeという関数があったとして、
これを使用するには
A_write();
と記入する他ありませんでしたが、ポインタに入れると、
int (*pointer_name)();
pointer_name = A_write;
となり、呼び出しは
(*pointer_name)();
となります。カッコで囲んで先頭にアスタリスクです。

これだけだとあまりメリットは感じられませんが、真の使い道は配列にしてからだと思います。

同じく、関数A_writeとB_writeがあったとして、これを呼び出すならば、
A_write();
B_write();
となります。ちょっとC言語をさわったことがある人なら想像つくと思いますが、
これを例えばB_write→A_writeとしたいならば、一度プログラムを書き換えるしかありません。
実行中に選択するならばifとかforとかを使ってループさせれば実現出来ますが、
さらにCとかDとか増えてくるとifが増えてきたりともう大変なことになってきます。

上記を関数ポインタの配列として使うと、
int (*pointer_name[2])();
pointer_name[0] = A_write;
pointer_name[1] = B_write;
となります。呼び出しはもちろん、
(*pointer_name[0])();
(*pointer_name[1])();
となります。

こうするとちょっとメリットが見えてきました。
pointer_nameの配列番号を自由にいじることでfor 0 to 1やfor 1 to 0で
上からだったり下からだったり自由に選択出来ます。

こんな感じで今回はバーサライタに文字の選択を追加しようと思います。
しかしここで予想だにしない問題が!!!
続きます。

2011年3月19日土曜日

東北地方太平洋沖地震

前回の記事を投稿した当日、2011年3月11日金曜日にご存知のとおり地震が発生しました。
幸運なことに滋賀県在住のため被害などはありませんでしたが、
地震による災害は多くの生命を奪っていきました。

この件について多くのデマやチェーンメールが流され、
無為に不安を煽るような事がなされたことは遺憾です。

インターネットはもちろん民放や新聞でさえも多くの誤った情報が流されていると感じます。
どうか誤った情報に流されること無く、情報をよく吟味して、
正しい情報であろうと無作為に拡散することなく、口頭で伝えるなどの手段を取ってほしいと思います。

口頭で伝えることによって、現在の情報の真偽を疑うことができます。

地震により被害を受けていない人々が情報の撹乱により被害を大きくすることを人災と呼びます。
実害を受けた東北地方の方々のためにも落ち着いた行動をし、
現在、支援作業にあたっている方が全力で作業出来るように配慮してほしいと願います。

2011年3月11日金曜日

bloggerテンプレート

やっぱりhtml/css/javascriptとかが少しわかってくると
次にやりたいのはテンプレートの作成ですよね。

でもbloggerの新テンプレートだと環境変数等がフクザツで解りにくいので、
旧テンプでテストしてみました。

テスト用のブログ

元のテンプはRoundersです。作成者はblogger(公式)。


こういうブログ系列は扱ったことがないので変数がまったくあぼんでした。
あと、普段はちょっとcssとか齧るくらいなのでstyleの指定って
divでしかほとんどしないんですよね。
でもこのような場合は主にclass分け、id指定が絡んでくるのでかなりの難関でした。
テンプ作ってる人って結構すごいんだと実感(笑)


もとのテンプと比較すればわかるように
・全体の幅の拡大
・タイトルの背景色と文字色の変更
・好みでなかったちょっとしたデザイン(ドット線とか)の変更
・全体のレイアウトの調整
に手を加えました。


一番の難題はコメントフォームの属性が用意されていなくて、
自分で新たに作成しなくてはならなかったこと。

もともとある属性をいじるだけなら簡単だったんですけど、
属性の追加となるとちゃんとわかっていないと出来ないんですよね…。
マークアップ言語舐めてました。プログラミング言語とは違った難しさ。
オブジェクト指向(?)な雰囲気あるよね。たぶん。


横枠が不振な位置にあるのは仕様です。
あの部分は画像なんだけど特に新しいの作るわけでもなく横幅を増やしたので
画像が足りてないんですね。
これは全部のレイアウトが決まってからのお話。

あとはガジェットの追加とか、不必要な部分の排除をすればプロトタイプは完成かな。
それから「同日に投稿された記事が繋がらないように」なれば完璧なんだけどなぁ。

なかなか上手くいきません。
以上。

2011年3月9日水曜日

javascript test2


ボタンを押すことによってリンク先が変化する。

javascript test



javascriptがbloggerで使えるかどうかのテスト。
CSSのdisplay:blockやjavascriptのgetElementByIdも
問題なく使えるようです。

2011年3月7日月曜日

module9


Option Explicit

Sub kuroban()
    Range("K2").Select
    ActiveCell.FormulaR1C1 = "黒"
    Range("K3").Select
    ActiveCell.FormulaR1C1 = "の"
    Range("K4").Select
    ActiveCell.FormulaR1C1 = "番"
    Range("K5").Select
    ActiveCell.FormulaR1C1 = "で"
    Range("K6").Select
    ActiveCell.FormulaR1C1 = "す"
End Sub
Sub siroban()
Range("K2").Select
    ActiveCell.FormulaR1C1 = "白"
    Range("K3").Select
    ActiveCell.FormulaR1C1 = "の"
    Range("K4").Select
    ActiveCell.FormulaR1C1 = "番"
    Range("K5").Select
    ActiveCell.FormulaR1C1 = "で"
    Range("K6").Select
    ActiveCell.FormulaR1C1 = "す"
End Sub

Sub okiba(okiba As Integer)
Dim n As Integer, m As Integer
okiba = 0
For n = 2 To 9
For m = 2 To 9
If Sheet1.Cells(n, m).Interior.Color = RGB(0, 255, 0) Then
okiba = okiba + 1
End If
Next m
Next n
End Sub

module6


Option Explicit

Sub Macro()
'
' Macro Macro
'

'
    Range("A1:J10").Select
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Range("B2").Select
    ActiveCell.FormulaR1C1 = "1,1"
    Range("C2").Select
    ActiveCell.FormulaR1C1 = "1,2"
    Range("D2").Select
    ActiveCell.FormulaR1C1 = "1,3"
    Range("E2").Select
    ActiveCell.FormulaR1C1 = "1,4"
    Range("F2").Select
    ActiveCell.FormulaR1C1 = "1,5"
    Range("G2").Select
    ActiveCell.FormulaR1C1 = "1,6"
    Range("H2").Select
    ActiveCell.FormulaR1C1 = "1,7"
    Range("I2").Select
    ActiveCell.FormulaR1C1 = "1,8"
    Range("B3").Select
    ActiveCell.FormulaR1C1 = "2,1"
    Range("C3").Select
    ActiveCell.FormulaR1C1 = "2,2"
    Range("D3").Select
    ActiveCell.FormulaR1C1 = "2,3"
    Range("E3").Select
    ActiveCell.FormulaR1C1 = "2,4"
    Range("F3").Select
    ActiveCell.FormulaR1C1 = "2,5"
    Range("G3").Select
    ActiveCell.FormulaR1C1 = "2,6"
    Range("H3").Select
    ActiveCell.FormulaR1C1 = "2,7"
    Range("I3").Select
    ActiveCell.FormulaR1C1 = "2,8"
    Range("B4").Select
    ActiveCell.FormulaR1C1 = "3,1"
    Range("C4").Select
    ActiveCell.FormulaR1C1 = "3,2"
    Range("D4").Select
    ActiveCell.FormulaR1C1 = "3,3"
    Range("E4").Select
    ActiveCell.FormulaR1C1 = "3,4"
    Range("F4").Select
    ActiveCell.FormulaR1C1 = "3,5"
    Range("G4").Select
    ActiveCell.FormulaR1C1 = "3,6"
    Range("H4").Select
    ActiveCell.FormulaR1C1 = "3,7"
    Range("I4").Select
    ActiveCell.FormulaR1C1 = "3,8"
    Range("B5").Select
    ActiveCell.FormulaR1C1 = "4,1"
    Range("C5").Select
    ActiveCell.FormulaR1C1 = "4,2"
    Range("D5").Select
    ActiveCell.FormulaR1C1 = "4,3"
    Range("E5").Select
    ActiveCell.FormulaR1C1 = "4,4"
    Range("F5").Select
    ActiveCell.FormulaR1C1 = "4,5"
    Range("G5").Select
    ActiveCell.FormulaR1C1 = "4,6"
    Range("H5").Select
    ActiveCell.FormulaR1C1 = "4,7"
    Range("I5").Select
    ActiveCell.FormulaR1C1 = "4,8"
    Range("B6").Select
    ActiveCell.FormulaR1C1 = "5,1"
    Range("C6").Select
    ActiveCell.FormulaR1C1 = "5,2"
    Range("D6").Select
    ActiveCell.FormulaR1C1 = "5,3"
    Range("E6").Select
    ActiveCell.FormulaR1C1 = "5,4"
    Range("F6").Select
    ActiveCell.FormulaR1C1 = "5,5"
    Range("G6").Select
    ActiveCell.FormulaR1C1 = "5,6"
    Range("H6").Select
    ActiveCell.FormulaR1C1 = "5,7"
    Range("I6").Select
    ActiveCell.FormulaR1C1 = "5,8"
    Range("B7").Select
    ActiveCell.FormulaR1C1 = "6,1"
    Range("C7").Select
    ActiveCell.FormulaR1C1 = "6,2"
    Range("D7").Select
    ActiveCell.FormulaR1C1 = "6,3"
    Range("E7").Select
    ActiveCell.FormulaR1C1 = "6,4"
    Range("F7").Select
    ActiveCell.FormulaR1C1 = "6,5"
    Range("G7").Select
    ActiveCell.FormulaR1C1 = "6,6"
    Range("H7").Select
    ActiveCell.FormulaR1C1 = "6,7"
    Range("I7").Select
    ActiveCell.FormulaR1C1 = "6,8"
    Range("B8").Select
    ActiveCell.FormulaR1C1 = "7,1"
    Range("C8").Select
    ActiveCell.FormulaR1C1 = "7,2"
    Range("D8").Select
    ActiveCell.FormulaR1C1 = "7,3"
    Range("E8").Select
    ActiveCell.FormulaR1C1 = "7,4"
    Range("F8").Select
    ActiveCell.FormulaR1C1 = "7,5"
    Range("G8").Select
    ActiveCell.FormulaR1C1 = "7,6"
    Range("H8").Select
    ActiveCell.FormulaR1C1 = "7,7"
    Range("I8").Select
    ActiveCell.FormulaR1C1 = "7,8"
    Range("B9").Select
    ActiveCell.FormulaR1C1 = "8,1"
    Range("C9").Select
    ActiveCell.FormulaR1C1 = "8,2"
    Range("D9").Select
    ActiveCell.FormulaR1C1 = "8,3"
    Range("E9").Select
    ActiveCell.FormulaR1C1 = "8,4"
    Range("F9").Select
    ActiveCell.FormulaR1C1 = "8,5"
    Range("G9").Select
    ActiveCell.FormulaR1C1 = "8,6"
    Range("H9").Select
    ActiveCell.FormulaR1C1 = "8,7"
    Range("I9").Select
    ActiveCell.FormulaR1C1 = "8,8"
    Range("B2:I9").Select
    With Selection.Font
        .Color = -16776961
        .TintAndShade = 0
    End With
End Sub

module5


Option Explicit

Sub white_hidariue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx - 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx + n, yy + n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub
Sub white_ue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx + n, yy).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_migiue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx - 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx + n, yy - n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_hidari(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 0
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx - 0
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx, yy + n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_migi(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 0
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx - 0
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx, yy - n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_hidarisita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx - n, yy + n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_sita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy - 0
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy - 0
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx - n, yy).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub white_migisita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
        For n = 1 To cnt
            .Cells(xx - n, yy - n).Interior.Color = RGB(255, 255, 255)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub


module4


Option Explicit

Sub search_for_black(x As Integer, y As Integer, handan As Integer)
black_hidariue x, y, handan
black_ue x, y, handan
black_migiue x, y, handan
black_hidari x, y, handan
black_migi x, y, handan
black_hidarisita x, y, handan
black_sita x, y, handan
black_migisita x, y, handan
End Sub

Sub search_for_white(x As Integer, y As Integer, handan As Integer)
white_hidariue x, y, handan
white_ue x, y, handan
white_migiue x, y, handan
white_hidari x, y, handan
white_migi x, y, handan
white_hidarisita x, y, handan
white_sita x, y, handan
white_migisita x, y, handan
End Sub

module3


Option Explicit
Sub Macro()
'
' Macro1 Macro
'

'
    Columns("A:J").Select
    Selection.ColumnWidth = 3.13
    Rows("1:10").Select
    Selection.RowHeight = 22.5
    Range("B2:I9").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .Color = -16776961
        .TintAndShade = 0
        .Weight = xlThin
    End With
    Range("B1").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("C1").Select
    ActiveCell.FormulaR1C1 = "2"
    Range("B1:C1").Select
    Selection.AutoFill Destination:=Range("B1:I1"), Type:=xlFillDefault
    Range("B1:I1").Select
    Range("A2").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("A3").Select
    ActiveCell.FormulaR1C1 = "2"
    Range("A2:A3").Select
    Selection.AutoFill Destination:=Range("A2:A9"), Type:=xlFillDefault
    Range("a1").Select

End Sub
Sub Macro3()
'
' Macro3 Macro
'

'
    Cells.Select
    Selection.Delete Shift:=xlUp
End Sub
Sub Macro4()
'
' Macro4 Macro
'

'
    Range("A1:J1,J1:J10,A10:J10,A1:A10").Select
    Range("A10").Activate
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = -16776961
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

module2


Option Explicit

Sub black_hidariue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx - 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx + n, yy + n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub
Sub black_ue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx + n, yy).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_migiue(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx - 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx + n, yy - n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_hidari(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 0
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx - 0
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx, yy + n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_migi(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx - 0
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx - 0
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx, yy - n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_hidarisita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy - 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx - n, yy + n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_sita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy - 0
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy - 0
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx - n, yy).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

Sub black_migisita(x As Integer, y As Integer, handan As Integer)
Dim xx As Integer, yy As Integer, cnt As Integer, n As Integer
xx = x
yy = y
With Sheet1
cnt = 0
xx = xx + 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
cnt = cnt + 1
mark:
xx = xx + 1
yy = yy + 1
If .Cells(xx, yy).Interior.Color = RGB(255, 255, 255) Then
    cnt = cnt + 1
    GoTo mark
ElseIf .Cells(xx, yy).Interior.Color = RGB(0, 0, 0) Then
        For n = 1 To cnt
            .Cells(xx - n, yy - n).Interior.Color = RGB(0, 0, 0)
        Next n
        handan = handan + 1
    End If
End If
End With
End Sub

module1


Option Explicit
Sub othello() 'メイン関数
Dim x As Integer, bpass As Integer, wpass As Integer
Dim n As Integer, m As Integer, bcount As Integer, wcount As Integer, okiba As Integer
Module3.Macro3
start
Module3.Macro
Module6.Macro
Do
    puttingblack bpass
    Module9.okiba okiba
    If bpass + wpass >= 2 Then
    MsgBox ("二人ともパスだったので対局を終了します")
    Exit Do
    ElseIf okiba = 0 Then
    MsgBox ("置き場が無くなったので対局を終了します")
    Exit Do
    End If
    wpass = 0
    puttingwhite wpass
    Module9.okiba okiba
    If bpass + wpass >= 2 Then
    MsgBox ("二人ともパスだったので対局を終了します")
    Exit Do
    ElseIf okiba = 0 Then
    MsgBox ("置き場が無くなったので対局を終了します")
    Exit Do
    End If
    bpass = 0
Loop Until x
For n = 2 To 9
For m = 2 To 9
If Sheet1.Cells(n, m).Interior.Color = RGB(0, 0, 0) Then
bcount = bcount + 1
ElseIf Sheet1.Cells(n, m).Interior.Color = RGB(255, 255, 255) Then
wcount = wcount + 1
End If
Next m
Next n
If bcount > wcount Then
MsgBox ("黒") & bcount & ("対白") & wcount & ("で黒の勝ちです")
ElseIf bcount < wcount Then
MsgBox ("黒") & bcount & ("対白") & wcount & ("で白の勝ちです")
ElseIf bcount = wcount Then
MsgBox ("黒") & bcount & ("対白") & wcount & ("で引き分けです")
End If
End Sub


Sub start()
Dim n As Integer, m As Integer
With Sheet1
Module3.Macro4
For m = 2 To 9
For n = 2 To 9
    .Cells(n, m).Interior.Color = RGB(0, 255, 0)
Next n
Next m
.Cells(4 + 1, 4 + 1).Interior.Color = RGB(255, 255, 255)
.Cells(5 + 1, 5 + 1).Interior.Color = RGB(255, 255, 255)
.Cells(4 + 1, 5 + 1).Interior.Color = RGB(0, 0, 0)
.Cells(5 + 1, 4 + 1).Interior.Color = RGB(0, 0, 0)
End With
End Sub

Sub puttingblack(bpass As Integer)
Dim x As Integer, y As Integer, c As Integer, xx As String, yy As String
Dim handan As Integer
handan = 0
Module9.kuroban
Do
bstart:
c = 1
xx = InputBox("上から何行目?0を2回入力するとパスになります", "黒の番です", 0)
If xx = "" Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo bstart
End If
yy = InputBox("左から何列目?0を2回入力するとパスになります", "黒の番です", 0)
If xx = "" Or yy = "" Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo bstart
End If
x = Val(xx)
y = Val(yy)
If x = 0 And y = 0 Then
MsgBox ("パスしました")
bpass = bpass + 1
Exit Do
ElseIf x = 0 Or y = 0 Or x < 1 Or x > 8 Or y < 1 Or y > 8 Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo bstart
End If
y = y + 1
x = x + 1
search_for_black x, y, handan
With Sheet1
If .Cells(x, y).Interior.Color = RGB(0, 255, 0) And handan <> 0 Then
.Cells(x, y).Interior.Color = RGB(0, 0, 0)
Else: MsgBox x - 1 & (",") & y - 1 & ("は置けません!")
c = 0
End If
End With
Loop While c = 0
End Sub

Sub puttingwhite(wpass As Integer)
Dim x As Integer, y As Integer, c As Integer, xx As String, yy As String
Dim handan As Integer
handan = 0
Module9.siroban
Do
wstart:
c = 1
xx = InputBox("上から何行目?0を2回入力するとパスになります", "白の番です", 0)
If xx = "" Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo wstart
End If
yy = InputBox("左から何列目?0を2回入力するとパスになります", "白の番です", 0)
If xx = "" Or yy = "" Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo wstart
End If
x = Val(xx)
y = Val(yy)
If x = 0 And y = 0 Then
MsgBox ("パスしました")
wpass = wpass + 1
Exit Do
ElseIf x = 0 Or y = 0 Then
MsgBox ("番号が不正です。もう一度入力してください")
GoTo wstart
End If
y = y + 1
x = x + 1
search_for_white x, y, handan
With Sheet1
If .Cells(x, y).Interior.Color = RGB(0, 255, 0) And handan <> 0 Then
.Cells(x, y).Interior.Color = RGB(255, 255, 255)
Else: MsgBox x - 1 & (",") & y - 1 & ("は置けません!")
c = 0
End If
End With
Loop While c = 0
End Sub

Excelオセロプログラミング概要

Excelでオセロを作ってみた。
プレイ中の感じです。(クリックで拡大)



残念ながらクリックに対応しておらず、完全に手打ち形式です。
実はこのころプログラミングとか全く触ったこともなく、かなり文が雑です。

Excelの授業課題として提出したので期間もほとんどかけられてません。
大体半年前だったかな?

あまりにも膨大な駄文なので分割してアップます。
(駄文なのに上げるのかとは言わないこと)


画像には表記されていませんが、座標[0,0]でパスができ、
双方ともにパスだった場合は強制的にゲームが終了します。

また、有効な置き場がなかった時には自動でパスし、置き場が完全になくなったときは
終了するようになっています。


プレイする分にはネックはクリック対応じゃないことくらいなんですけど、
ソースをみると無駄があるわあるわ…。


・石を裏返すときの処理と有効な置き場の探索で上下左右斜めすべての文が手打ちであること。
・意味のないモジュール分け。
・反対に必要なところなのにモジュールがひとつ。
・変数名(フラグなど)が何を指すか解りにくい。


こんなに。
特に1番上は致命的ですね。よくこれで出そうと思ったな自分…とか考えてしまうレベル。


言い忘れてましたがExcelのVBAを使用しています。
モジュールは7コ。数えた感じでは合計で1000行を軽く超していたような…。


ちなみにあれから半年、Android開発をしてみたいと思い立ち、
まずは原点のオセロだろうと思い、再びオセロを作り始めました。
グラフィカルな部分は未完成ながらもシステムは完成し、行数を数えてみると

なんと150行。

現行でグラフィック関連も少し書いているので、
それを除くとおよそ10倍の無駄があった計算になります。

ちなみに現行版はAndroidアプリにする予定だったのでJava言語で書かれています。


たった半年ながら大きな前進だったな、としみじみ。
Android版は画像ファイルなしで全てグラフィック描画処理で済ませようと思うので、
円の中心の座標とかタッチ入力の判定とかも少し書かれています。

問題はAndroidアプリの仕組みを理解していない節があるので
そこを勉強するのにあと半年くらいかかりそうだなー、なんて。


モジュール別にVBAプログラムをあげるのでラベルからもしくは以下からどうぞ。
module1
module2
module3
module4
module5
module6
module9(※9であることに注意)

Windowsプログラミングによるオセロ(構造としては完成系のつもり)

2011年3月6日日曜日

GPSロガー3

まずは前回の訂正から。

言っていた通り、前回のままではGooglemapに送信したときにエラー(フリーズ)
することが判明したので修正版をあげておきます。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

FILE *fr,*fw;
void KMLlayout(void);
void KMLlayout2(void);

int main (void){
errno_t error;

if((error = fopen_s(&fr,"gpsdata.txt","r")) != 0){
printf("gpsdata File Open Error!");
getchar();
return -1;
}
if((error = fopen_s(&fw,"mapdata.kml","w")) != 0){
printf("mapdata File Open Error!");
return -1;
}

KMLlayout();

int count;
double latitude,longitude;
char c[100];
char endflag[10] ="";
char *token,*nexttoken;

while(1){
count =0;
fscanf_s(fr,"%s",c,100);//fscanfのセキュリティ版
token = strtok_s(c,",",&nexttoken);//文字列を指定した文字で区切る(string.h)

/*終了フラグ*/
if(strcmp(token,endflag) == 0){
break;//2回連続で同じ行を読み込んだら終了する
/*最後の行までいくと最後の行を連続で読み続ける*/
}
strcpy_s(endflag,10,token);

/*変換*/
if(strcmp(token,"$GPGGA") == 0){
while(token != NULL){
if (count == 2){//NMEAとgoogleの経度緯度の順が逆なので分ける
latitude = atof(token);//文字列をdoubleに(stdlib.h)
latitude = latitude/100;//googleの位置フォーマットに合わせる
}
else if(count == 4){//別々の変数に入れる
longitude = atof(token);
longitude = longitude/100;
}
token = strtok_s(NULL,",",&nexttoken);//2度目以降はNULL文字
count++;
}
fprintf(fw,"%f,%f,0.000000 ",longitude,latitude);
}
}
KMLlayout2();
fclose(fr);
fclose(fw);
}


void KMLlayout(void){
fprintf(fw,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://earth.google.com/kml/2.2\">"
"<Document>"
"  <name>無題</name>"
"  <description><![CDATA[test]]></description>"
"  <Style id=\"style1\">"
"    <LineStyle>"
"      <color>73FF0000</color>"
"      <width>5</width>"
"    </LineStyle>"
"  </Style>"
"  <Placemark>"
"    <name>line</name>"
"    <Snippet></Snippet>"
"    <description><![CDATA[]]></description>"
"    <styleUrl>#style1</styleUrl>"
"    <ExtendedData>"
"          <Data name=\"_SnapToRoads\">"
"        <value>true</value>"
"      </Data>"
"    </ExtendedData>"
"    <LineString>"
"      <tessellate>1</tessellate>"
"     <coordinates>");
}
void KMLlayout2(void){
fprintf(fw,"</coordinates>"
"    </LineString>"
"  </Placemark>"
"</Document>"
"</kml>");
}



これはもう完成版で、前回ミスしていたところの修正とkmlへの対応版となっています。
まだkmlのフォーマットについて理解していない部分があるので現在は直線でしか表示できません。
(「ルートに沿う」が出来ない。これはmapの方で指定できます。)



修正の内容について。
まず、前回は$GPGGAの行の2要素(緯度)と4要素目(経度)になればファイルに書き出す、という
流れに任せたプログラムでしたがkmlでは緯度経度が逆の順に並んでいるので、kmlに書き出すと
「北緯135度,東経45度」というあり得ない数値になっていたのが原因のようです。

そこで修正版では一度緯度データをdoubleに保存しておき(この時点ではatof関数によってcharからdoubleに変換されている)、経度も同じように保存してまとめて表示するという文になりました。

経度は特にdoubleに入れる必要はありませんが、どうせなら表示は1か所の方が見やすいので、
緯度経度ともに変数に格納しました。

下の二つのKMLlayoutは、単にプログラム内にkmlのベース文を表示させるだけのプログラムです。
これとの兼ね合いで最初のFILE宣言がグローバルになっています。

あと、ファイルオープンで自動でダイアログが消えないようにgetcharを仕込みました。
まああってもなくてもいいんですけど、ないと成功したのか失敗したのかわかんないので^^;


出力部分を抜けばかなり短い文になった感じですね。
Excelでオセロ作った時は知識もないしすごい長かった記憶が…(笑
たしか1500行くらい使ったような。

こんな感じでたぶんGPSデータをgooglekmlに変換することができたんじゃないかな?
それにしても標準の関数だけでここまで出来るんだなぁー。なんて。

文字比較と文字→数値、文字分割あたりはすごく便利に感じました。
文字系統が全然理解できていないので簡単に使えるといいですよね。
まあバグなんて個人プログラムだから気にしなくていいし。(その割に_s文ばっかり)


あとはハード的な解決とマイコンの方のプログラムかなー。


2011年3月5日土曜日

GPSロガー2

今回は前回の続き。

前に言ってた通り、kmlのフォーマットをはじめに。
kmlはどうやらGooglemapやGoogleEarthの形式らしくて位置情報を持っています。

ベースはたぶんXML(自分は書けませんが…)です。
XMLベースなので(ということにしておいて)、テキストエディタで開けます。

前回書いた、
「一度DLしたファイルをブラウザで開いてそのリンクからもう一度DLする方法」

で落としてきたファイルをWin標準のメモ帳で開いてみると…。


<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
  <name>無題</name>
  <description><![CDATA[test]]></description>
  <Style id="style1">
    <LineStyle>
      <color>73FF0000</color>
      <width>5</width>
    </LineStyle>
  </Style>
  <Placemark>
    <name>line</name>
    <Snippet></Snippet>
    <description><![CDATA[]]></description>
    <styleUrl>#style1</styleUrl>
    <ExtendedData>
      <Data name="_SnapToRoads">
        <value>true</value>
      </Data>
      <Data name="_SnapToRoads">
        <value>true</value>
      </Data>
    </ExtendedData>
    <LineString>
      <tessellate>1</tessellate>
      <coordinates>
        135.314151,35.215426,0.000000 135.235266,35.367473,0.000000
      </coordinates>
    </LineString>
  </Placemark>
</Document>
</kml>


<Data name ="_SnapToRoads">
 <value>true</value>
</Data>


が二つほど入っているのが気にかかるところではありますが、
ちゃんと動くのでスルーという方向で。


ここでヒントを出しますと、これはGooglemapで表示させると1本の直線です。
お察しの通り

<coordinates>
135.314151,35.215426,0.000000 135.235266,35.367473,0.000000
</coordinates>

がその直線部分になります。
たしか京都付近だったかなー?

その付近なので、座標は日本の[135,35]付近になりますね。
これは東経135度、北緯35度ということです。

今のところ北半球東半分(というか日本)でしか使う予定がないので、
南半球西半分では数値がどのような値になるかは解りません。
(たぶんマイナス表記になると思うんだけどなぁ。)


まだハード(GPS本体)を入手していないので、
先にNMEAデータからKMLデータに変換するプログラムを書いていきます。
扱うのは単にテキストファイルで、ネットに接続する予定でもないので
普通に知っているC言語でやっていきたいと思います。


機械の人間でフローチャート書くのに慣れていないので、脳内構想です。

テキストファイル(読み出しと書き出し2つ)を開く

KML形式のフォーマット(ここでいう<coordinates>以外の部分)を書き出す。
(ここはたぶん不変なので)

読み出しファイルから$GPGGAの行を探す

その行の位置データだけを取得して書き出したファイルに追加する

終わり


すごく簡単に書くとこんな感じです。
KMLフォーマット抜きにするとこんな感じになりました。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void){
FILE *fr,*fw;
errno_t error;

if((error = fopen_s(&fr,"gpsdata.txt","r")) != 0){
printf("gpsdata File Open Error!");
return -1;
}
if((error = fopen_s(&fw,"mapdata.kml","w")) != 0){
printf("mapdata File Open Error!");
return -1;
}

int count;
double num;
char c[100];
char endflag[10] ="";
char *token,*nexttoken;

while(1){
count =0;
fscanf_s(fr,"%s",c,100);//fscanfのセキュリティ版
token = strtok_s(c,",",&nexttoken);//文字列を指定した文字で区切る(string.h)

/*終了フラグ*/
if(strcmp(token,endflag) == 0){
break;//2回連続で同じ行を読み込んだら終了する
/*最後の行までいくと最後の行を連続で読み続ける*/
}
strcpy_s(endflag,10,token);

/*変換*/
if(strcmp(token,"$GPGGA") == 0){
while(token != NULL){
if (count == 2 || count == 4){//GPGGA行の2と4要素だけが必要なので
num = atof(token);//文字列をdoubleに(stdlib.h)
num = num/100;//googleの位置フォーマットに合わせる
fprintf(fw,"%f ",num);
}
token = strtok_s(NULL,",",&nexttoken);//2度目以降はNULL文字
count++;
}
}
}
fclose(fr);
fclose(fw);
}


これであとは先頭行に適当に書きつければOK(だと思う)。
重大なミスを発見したので次回、修正します。
googlemapが経度,緯度なのに対してNMEAが緯度,経度だったのが問題。
誰かNMEAのサンプルデータをくれるとすごくうれしいんだけど
なかなか持ってる人っていないよねー。


早く完成させて車載したいなぁ。
じゃあ終わり。

2011年3月4日金曜日

GPSロガー

GPSロガーとは?
3次元位置計測情報を取得し、記録する装置。
取得した情報は地図上に表示されたりする。

製作理由はですね、
・第一種普通免許の取得
・春休み(暇)
・技術の向上
こんなところです。

物作るのに理由なんてありません。アマは。


とどのつまりクルマで走った場所をgooglemap上に記録したかった。
そんな理由なんです。
余談ですけどトド肉を今日食べました。


そんなこんなでプロジェクトスタート。

まずはじめにするべきはフォーマットの確認。
どうやらGPSの位置情報はNMEA-0183で表現されるようです。
$GPGGA,104549.04,2447.2038,N,12100.4990,E,1,06,01.7,00078.8,M,0016.3,M,,*5C
$GPGLL,2447.2073,N,12100.5022,E,104548.04,A,A*65
$GPGSA,A,3,26,21,,,09,17,,,,,,,10.8,02.1,10.6*07
$GPGSV,2,1,08,26,50,016,40,09,50,173,39,21,43,316,38,17,41,144,42*7C
$GPGSV,2,2,08,29,38,029,37,10,27,082,32,18,22,309,24,24,09,145,*7B
$GPRMC,104549.04,A,2447.2038,N,12100.4990,E,016.0,221.0,250304,003.3,W,A*22
$GPVTG,221.0,T,224.3,M,016.0,N,0029.6,K,A*1F
$GPZDA,104548.04,25,03,2004,,*6C

こんな感じのデータ内容らしいです。
実機持ってないのが痛いところですけど
これをベースにプログラム組んでいきたいと思います。

まず、あまりマイコンに負担をかけたくないので2ステップでの予定です。
データの取得と記録→
NMEA-0183形式をGooglemapのXML(KML)形式へ→
Googlemapに位置情報を投稿
こんな感じの2ステップです。


現在2011年3月4日では、
・C言語ベース
・AVRマイコン(atmega88p)を使って情報をSDカードに記録してPCでKMLに
・GPSデータからKMLまでは自動生成であること
・シガーソケットからの給電
を目標にしています。


現在、フォーマットの確認を終えてそこからKMLへのプログラム作りです。
接続方式などは現物を入手してから考えるのでここではスルー。


上記NMEAの形式ではどうやら最上段の$GPGGA行の2要素目、
2447.2038
と、4要素目
12100.4990
が位置情報みたいです。

たぶん、付近にあるNとかEとかは
North(北緯)とEast(東経)の頭文字だと思われます。
これを取得して利用していきます。

そしてこの形式では小数点が2ケタほど右に行っているようなので、
そこを100倍か何かして
24.472038
121.004990
のような感じに変えていきます。

親切に行ごとにGPなんとか~が書かれているのでそれを利用して、

$マークが来たらその先頭の文字列はGPGGAであるかを比較する。

GPGGAだったらその行を取得(要素ごとにスペースが入っているかによって若干変わる)。

行の2要素目と4要素目を取得してKML形式に書き出し。(正確には3と5要素)


こんな感じの流れを想定しました。
KMLのフォーマットなどは次回で。


ちなみにGooglemapでマイマップを作製し、右上のバー(印刷、送信、リンクとかがあるところ)の
「GoogleEarthで表示」ってのをクリックするとKMLファイルがダウンロードできます。
当たり前ですが、このときにちゃんと線を引くなりなんなりしていないと中身を見てもすっからかんです。


そしてここからがミソ、というかそんな感じなんですけど
ここでダウンロードしたKMLは情報ファイルにリンクが張ってあるだけで、
それだけでは意味を持ちません。
なのでそのリンクを辿っていきます。

DLしたKMLをブラウザで開くとURLが見えると思うので、
それをアドレスバーにぶっこんじゃってください。
そうするともう一度KMLのダウンロードが開始されます。

ミソ、といってもやることはこれだけなんですけど
これが出来ないと位置データ自作は難しいなぁ。

やっぱり完成したものを一回見てそれをいじってみないと
どこが必要な部分かが分かんないんだよなー。

そんな感じで製作(してないけど)1日目終了。
(^-^)/~