Cat-Pot技術公開1:ラインセンサ回路

大会まであと1日,3月25日になりました.今日は調整日です.

大会の開催に伴って大会中の技術交流のネタのひとつとして今年作ったラインセンサの回路図を公開します.

この回路はつい廃オカダくん(@OkadaTechnology)との共同開発になります.あっちが公開しようと言うので同じ日に公開することになりました.

経緯を簡単に説明します.

オカダ:マイコン処理重なりすぎてライン処理入る前に白線通り過ぎるんですけどーーーー(;´д`)

私:別マイコンで処理させればよくね????

オカダ:ICでなんとかならん??

私:ほぇ~~~~

(数分経過)

オカダ:サイリスタで読むまでONにして読んだらOFFで解放すればいいんじゃ!

私:サイリスタって何ぞ.てかそれ自己保持させればいいんじゃね?

(オカダによるサイリスタの説明が入る)

私:へーきっついな!

(数日経過)

私:自己保持させるならOR回路で組めるくね??簡単やん!

オカダ:ためします!!!

数日経過・・・・その後いろいろあり

私,オカダ:動いた!!!強そう!!!

てな感じでラインセンサ回路ができました.回路図はこちら.

LINE_SENSOR.bmp

主な機能を以下にまとめます.

・複数個の受光素子をORICで統合→方向ごとに管理が可能に

・立ち上がりを保持(センサの出力を保持)

・信号ピンにより保持のON,OFF機能の搭載

・今まで通りの検知も可能なように保持前のデータも出力

なお,論理演算をするために信号がHigh,Lowになります.ADCによる処理が出来なくなるので閾値には気を付けましょう.

目玉はやはり自己保持回路部ですね.生の値(RawData)の後にOR回路と抵抗とトランジスタだけで実装ができる点でマイコンに比べ優位でしょうか.まぁ値の調整面倒ですが.

センサのところは1方向分になるのでうちの回路の場合この部分が3つあります.新JISに反抗するために4072を使ってますが,実際の回路は4075で構成して,数がちょうど合うようにしています.

さてさて,肝心の保持することによる利点ですが,

・自己保持ON→読み取り→自己保持OFF→(wait)→自己保持ON→以下ループ

とすれば,前回のチェックから今のチェックの間でラインを読んだことがわかります.このため検知漏れは確実になくなることになります.

・また,保持を解除していてもただのORで組んでいるだけなのでRawDataもOR回路の出力になります.このため保持をしていなくても検知が可能です.これは通常の利用方法と同じでしょうかね.

最後に,この回路の応用例を挙げます.

まず,ロボットはボールに対して回り込みおよび追いかける動作をしていることとします.

この状態の時ラインを読む可能性があるのはボールのある方向のみです.そのためラインを踏む可能性のある方向のみ(ボールのある方向,あるいはロボットの進む向き)の自己保持をONにします.

この状態で通常通り回り込み動作をさせます.

ボールのある方向でラインを踏んでしまったとしましょう.

そうすると,回路は当然値を保持します.なので今度はRawDataを用いてラインの処理を行います.

RawDataが白線を検知しなくなるまでロボット動かします.

ボールの位置が変わるまで保持を継続し変わったら保持を解除すればライン間際で往復することを防ぐことが考えられます.

簡単ですが応用的な使い方は以上です.

まとめます.

ラインセンサはマイコンで処理してもプログラム次第でなんでもやりようがあるし,いいと思う.

でも,ロジックで実装してみたら案外簡単にできるかもしれない.

固定観念にとらわれず,柔軟な発想で新しい回路を開発して下さい!!!

コメント受け付けます!質問もどうぞ!!ツイッターアカウントは@ryuna_roboです.こちらの方が対応早いです.(文章はひどいですが)

コミュ障ですが皆さんと交流したいので絡んでください.では大会頑張りましょう!!

全国大会出場します!!!

お久しぶりです.

試験やら大会やら大会やらで更新が空いてしまいました.

RCJSのオープンB全国大会にCat-Potの一員として出場することが決まりました!!!!

いきさつを以下にかきます

先々週RCJの北信越ブロック大会が開催されました.今年の出場チーム数は6チームでしたので,

3チームごとのリーグを行いその後一位から4位まで決めるといった流れで大会が進行されました.

Cat-Potが試合を行うリーグの相手は inputと長野高専のチームでした.

前日にやっとロボットが2体完成して,ふぅっと息つく間もなく新しいロボットが壊れてしまって,

初戦inputとの試合は1台で戦いました.もともと彼らが強いのと,こちらが一台というのもあり,一試合目は圧倒的に負けてしまいました.

落胆の中,調整の合間に二体目を弄っていたら基板の故障かと思っていたのがただの配線の接触不良ということに気付きました.そして二体目を試合直後に修理して,なんとか2試合目に参加,苦しいながらも勝利してリーグ2位になりました.

その後,ご飯をはさんで3試合目,3位決定戦が行われました.

休憩の間にプログラムを調整して多少まともに動くようにして迎えた3試合目,

低速ですが,確実に点を稼ぎ,相手に2倍の得点差で勝って辛くも3位入賞となりました.

ここまで,まさか3位になるとはって気分で終わりました.

大会後,例年だと出場枠が2枠なので,完全にロボカップ引退した気持ちでいました.

前日まで全く2台目動かなくて最下位候補だと思ってた僕からすれば3位はまずまずで,少し救われた気分だったので引退もいいかなとか.

ちょうど大会終わって一週間後テストだったので部活のことは一切触れずに過ごしてた今日まで.

そんなときにオカダ氏からおめでとうとの連絡が.

たまたまその日だけツイッターとかメールとかまったく更新しなかったため,まさかのチームでもなんでもない人から全国出場通知を受ける意味不明な結末になってしまいました.おかだくんありがとう

通知を受けた後メンバーと相談して,全国出場しようってことになって.結果ロボカップ引退できませんでした.よかったね!!!

そんなん今にいたります.

これからロボットを急ピッチで調整します.現行モデルでは夢を見すぎている点がいくつもあって実現不可能なところがあるのでそこらへん省いていろいろやったり.

全国でみんなよろしくね!!!以上 いきさつでした.

最後にブロック大会までいろいろな人にお世話になりました.

一番はチームのメンバ.これからも頑張ろう!

ツイッター界隈の人に感謝です.

共同回路設計者のおかだくんには特大の感謝ですね.地区大会ではその回路まったく使わなかったけどな!!!!!

それじゃぁ全国まであと一か月,悔いのないようにがんばりましょう!

gnuplotを使ったグラフの描画

近年技術の発達とともに,オシロスコープにもいろいろな機能が追加されるようになってきています.
その一つにUSBメモリがぶっさせることが挙げられます.この機能を使うと表示されているデータをUSBメモリCSVファイルに保存でき,データをPCで確認することが可能となりました.
今回はそのCSVファイルからEPS画像を作成することが目的です.
csvファイルはexel等の表計算ソフトで読み込むことが出来,それを用いればグラフを作成することが出来ます.また,gnuplotと呼ばれるグラフ描画ソフトを用いることによりグラフを生成する方法もあります. この2つのやり方について特徴を次の表にまとめます.
方法特徴長所短所
exelによるグラフ作成簡単波形の調整をしながらグラフを見ることが出来るファイルが増えてくるといちいち開くのが面倒になる
gnuplotによるグラフ作成見栄えがよいギリシャ文字等も美しく表現できる作成するのにgpファイルが必要で,グラフごとにgpファイルを作成しなくてはならない
時間がかかったり,gpファイルのような中間ファイルが増えてきてフォルダを圧迫するのではスマートでありません.
また,ファイルを増やさないために毎度gpファイルを書き換えるのならばそれこそ時間がかかってしまいます.
それでも,きれいにかつ短時間でグラフを生成したいような場合は必ずあります.
そこで,今回はC言語力を借りてこれを解決しようと思います.
具体的には,同じようなグラフいくつも作成するとき,グラフ名やX軸,Y軸の最大値,グラフの値のみを変化させてcsvから直接eps画像の生成を行います.
これからプログラムを紹介する前に,プログラムを走らせる前の前提条件を以下にまとます.
  1. bcc compilarなどのCプログラムをコンパイルする環境が整っていること
  2. gnuplotがPCに入っていてパスもとおっていること
  3. そもそもepsファイルが見れること.(gsview等のソフト)
  4. ある程度C言語の知識があること
C言語にはパイプと呼ばれる機能が存在します.これはCのプログラムが動作中にプログラム内で別のプログラムを呼び出す.といったものです.今回はこれを用いてcのプログラムが動作中にgnuplotを起動し,項目をfprintfによりgnuplotに直接入力して波形を出力させます.
では,プログラムを以下に示します.
プログラムの流れは以下の通り.
  1. コマンドライン引数の数が正しいかチェック
  2. コマンドライン引数の2つめに入れたcsvファイルを開く
  3. 波形のX値,Y値を読み込む
  4. csvファイルを閉じる
  5. パイプでgnuplotを開く
  6. gnuplotに各項目を入力していく
  7. 波形データを入力
  8. eps画像を出力
  9. gnuplotを閉じる
実行するときは csv2eps ???.csv nameと入力して実行します.???.csvには一列目に時間,二列目に振幅が格納されていて,データ同士がコンマ区切りの物を使います.nameにはグラフに付けたい名前等(出力されるepsファイルの名前)を入力します.
では,例をのせます.次のような5点の時間対振幅波形が格納されたdata.csvからグラフpr1を作成したい場合.
0,5 10,100 50,50 60,5 120,55
コマンドラインでは次のように入力します.
csv2eps data.csv pr1
実行すると次のようなeps画像が出力されます. pr1.png 図より,各点における時間と振幅のグラフが作成できていることがわかります.また見た目も美しく仕上がっています. このようにプログラムを用いれば簡単にepsファイルを作成することが出来ました.またgnuplotの長所も生かすことが出来たといえます. gnuplotでは折れ線グラフのほかにも棒グラフや対数グラフ,3次元グラフなどいろいろなことが出来ます.gnuplotTeXライフを楽しく過ごしましょう!

Cat-Pot(2年目)始動!

進捗どうですか??

すごく残念なんですが,NHK高専ロボコンでうちの高専は全国大会に行くことが叶いませんでした.

とてもいい出来だっただけに,惜しかったと思います.

部活の雰囲気も明るく,真面目に取り組んでいるので来年こそは全国大会に行って,

ロボットの掲げる目的を達成できるはずでしょう.

さて,言い方は悪いのですが,うちの高専ではNHK高専ロボコンが終わるとオフシーズンと呼ばれる期間に入ります.(僕はNHK高専ロボコン中もオフシーズンでした.

オフシーズン中は様々な大会に参加したり,新たな機構や回路を試して,NHK高専ロボコンにつなげる活動をしています.

ロボカップでも,昨年は機構的なチャレンジで,オムニホイールを使わない複雑な形の4輪のロボットを製作しました.勝つことはできませんでしたが,機構や,回路で学ぶことは多くありました.

大会を通していろいろな知識を学ぶことができ,交流によりまた知識を広げられるのはいいことですね.

前置きは以上で,ここからが本題です.

今年もオフシーズンが始まりました.

チームCat-Potは,今年も皆さんが驚くようなロボットを作っていきたいと思っています.

どうぞ今年もよろしくお願いします.

LPC824M201JHI33の動作確認

今回はスイッチサイエンスさんより販売されているLPC824の石への書き込み法についてまとめようと思います.

スイッチサイエンスさんより販売されているものはこちら

https://www.switch-science.com/catalog/2025/

また石単体の販売はDigikeyから

http://www.digikey.jp/product-detail/ja/LPC824M201JHI33E/568-11572-ND/4975716

主な特徴を以下にまとめます.

・スイッチ・マトリックス

・豊富なADC

・mbedのオンラインコンパイラを利用できる()

いいことばかりですね().惚れちゃいそう(涙).

それでは本題に入りましょう.

書き込み方法(イカ醤油ぽっぽ焼き,FlashMagic)について以下にまとめます.

・書き込み準備

LPC824M201JHI33への接続

PIO0_12: ISP entry pin.

PIO0_5 : Reset pin.

PIO0_4 : TXD pin in ISP mode.

PIO0_0 : RXD pin in ISP mode.

また33ピンはGND,19ピンは3.3Vに接続.

LチカはPIO0_21で行います.

・プログラム

プログラムは以下の通り

#include "mbed.h"

DigitalOut led(P0_21);

Serial pc(P0_4,P0_0);

int main() {

while(1) {

led = 1;

wait(0.2);

led = 0;

wait(0.2);

pc.printf("Hello World!\r\n");

}

}

・注意点

スイッチサイエンスさんより販売されているLPC824のボードにはクリスタルがついていて外部発振となっています.このため,クリスタルを付けずに試す場合は,この点を変更しなければなりません.

mbed-srcをプログラムへインポートして

targets/cmsis/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/system_LPC8xx.c

#define SYSPLLCLKSEL_Val 0x00000001

の項について

#define SYSPLLCLKSEL_Val 0x00000000

のように書き換えて内部発振をするように変更してください.

・イカ醤油ぽっぽ焼きによる方法について

サイト通りに試します.

https://developer.mbed.org/users/okano/code/ika_shouyu_poppoyaki/

先ほどの接続方法並びにプログラムとサイトの手順を照らし合わせて書き込みを行ってください.

printfdebugについては今回はTera termを用いました.書き込みの様子等も確認ができます.

・FlashMagicによる方法について

ISPモードに入れるため,リセットとISPピンについてスイッチでプルアップして接続しておきます.(図を参照)

初めに,ftdiケーブルやusb to serialモジュール等を用いて各ピンを接続します.

(注意 ftdiを使う場合はドライバのインストールも行っておいてください.こちらに詳しく書かれています.)

rx-- RXD

tx-- TXD

VCC- VDD

GND- VDD

20150915_221135.jpg

まず,FlashMagicとHexfiletool(binからhexへの変換用)を用意します.

hexfiletoolを使用してbinからhexに変換します.(図を参照)

hex_file_tool.PNG

変換したhexファイルをFlashMAgicに入れます.また,図のようにFlashMagicの画面を合わせます.

flash_magic.PNG

ISPモードにいれます.

1リセットとISPを両方Lowにする

2リセットをhighにする

3ISPから手を放す.

以上の手順でISPモードに移行させます.

ISPモードに移行したらStep5-Start!より書き込みをスタートします.

Finishedとなったら書き込み完了です.Resetボタンを押してプログラムの動作を確認してください.

また,toolsのTerminalよりprontfによるデバッグ等が行えます.

以上簡単に説明しました.足りない点があったらまた加筆していこうと思います.

質問ありましたらどうぞ.

参考

イカ醤油ポッポ焼き味付けレシピ

https://developer.mbed.org/users/okano/code/ika_shouyu_poppoyaki/

lpc1114での遊び方

https://developer.mbed.org/users/ytsuboi/notebook/getting-started-with-mbed-lpc1114-ja/

LPCマイコン情報

http://www.nxp-lpc.com/lpc_micon/cortex-m0+/lpc800/

パルスボールの検知について_ver2

どうもです.

先日のパルスボール検知についての記事の

投稿後,直接でないにしても,いろいろ間接的にコメントをもらったのでその件について試してみました.

以下には,コメントをわかりやすくまとめてそれに対する実験を載せます.

一つ目:普通にもっと読めるでしょ.

なるほど....実験が悪いのかな....

確かに読み込んだ後,そのまま遠くへ持っていくと読み続けます.しかし,そのあと読まない位置にづらしてからもとに戻すと,同じ位置でも読まなくなる現象が起きました.この場合,受光部近傍で手を振ることで,もう一度読み直すよくわからんことで改善するようです.試合中はできないですね...

外乱光とか実験条件も多分にあると思うので精密な実験はできませんでした.

二つ目:IRM2121はON直後長距離まで読めるよ.

これは,Gcraud の人がついったで言ってました.

そこで,任意に周期を弄れてかつ簡単なNE555でVCCにパルスを与えて距離を測ってみました.

とても読めたのですが,コメントをくださった方の言うとおり,素子の裏側でも読めたりと,壁をちゃんと作るかなんかしないと使い物にならない状況でした.しかしながら角度によってパルスの間隔は変わるので,距離によれば,問題はなさそうです.

以上二つ試してみました.

前半の実験では,ボールの位置がずれてしまうと検知が不可能になってしまいます.

一方後半の実験では,繰り返し電源をOFFにするため,回路は少しだけ面倒になりますが,長距離まで読むということは可能になりました.

今後は,後半の実験で組んだ回路をもとに壁の作成や,読める距離の調整等を行っていきたいと思います.

パルスボールを検知するためのセンサについて

どうもです.

昨今のジュニアサッカーオープンBでは,パルスボールの赤外線を読むセンサとしてIRM2121が多く出回っているようです.

しかしながら,実際試してみると検知距離が短い.

少しロボットから離れただけで読まなくて辛いーと考えている人も少なくはないんじゃないでしょうか.

ではなぜ,IRM2121を使う人が後をというか....なんというかなのか.

ぶっちゃけ知らないです.ていうかみんな嘘ついてそうですよね.

そこでIRM2121の代わりになるセンサをこれから探していきたいと思います.(近距離においてはIRM2121はとてもいい)

試しにというかバカの一つ覚えで.同じ見た目のものを試してみました.

実験は,リモコン受光モジュールにローパスフィルタでなまらせたものを,オシロスコープで確認の流れで行いました.

・IRM2121 : 近距離しか見えない.壁がなくても何とかなる.距離により割と値が変わる.

・RPM7138-R: 遠くまで見えるが電圧値の変動に乏しい.また壁必須で,周りをしっかりと囲わないと全く意味がないよう.

2個しか試していないので今後追加していきます.

ちなみに受光モジュールは距離に応じたパルスが出るので,デジタルで読んだほうが精度があったりします.(体感)

以下に,デジタルで読むコードを乗せておきます.(mbedですが)

処理的にはC言語使える人なら余裕だと思うので,

実験して報告よろしく!!!(そんな人ならこのコード普通に思いつくくね?てか煩雑じゃね)

書き直すの面倒なのでライブラリだけですが...IRM2121 mbedとかで調べれば出ます.

名前がIRM2121となっていますが,たいていのものは使えるはずです.

/*IRM2121.h*/

#ifndef MBED_IRM_H

#define MBED_IRM_H

#include "mbed.h"

#define NAKATA 833 //周期833us

#define NOT_F 0

/** IRM2121 class, based on an DigitalIn pin, and a timer

* use RoboCup Junior Soccer to find PULSE BALL.

* Example:

* @code

* // Set Digital and read sensor.

* #include "mbed.h"

* #include "IRM2121.h"

* IRM2121 IR(p21);

*

* int main() {

* unsigned int length;

* while(1) {

*

* length = IR.Read();

* }

* }

* @endcode

*/

class IRM2121 {

public:

/** Create a IRM2121 object connected to the specified pin

**/

IRM2121(PinName IRM_PIN);

unsigned int Read (void);

/** Read the result

*

* @param none

*/

private:

DigitalIn _pin;

Timer _timer;

unsigned int _Time;

};

#endif

/*IRM2121.cpp*/

#include "IRM2121.h"

#include "mbed.h"

IRM2121::IRM2121(PinName IRM_PIN)

: _pin(IRM_PIN), _timer()

{

}

unsigned int IRM2121::Read(void)

// 0 means not valid.

{

_timer.reset();

_timer.start();

while(_pin){

if(_timer.read_us() > NAKATA){

_timer.stop();

return NOT_F;

}

}

_timer.reset();

while(!_pin){

if(_timer.read_us() > NAKATA){

_timer.stop();

return NOT_F;

}

}

_Time = _timer.read_us();

while(_pin){

if((_timer.read_us() -_Time) > NAKATA){

_timer.stop();

return NOT_F;

}

}

_Time = _timer.read_us() - _Time;

_timer.stop();

return _Time;

}