Arduinoで、「センサーのSPI通信」と「オンボードのUSBホストポートのSPI通信」を同時に使いたい!
■目的
現在「Arduino MEGA ADK」を使用しております。
「Arduino MEGA ADK」では基板上にUSBホストポートが付いております。←Android端末に接続するために使用。
また、複数のセンサをSPI通信にてArduinoに接続しております。←使用。
** 目的は、複数のセンサ値をArduinoで取得し、値をAndroidに渡して処理をすることです。**
(※センサはI2C通信とSPI通信に対応していますが、I2C通信だと2つまでしか同時に使用できないようです。合計8つまでの値を読み取ってAndroidに値を引き渡すのが目的のため、SPI通信を使用しております。)
■現状
○ USBポートからAndroidに値を引き渡すことは達成済み
○ 複数のセンサからArduinoで値を取得することも達成済み
※しかし、「Arduinoで複数センサの値を取得 → Androidに引き渡す」 と処理を連結させると、Android端末への接続が切れてしまいます。
■原因を突き止めました。
Arduinoのオンボードで付いているUSBホストポートはSPI通信で接続しているようでした。
そのため、複数センサの値をSPI通信にて取得する処理と干渉してしまっているようでした。
(I2C通信であれば、値を読み取ってAndroidに値を引き渡せましたが、2つのセンサしか接続できないため断念。)
■参考サイトの引用
USB Host: MAX3421E. The MAX3421E comunicate with Arduino with the SPI bus. So it uses the following pins:
Digital: 7 (RST), 50 (MISO), 51 (MOSI), 52 (SCK).
NB:Please do not use Digital pin 7 as input or output because is used in the comunication with MAX3421E
Non broken out on headers: PJ3 (GP_MAX), PJ6 (INT_MAX), PH7 (SS).
■思考錯誤
SS(CS)はデフォルトのDigital10や、その他のポートで試してみました。
しかし、SPI通信でセンサから値を取得すると、Androidとの接続が切れてしまいます。
(なぜか、センサのSSの配線を繋げなければAndroidとの接続ができます。)
■推測
そのため、当初疑っていた以下の様なSPI通信の初期設定部分が原因ではない可能性が出てきました。
SPI.setBitOrder(MSBFIRST) ; // ビットオーダー
SPI.setClockDivider(SPI_CLOCK_DIV8); // クロック(CLK)
残念ながら初心者の私にはお手上げ状態です。
お力添え頂けますと幸いです。
よろしくお願いします。
■センサ(気圧センサ LPS331AP)の配線
3.3V:Arduinoの3.3V
GND:ArduinoのGND
MISO:Digital50にあたる場所
MOSI:Digital51にあたる場所
SCK:Digital52にあたる場所
SS(CS) → D10やD3やD40など様々試してみたが変化なし
■症状を改めて整理
Arduino上の配線を全て取り払い、AndroidにのみUSBホストから接続 → USBホスト使用可能
Arduinoにセンサを配線し、SS(CS)ポートを接続しない → USBホスト使用可能
Arduinoにセンサを配線し、SS(CS)ポートを接続する → USBホスト使用できない!(おそらくSPI通信が干渉)
■ソースコード(一部省略しております。)
#include <SPI.h>
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
int CS_i = 4;//CS(SS)のポート番号
/////////////////////////////////////////////
///Androidに値を送るための宣言(省略)////
/////////////////////////////////////////////
void setup()
{
// シリアルモニターの設定
Serial.begin(9600);
acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
Serial.println("\r\nStart");
// SPIの初期化
SPI.begin() ; // SPIを行う為の初期化
SPI.setBitOrder(MSBFIRST) ; // ビットオーダー
SPI.setClockDivider(SPI_CLOCK_DIV8); // クロック(CLK)をシステムクロックの1/8で使用(16MHz/8)
//シリアルモニタを開いたら、セットアップをやり直す!?
while (!Serial) {}
digitalWrite(CS_i, HIGH); //通信終了状態に
pinMode(CS_i, OUTPUT); // 出力に設定
//センサが認識していることを確かめる。
Serial.println(LPS331AP_read(CS_i, LPS331AP_WHOAMI), HEX);
//センサの設定を書き換える。
LPS331AP_write(CS_i, LPS331AP_CTRL1, B10010000);
delay(1000);
}
//センサへデータを書き込む関数
void LPS331AP_write(int CS, byte reg, byte val)
{
digitalWrite(CS, LOW); //LOWにすることで通信開始
SPI.transfer(reg);
SPI.transfer(val);
digitalWrite(CS, HIGH); //HIGHにすることで通信終了
}
//センサから値を受信する関数/
byte LPS331AP_read(int CS, byte reg)
{
byte ret = 0;
digitalWrite(CS, LOW); //LOWにすることで通信開始
SPI.transfer(reg | LPS331AP_RW); //読み込むデータを指示
ret = SPI.transfer(0); //データを取得
digitalWrite(CS, HIGH); //HIGHにすることで通信終了
return ret;
}
void loop()
{
/////////////////////////////////////////////////
///センサから値を取得する処理 (省略)////
//Androidに値を送る処理 ////
////////////////////////////////////////////////
}

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/11/12 13:25
2015/11/12 14:02