Seeeduino XiaoでSPI通信

Seeeduino XiaoでSPI通信をさせてみたくて、手元に落ちていた秋月電子のLPS331APモジュール(AE-LPS331)を動かしてみました。このモジュールはすでに販売終了していて秋月電子のWebサイトには資料の掲載がなく、資料を探すのに少々苦労しました。

動作させるにあたって、LPS331APモジュール上の半田ジャンパ(I2Cのプルアップ用)を外して以下の接続を行いました。

信号名AE-LPS331ピン番号Seeeduino Xiao接続先備考
VDD1(1.71〜3.6V)3V3Xiao⇒LPS331で電源供給
SPC2SCKSPIクロック
SDI3MOSISPIデータ(Xiao⇒LPS331)
SDO4MISOSPIデータ(LPS331⇒Xiao)
CS5D1チップセレクト
GND8GNDGND

Seeeduino Xiaoの開発環境はArduino環境を使用しました。環境はSeeed Studioのページの書いてある通りにセットアップしました。(今考えれば CircuitPython で良かったのかもしれません)

LPS331APを動かすソースコードはGoogle検索で見つかった光永 法明先生のページ「ST micro のデジタル気圧センサ LPS331AP を使う(SPI接続)」という記事に掲載されているものをそのまま使わせて頂きました。(LPS331APを動かすのが目的ではなく、SPIの信号を出すのが目的なので・・・)

実際には、下記の通り、CS端子(SS端子)の設定の変更とLEDを点滅させるコードを追加しています。

#include <SPI.h>

const int LPS331AP_CS = 1;
int _SS = 1;      // ~CSをD1に接続

const byte LPS331AP_ADDR = B1011100;  // SA0 = GND
//const byte LPS331AP_ADDR = B1011101;// SA0 = VDD_IO

const byte LPS331AP_WHOAMI = 0x0f;
const byte LPS331AP_CTRL1 = 0x20;
const byte LPS331AP_CTRL2 = 0x21;
const byte LPS331AP_CTRL3 = 0x22;
const byte LPS331AP_P_LL = 0x28;
const byte LPS331AP_P_L  = 0x29;
const byte LPS331AP_P_H  = 0x2A;
const byte LPS331AP_T_L  = 0x2B;
const byte LPS331AP_T_H  = 0x2C;

const byte LPS331AP_RW = 0x80;
const byte LPS331AP_MS = 0x40;

void LPS331AP_write(byte reg, byte val)
{
  digitalWrite(LPS331AP_CS, LOW);
  SPI.transfer(reg);
  SPI.transfer(val);
  digitalWrite(LPS331AP_CS, HIGH);
}

byte LPS331AP_read(byte reg)
{
  byte ret = 0;

  digitalWrite(LPS331AP_CS, LOW);
  SPI.transfer(reg | LPS331AP_RW);
  ret = SPI.transfer(0);
  digitalWrite(LPS331AP_CS, HIGH);
  
  return ret;
}

void setup() {
  digitalWrite(_SS, HIGH);
  pinMode(_SS, OUTPUT);
  
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8); // 8MHz/8 = 1MHz; (max 10MHz)

  Serial.begin(115200);
  while (!Serial) {}

  Serial.println(LPS331AP_read(LPS331AP_WHOAMI), HEX); // should show BB

  LPS331AP_write(LPS331AP_CTRL1, B10010000);
                             //   |||||||+ SPI Mode selection
                             //   ||||||+- DELTA_EN
                             //   |||||+-- BDU: block data update
                             //   ||||+--- DIFF_EN: interrupt circuit enable
                             //   |+++---- ODR2, ODR1, ODR0 (1Hz)
                             //   +------- PD: 0: power down, 1: active
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  long P;
  short T;
  float p, t;

  P = LPS331AP_read(LPS331AP_P_H);
  P = (P << 8) | LPS331AP_read(LPS331AP_P_L);
  P = (P << 8) | LPS331AP_read(LPS331AP_P_LL);

  T = LPS331AP_read(LPS331AP_T_H);
  T = (T << 8) | LPS331AP_read(LPS331AP_T_L);

  p = P;
  p = p/4096.0;
  
  t = T;
  t = 42.5 + t/480.0;
  
  Serial.print(P);    // pressure (reading)
  Serial.print(" ");
  Serial.print(T);    // temperature (reading)
  Serial.print(" ");
  Serial.print(p);  // pressure in [mbar]/[hPa]
  Serial.print(" ");
  Serial.println(t);  // temprerature in [`C]

  digitalWrite(LED_BUILTIN, HIGH); 
  delay(500); 
  digitalWrite(LED_BUILTIN, LOW); 
  delay(500);  
}

で、動かしてみたのですが、理由がよくわかりませんが、Arduino環境のシリアルモニタでは1秒程度で表示が止まってしまいます。不思議なことに、

$ tail -f /dev/ttyACM0 
4124716 -5507 1007.01 31.03
4124388 -5508 1006.93 31.02
4124483 -5508 1006.95 31.02
4124639 -5496 1006.99 31.05
4124199 -5532 1006.88 30.98
4124532 -5506 1006.97 31.03
4124496 -5508 1006.96 31.02
  :

とすると、問題なく動作し続けるのですが・・・。
これに嵌って、余計な時間を費やしてしまいました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)