« 高校生車座フォーラム | トップページ | I2Cの仕様書の日本語バージョン???? »

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(ローパスフィルタ)に移りたいと思います。

« 高校生車座フォーラム | トップページ | I2Cの仕様書の日本語バージョン???? »

Arduinoマイコン」カテゴリの記事

PSoCマイコン」カテゴリの記事

ロボットのソフトウェア」カテゴリの記事

コメント

こんにちわ、ぽよこまだんなです

すみません、何を悩んでいるのかよく把握できませんでしたが、
PSoC側はバッファ内のデータを[0]から順番にマスタに返します
ですので、バッファのクリアとArduino側のreceiveの順番が揃っていれば
「最初に受信したデータ=先頭のデータ」となるのですが
複数バイトの場合、途中で転送エラーが発生するとこの順番がずれてしまいます
そこで、マスタからはスレーブに送信開始のタイミング(バッファクリアのタイミング)
を教えてやる必要があるのですが、PSoCのI2CHWではリード要求でバッファクリアを
行うと間に合わずに転送後にバッファのクリアが行われます

そんな訳で
マスタから転送するよの指示を送り、その指示でスレーブはバッファをクリアして
その後、マスタからリードすると
最初の読み込みデータ=先頭のデータ
となると思います

ありがとうございます。
ということは、転送エラーの後にマスタ(Arduino)がスレーブ(PSoC)に送信要求すると、スレーブは送信の準備(バッファのクリア)ができていないので、マスタはうまく受信できない。だからあらかじめスレーブは送信の準備(バッファのクリア)をしておかないといけない。よって、バッファをクリアせよ!(あらかじめこの言葉を決めておく)とマスタがスレーブに命令した後で、マスタは送信要求すれば、以前の転送エラーの後でもいつでも送信要求されたときにはスレーブは送信の準備(バッファのクリア)ができている状態になるということですか?
よろしくお願いします。

はい、そういう感じになります。
ようはいきなり受信するとスレーブのどのアドレスのデータなのかわからなくなるので、
最初にマスタからタイミングを指示して、スレーブは指示に合わせましょう
と言った取り決めを作っておきましょう
ということです

ありがとうございます。

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1389908/37684613

この記事へのトラックバック一覧です: ArduinoとPSoCのI2C通信(複数バイト):

« 高校生車座フォーラム | トップページ | I2Cの仕様書の日本語バージョン???? »