« 2010年10月 | トップページ | 2010年12月 »

2010年11月

2010年11月30日 (火)

Arduinoの処理速度

Arduinoって1つのコマンドに1クロックで処理できるようです。
ただ、ライブラリ関数は1つの関数でたくさんのコマンドを実行するので遅くなるようです。

digitalWrite(10, HIGH)  …Arduinoの出力
→ 44 CPUクロックサイクル
PORTD = i; …AVRのレジスタ直接操作による出力
→ 3 CPUクロックサイクル
だそうです。
こうなるとレジスタにアクセスするほうが格段に速いですね。

数学関数とかとにかく関数が充実しているので、Arduinoはすごいと思います。

 

STM32マイコン徹底入門が発売されますが、どんどん本・マイコンが増えていきますね。すばらしい!!

僕はSTM32を使おうかArduinoのどちらを使おうかと迷ってますが、そんなに処理速度を求めないと思うので、Arduinoかなとも思っています。なにしろArduinoは三角関数から液晶まで関数化されていてだいぶ楽ですから。

プレゼンテーションについて少しネットサーフィンしてたら、
http://www.youtube.com/watch?v=L0XeQhSnkHg&feature=player_embedded
こんな動画がありました。
さすがアップル社です!細かい性能を言うとかじゃなくて、人を引きこんでいくこのプレゼンテーションはすごいと思いました。
観客を笑わせるとかは僕には不可能ですが、もう少し分かりやすい発表とかできたらなと思います。

明日から12月ですね。もう今年が終わりそうな気がします。
時間がたつのは早いものです。

2010年11月28日 (日)

超音波センサー…・・・・・・ ・ ・ ・

超音波センサーを
「はじめてのPSoCマイコン」
という本のサンプルプログラムを用いて作ってみたのですが、どう頑張っても50cmくらいまでしか測定できません…
一瞬であれば80cmくらいも測定できますが、それ以上の長さは無反応なのです・・
ただ、50cmくらいまでの測定の精度はそんなに悪くはありません。

本にはきちんと160cmくらい測定できている(と書いてある)のですが・・・

う~ん
どうしてうまくいかないか分かりません・・・

思いついた原因①
送信用超音波センサーにつなげるためのピンと受信用超音波センサーにつなげるためのピンを1回つないでしまったことがあります。
あとで分かったのですが、その時にAGND(受信用超音波センサーにつなげるためのピン)とVDD,VSS(送信用超音波センサーにつなげるためのピン)がショートしたのではないかと・・
その1回のショートでマイコン内の線が切れて受信もしくは送信が鈍っているのではないかと・・
ただ、50cmくらいまではきちんと測定できていることから考えると、これが原因ではない気がします。

思いついた原因②
本の超音波センサーと自分が使っている超音波センサーが違うから。
この原因は考えられそうです。

 

思いついた解決方法①
PSoCマイコンを交換してみる
ただ今はPSoCマイコンを1つしか持っていないので購入しないとできません。

思いついた解決方法②
本で用いられている超音波センサーと同じものを使う。
ただ、僕は32.8kHzの超音波センサーを作るのを目的としているため、この解決方法だと40kHzしか使えなくなってしまいます。

思いついた解決方法③
遠い距離が認識できないようなので
送信してから一定の時間が経ったらPGAの増幅率を引き上げる

そこでPGAの増幅率だけを上げてみると、送信した超音波の反響を受信してしまうみたいで、ずっと14cmになってしまいました。
そこで不感帯(反響による誤動作を防ぐため、送信してから一定時間受信しないようにする期間)を長くして同じくPGAの増幅率を上げた状態でやってみると、120cmくらいまで測定出来るようになりました^^;ただ不感帯を長くしたために、測定可能な最短距離が18cmになってしまいました。
以上の結果から言うと解決方法③は有効な気がします。

うーん・・
一定の時間が経ったらPGAの増幅率を引き上げるのは難しそうです・・・

2010年11月23日 (火)

モータードライブ回路設計

FETを4個使ったモータードライブ回路を設計してみました。
FETをまだ買っていないので、回路は作っていません。

2011/8/25追記。
この回路図は間違っているので
http://kyoukyou-zero.cocolog-nifty.com/blog/2011/05/25a-6441.html
をご覧ください。

回路図↓(クリックすると拡大します)

Fet_2 

動かし方↓

Fet2
略語の意味
 H:High +5.0Vのこと(モーター駆動用とは別電源)
 L:Low GNDのこと
 PWM;パルス幅変調

モータードライブ回路を今まで自作したことがないので、この回路でうまく動くか不安です。モータードライブ回路を作ったことがある方、できればコメントください。IN1とIN3を同時に(IN2とIN4を同時に)、Highにしてはいけないという事以外で注意すべきこととかこの回路でまずい所とかもお願いします。

部品が届いたら組み上げてみようかなと思います。

2010年11月21日 (日)

IRセンサーのデータ解析

IRセンサーで取ったデータのグラフです(クリックすると拡大します)

Ir

センサーの値の取り方はいたってカンタン!
2000回デジタル入力してそのうち何回HIGHであったかというのがここで言うセンサーの値です。
赤外線リモコンモジュールは受信するとLOWになるので、ボールとの距離が近づけば値は小さくなります。

グラフを見てみると10cm違ってもあまりセンサーの値が変わらないことが分かります。

近似曲線を引いてみました。(7区間平均してみました)

Ir

これで、10cm以上誤差が出る確率は20%くらいに抑えることができました。

これらは処理によって誤差を少なくしようというものですが、それだと限界があり、また、ボールへの反応速度がガクンと落ちてしまうので、ハードウェアでも工夫しようと思います(というかハードの工夫の方が大切です)。

ちなみに前回の記事に書いたPSoCのCPU_Clockですが、SysClk/1にすると電源電圧が4.7Vを下回ったときに動作不可能になるようです。
ブレッドボードが錆び始めていて内部抵抗が高い→電圧が一瞬下がることがある→4.7V以下になったときに動作不可能になる
というのが原因で動作不可能になったと考えられます。

SysClk/2にしたら今のところ順調に動いています。

2010年11月20日 (土)

PSoCマイコンのCPU_Clock

IRセンサーの信号をPSoCマイコンで受け取っていたら、ブレッドボードの線を少し揺らすだけでPSoCマイコンが動作しなくなるという状況が起きました。

結局の原因を率直に言うと、CPU_ClockをSysClk/1にしていたからでした。
デフォルト設定はSysClk/8です。

CPU_ClockをSysClk/1にすると動作が不安定になることを確かめるため、次のような実験を行いました。
PSoCに電源が入ったらLEDを点灯させるだけのプログラムを入れました。デフォルト設定からCPU_ClockだけをSysClk/1に変更しました。電源を入れて、LEDが点灯します。そこで、ブレッドボードの線を少し揺らすといきなりLEDが暗くなりはじめて点灯したり消えたりするのです(大量にリセットがかかっていると考えられます)。
次に他は全く同じプログラムでCPU_Clockだけをデフォルト(SysClk/8)に戻します。電源を入れて、LEDが点灯します。それから、ブレッドボードの線を揺らしてもずっと点灯したままになるのです(正常な証拠)。

これらのことから、CPU_ClockをSysClk/1にするとかなり動作が不安定になる(というか動作不可能になる)ことが分かりました。ただ、なぜCPU_ClockをSysClk/1にすると動作不可能になるかは分かりません。なので、とりあえず、CPU_Clockはデフォルト設定のままにしておこうと思います。

 

今日、LPFやADCなしでIRセンサーの情報を読み取ることができました(今までのアナログブロックでの苦労はなんだったんでしょう・・?)。
IRM-3638を使い、PSoCマイコンでデジタル入力して演算しました。
ボールまで距離の誤差は+/-10cm以内くらいに収められました。(だいたいです)
このくらい正確に距離が分かれば制御もできそうです。
ボールがどこかに存在すればたとえボールがIRセンサー受光部の反対側にあってもIRセンサーは反応してしまいました。
でも、IRセンサー受光部の反対側にボールがあった場合、ボールまでの距離はかなり低く示される(光が弱いということ)ので大丈夫そうです(ちなみにIRセンサーは真正面の光によく反応し横からの光にはあまり反応しません。この性質はけっこう使えます)
まだ1つしかIRM-3638を買っていないので、これからやっていきたいと思います。

2010年11月18日 (木)

LPFを通したあとの波形

パルスボールの赤外線を赤外線リモコン受信モジュールで受けて、その信号をLPFに通してみました。LPFはPSoCマイコンの内部に作ることができるので外付け部品は要りません。

オシロスコープで波形を見てみました。
波形はそこそこキレイです。
2次フィルタは少しガタガタしていて4次フィルタはよりキレイな波形になりました。
4次フィルタでは50Hzで0dBで1000Hzで-100dBになるようにしました。
と・・いうことは50分の1秒くらいは遅れているということかも知れません(それ以上かも)。

IRセンサーのボールまでの距離の情報は、LPFを通しAD変換してから(これらの処理はPSoCマイコンで行って)メインコンピューターに送ろうと思っていたのですが、LPFやADCを使わなくても、たくさんデジタル入力を行って平均値を求めればデューディー比が分かる気がします(これだとPSoCじゃなくてもいけるではないか!)。
でも、LPFの出力をADCで読み取っても大丈夫そうなのでこのまま行こうかな・・と考えたりしています。

不安なことは、モーターを動かした時に放射ノイズによってデジタル通信(PSoCマイコンとメインコンピューターとのI2C通信のこと)に転送エラーがたくさん出てしまうかもしれないということですが、被害が出てから考えようと思います。(アナログで情報を送っても情報が曲げられるだけですが、デジタル通信は情報が途切れるのが欠点かなとは感じています。)

2010年11月17日 (水)

LPFやってみたが・・

PSoCマイコンのLPFブロックを使ってみたのですが全くうまくいかず・・
LPFブロックに与えるクロックを全く何も考えずにやったからだと思います。
うまくいかないのも当然です・・・
クロック周波数をきちんと考えて設定しようと思います。

2010年11月16日 (火)

簡単なミスほど見つかりにくく時間がかかる!?

PSoCでのADCのデーターをI2C通信でArduinoに送って液晶に表示させようとしたら、80035とか   -2405とか出たのであります(アラビックリ!!)。
なぜかを簡潔にいうと
バグその①PSoCのADCのデーターは12ビットの場合「-2048 ~ +2047」で表される。だからそのまま使うとマイナスが出るのは当たり前。
このバグはまだ納得できるのですが・・・
バグその②液晶でいちいちクリアしなきゃならなかった。いちいちクリアしないと、例えば"12345"と表示した後"800"と表示しようとすると、重なって"80045"と表示される。
そりゃ~変な値がでるはずです!
これを見つけるのに4時間くらいかかりました。ADCからは正しいデータが出ているかとか1つずつ原因をつぶしていっても奇妙なことが起こるので、う~~んとうなり、PSoCとArduinoにそれぞれ液晶につなげてどういう風にデーターが曲げられているかを眺めたら、あぁぁ~~なるほど!!となりました。
もう爆笑しました!何時間もバグを探し続けてこれですから!
同時に後悔と自分を責めるという気持ちとでもいいますか・・とにかくひどい!

でも、今日中に見つかってよかったかな?とポジティブになりつつ(?)、これを書いている次第でございます。
I2Cのエラーは今のところ出ていないです・・(たぶん)

明日もボチボチ頑張ります!

(あとちなみに、前の記事のI2C日本語仕様書はやはり誤植で原文が正しいようです)

I2Cの仕様書の日本語バージョン????

英語のI2C仕様書の図を見てください↓(クリックすると拡大します)

I2c_2 
出典:http://www.nxp.com/acrobat_download2/literature/9398/39340011.pdf
    の14ページ目

次に日本語バージョンを見てください↓(クリックすると拡大します)

I2c_3
出典:http://www.nxp.com/documents/other/39340011_jp.pdf
    の同じく14ページ目

日本語バージョンなのですが斜線部分にすべきところがなっていない気がするのですが・・・
いきなりスレーブがマスタにしゃべりかけるなんてOKでしたっけ?
(実は前の記事で同じ図を出していて自分はその時はスルーしてたんですが・・よく考えると・・・)

微妙に不安なのでどなたかコメントお願いします。

2010年11月15日 (月)

ArduinoとPSoCのI2C通信(複数バイト)

2バイトでのArduinoとPSoCのI2C通信をしてみました。

PSoCではI2CHWブロックを使い、Arduinoがマスタ、PSoCがスレーブというように設定しました。

ここで注意すべきことがありまして、

たとえばPSoC側を
  dat = 1234;             //16進数で4D2になります
  buf_tx[0] = dat >> 8; //この場合0x04になります
  buf_tx[1] = dat;        //この場合0xD2になります
(buf_tx[n]とは送信するためのバッファ変数です。またdatはintでbuf_txはBYTEです。)
(PSoCマイコンではバッファ変数に送りたいものをあらかじめ入れておいて、マスタから送信しなさいと言われたら何も考えずにバッファ変数の内容を答えます。だから、マスタからいつ「送信しなさい!」といわれても良いようにあらかじめ言うことを準備しておきます。これらは、その準備のコードです。)

というコードにして、Arduino側で
  Wire.requestFrom(18,2);//1バイト要求することを宣言
  rd_data[1] = Wire.receive();//受信してrd_data[1]に代入
  rd_data[0] = Wire.receive();//受信してrd_data[0]に代入
という風に受信すると、
rd_data[1]には0x04が入り、rd_data[0]には0xD2が入ります。

つまり、PSoCでは「変数名[0]」にMSBを入れて、「変数名[n]」にLSBを入れなければいけないと考えられます。

普通上位バイトから受信して、後で下位バイトを受信すると思い込んでいるのですが、ArduinoのWire関数は少々ブラックボックス化されているので、確実ではありません。
ただ、PSoCのバッファ変数の[0]は、Arduinoでは最初に受信されるのは確かです。

配列の[n]のnが少ないほうが下位バイトで後から送信するのだと思っていた僕は混乱しました。

ともかく、Wire.receive();で最初に返されたデーター(つまり最初に何らかの変数に代入したデーター)は、I2Cで実際に最初に受信したデーターであるということがはっきりすればこれらが確実になるということでございます。

分かりにくい文章ですみませんが、Wire.receive();で最初に返されたデーターが、I2Cで実際に最初に受信したデーターであるかどうか分かる方は御教授ください。お願いします。

  

 

さて、ちなみに僕がなぜこんなにPSoCマイコンとArduinoとのI2C通信をやっているかというと、
IRセンサー ― PSoC ========== Arduino (===はI2Cでつなぐと思ってください)
という感じでつないで、
利点①Arduinoの少ないアナログ入力を節約でき、1つのArduinoでたくさんのIRセンサーと2本の線だけでつなぐことができる
利点②アナログでないので、(PSoCとArduinoの間の線が長くても)モーターからの外部ノイズの影響を受けにくい(たぶん・・)
利点③外付け部品がほとんどいらない
と考えているからです。
といいながら想像だけでIRセンサー部分がまったくできていないのですが・・・
早くI2C通信を終えてLPF(ローパスフィルタ)に移りたいと思います。

2010年11月14日 (日)

高校生車座フォーラム

高校生車座フォーラムというイベントがあって行ってきました。
いろんな分野の研究者と高校生が輪になっていろんな話をするというイベントです。
京都大学女性研究者支援センター主催ですが、男子女子関係なく参加できます。

4グループに分かれました。僕の入ったグループは3人の研究者と7人の高校生でいろんなことを話しました。
研究者はどんな仕事か、理学部と工学部はどう違うのか、研究者が研究しているテーマとの出会いなどを聞きました。
いろんな分野があって、研究者は狭く深く研究するけれども、その先にはいろんな分野と繋がっているんだということが分かりました。
研究者は自分のやりたいことをとことん突き詰めていっているんだと思いました。
また、学生時代での大学の先生方とのめぐり合いというものも自分の将来の研究テーマに関わってくるんだということとかも知りました。
他にもいろんなことを聞きました。

いろんな分野に目を向けることができてとても世界が広がりました。これからもいろいろな分野のことを吸収できたらいいなと思います。

金曜日のことですが、理科室にあるオシロスコープを初めて使わさせてもらいました。赤外線リモコン受信モジュールがパルスボール(ロボカップジュニアサッカーB部門で使われる公式ボールで赤外線を発光する)の光を受けてどのような信号を受けているのかを目で見ることができました。
PWMのデューディー比がボールとの距離によって変化するのがすごく分かりやすく見えました。

2010年11月11日 (木)

I2C通信によるArduinoと外部EEPROMの接続成功&PSoCの超音波センサの想像

I2C通信によるArduinoと外部EEPROMの接続に成功しました。使用したEEPROMはマイクロチップ社の24LC64です。

EEPROMのデーターシートを読んでがんばってプログラムを作ったのですが最初全く動きませんでした。
ひとつづつうまく動かない原因となるものを探していったのですが、まずは、EEPROMのアドレスはきちんと合っているということは確認できたのですが、うまく動かない原因はなかなか見つかりませんでした。
いろいろ検索していると、あるyou tubeの動画を見つけました。
自分のプログラムと照らし合わせてみると、delay(5);を送信と受信とかの間に挟んでいないことに気づき、半信半疑でやってみたら成功しました!!
たったそれだけなのに原因を見つけるのは大変です。
ただ、なぜdelayを入れなければいけないのかはまだ分かりません。

ロボットのデータロガーが取れたらまあ便利かなと思ってやったんですが、モーターもIRセンサーも方位センサーもまったくできていないのに僕はいったい何を目指しているのでしょうか・・・? 早くIRセンサーとかやらないと間に合わない・・・

ちなみにArduinoのWireライブラリは再度開始条件は使用できないみたいなのですが、停止条件を出したあと、何ミリ秒か空けて、開始条件を出せばEEPROMのデーターは読み込めるようです。

超音波センサの話ですが、PSoCマイコンで距離を計算してArduinoに送るのはやめようと思います。PSoCは難しいです!というわけでArduinoからPSoCに送信のタイミングを送信してPSoCは超音波が返ってきたと感知したらArduinoに送る、つまり、Arduinoで時間を計測して距離をだそうと思います。
メインArduinoとPSoCの超音波センサとの間にはスレーブArduinoを別に用意してそれに計算させようと思います。

Arduinoはスタートできるタイマーは僕が探した限り見つからなかったのですが、プログラムを開始(つまり電源を入れたとき)からの時間をμ秒で返してくれる関数があるので(micros)それを使おうと思います。最小分解能が4μ秒なので、音速340m/sのとき1.36mmの分解能で距離が測れるはずです。

まあ要するに難しいPSoCを頑張るよりもできるところはArduinoに任せてしまおうということであります。

2010年11月 8日 (月)

380モーター??

今年のロボカップの世界大会前からタミヤの380ギヤードモーターに目をつけていたのですが、タミヤのギヤヘッド用 380モーターを購入したら、モーターに
STANDARD MOTOR
RP380-ST
という印刷があったので、マブチじゃないの?と思いながら型番を検索してみるとでてきました。
http://www.standardmotor.net/sc_webcat/ecat/product_view.php?lang1&cat=1&id=68&page=1
上のリンクです。
タミヤのホームページに載っているスペックと全然違います。早速タミヤに問い合わせてみるとどうやらきちんと把握できていないようです。でも確実にホームページと実際のスペックが違うということで、返品させてもらうことができました。
STANDARD MOTORというメーカーのスペックは上のリンクとマブチのホームページによると出力がマブチよりもかなり弱いと思われます(最大トルク時の電流は10倍近く異なります)。

さてさて、マブチの380は出力が強いのでいいんですが、マブチのホームページによるとどうやら進角仕様のようです。たぶん逆回転もできるとは思いますが正回転より遅いと思うのでオムニの場合スピードコントロールが大事になってきそうです。
それと380用の金属ピニオンギヤが見つかりません・・

他のギヤードモーターも探してみましたが”これだ!!”というものは見つからず・・
マクソンモーターは予算の関係で厳しいです。
モーターが一番の難関かもしれません。

というわけで来年モーターをどうするか、いまだに検討中です。。

2010年11月 4日 (木)

ArduinoとPSoCとのI2C通信成功!!

ArduinoとPSoCとのI2C通信が成功しました!
3時間弱、格闘して、やっと成功したのです!うれしい!3時間弱なのにとーっても長い道のりだった気がします。

今回実験したものは
①ArduinoがマスタでPSoCがスレーブ
②ArduinoとPSoCにそれぞれLEDとスイッチを1つずつつなぐ
③ArduinoとPSoCとの間はGND、VDD、SCL、SDAの4本だけでつなぐ
④Arduinoのスイッチを押したらPSoCのLEDが点灯し、PSoCのスイッチを押したらArduinoのLEDが点灯する
こういう単純なものです。

今回、成功するまでのバグを書きます。
①PSoCのLEDにつなぐピンを間違えていた→直した
②PSoCで内部プルアップがうまくいかなかった→内部プルアップは外して外部プルアップにした
③PSoCでのスイッチ割り込みがうまくいかなかった→割り込みはせず普通の入力にした
④PSoCで②の割り込みの設定を消すときにM8C_EnableGInt;というコマンドも消してしまってI2Cができなくなった→消してしまったM8C_EnableGInt;を初期化の位置に追加した

いまだに②と③は謎のままです・・・(とりあえずI2Cができたので今回はこれでよし!)

これらの目的は
①超音波センサーからArduinoに信号を送る際に、アナログ電圧でするとノイズによって距離の誤差が増えてしまうのではないかと考え、デジタルだとノイズの影響が少ないので、I2C通信で送れるようにするため。
②Arduinoはアナログ入力が少ないのでIRセンサーもI2Cにできれば、4本だけをArduinoにつなぐだけでよくなるから。
なお、目的①のノイズの影響についてですがアナログが劣化するというのはあくまで想像です。ただ、ノイズに強くなると強いモーターが使えて、ノイズによる誤動作の心配がいらなくなるかなと。

マスターは1個の予定なのでたぶん競合の心配はいりません。(というかArduinoって競合調停の機能ってあるんでしょうか?どっちでもいいですが・・・)

あとArduinoのI2Cってたぶん再度開始条件って使えないんですかね?(こっちは外部EEPROM用)
停止条件のあと開始条件を出すしかない気がするのですが・・

2010年11月 3日 (水)

PSoCでの超音波距離センサー

本のとおりにブレッドボードで配線してプログラムを入れたら、PSoCでの超音波距離センサーがとりあえずできました。
距離を測ったら温度補正をして液晶に表示されます。

最初に校正(キャリブレーション)をしないといけないということを知らず、10050mmとか液晶に表示されて少し戸惑いました。

次の課題は
①近距離も測定できるようにすること
②M8C(CPUコアのこと)から送信のタイミングを指示できるようにすること
③I2CでArduinoに送れるようにすること
④周波数25kHzと32kHzの超音波センサーで測定できるようにすること
ちなみに④が目的です

2010年11月 2日 (火)

Arduinoの液晶表示は要注意!!

はっきり言うと、2行表示させるためには、setup()の中の一番最初に
lcd.begin(16,2);
と宣言しておく必要があります。
これをしないとlcd.setCursor(0,1);と1列目2行目にカーソルを移しても、
2行目は表示されません!
(みんな知ってるのだろうか!?)
1行目しか表示されず僕はかなり戸惑いました。

これさえ気をつければArduinoは涙が出そうなくらいカンタンです!
カンゲキ!!

以下メモです。

※カーソルは書くたびに次に移動する。

BIN:2進法
OCT:8進法
DEC:10進法
HEX:16進法

  lcd.setCursor(0, 1);
  lcd.print(count, DEC);
  count = count + 1;
は約0.0018秒で動作する。

2010年11月 1日 (月)

Arduino初体験

Arduinoを初体験しました(かなり遅れている気が・・・)

LEDをチカチカさせました。

スイッチを入力してみました。

ほんの少しの発見その①
while()の中には関数;のカタチで入れるとエラーがでるが、関数(セミコロンなし)だとうまくいく。
例:スイッチが押してある間だけ動作Aをする。
while(digitalRead(Switch)){
  動作A
}

ほんの少しの発見その②
Switch構文を初めて使ってみた。
使いやすいし見やすい。

ほんの少しの発見(?)その③
外部EEPROM(I2Cで送受信)を使えるような気がする。
あとArduinoとPSoCとをI2Cで通信する仕方が分かった気がする。
想像と現実は違うけど・・・