質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

受付中

ADXL345加速度センサの読み出しに時間がかかる。

masay0
masay0

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2回答

0リアクション

1クリップ

935閲覧

投稿2021/09/13 06:03

前提・実現したいこと

 ADXL345加速度センサICで3軸方向の加速度を定期的に計測し、CPUのメモリに保存したい。

発生している問題・エラーメッセージ

 FFT処理を行うために、1回に取るデータは256組または512組としたいが、ADXL345から連続的に読み出すデータの組数がある程度以上になると、読み出しにかかる時間が異常に長くなる。
下記ソースコード中のloop()関数中の

for (i = 0; i < 128; i++) {    adxl345_get_axi(accData[i]);  // 加速度データ3軸分を読み出す }

 forループ回数が128以下の場合、読み出しにかかる時間は、約120μs×ループ回数程度ですが、回数を150回程度にすると、約1ms×ループ回数程度に増えます。回数を256回にすると、forループから帰ってこなくなります。

該当のソースコード

 ソースコード(下記)

/* Name: ADXL345 Reading Sample for Wio LTE JP.ino Created: 2021/09/09 9:33:14 Author: */ #include <Wire.h> #include <WioLTEforArduino.h> WioLTE Wio; #define ADXL345_I2C_ADRESS 0x53 // I2C address of ADXL345 #define ADXL345_DATAX0 0x32 // Output data register #define ADXL345_SCALE_FACTOR 1 // LSB = 4m[G] #define ADXL345_DEVID 0x00 // Device ID register #define ADXL345_DEV_ID 0xe5 // Device's ID #define ADXL345_POWER_CTL 0x2d // Power control register #define ADXL345_INT_SOURCE 0x30 // Interrupt source register, bit 7 is data-ready #define ADXL345_BW_RATE 0x2c // Bandwidth register // The setup() function runs once each time the micro-controller starts void setup() { SerialUSB.begin(115200); delay(2000); SerialUSB.println("Read ADXL345"); SerialUSB.println("Initilize Wio LTE JP"); Wio.Init(); SerialUSB.println("Setup I2C"); Wire.begin(); Wire.setClock(1000000); // I2Cのクロックを1MHzに設定 SerialUSB.println("Initilize ADXL345"); //ArduinoとADXL345のI2C通信確認 uint8_t ucData; adxl345_get_data(ADXL345_DEVID, &ucData, 1); //デバイスID取得 if (ucData != ADXL345_DEV_ID) { SerialUSB.println(F("I2C connection fail.")); } //ADXL345の帯域を3.2kHzに設定 adxl345_set_data(ADXL345_BW_RATE, 0x0f); //ADXL345を測定モードへ変更 adxl345_set_data(ADXL345_POWER_CTL, 0x08); delay(100); SerialUSB.println("ADXL345 Initialized, Start measuring."); } // Add the main program code into the continuous loop() function void loop() { int i; unsigned long time1,time2,time3; float accData[512][3]; time1 = micros(); // 読み出し開始時刻(μs) for (i = 0; i < 128; i++) { adxl345_get_axi(accData[i]);  // 加速度データ3軸分を読み出す } time2 = micros(); // 3軸×512データ 読み出し完了時刻 SerialUSB.print("Read time:"); SerialUSB.print(time2 - time1); // ADXL345の読出しにかかった時間を表示 // 読出し保存したデータの先頭を確認のために表示 for(i=0;i<2; i++){ SerialUSB.print(" X:"); SerialUSB.print(accData[i][0]); SerialUSB.print(" Y:"); SerialUSB.print(accData[i][1]); SerialUSB.print(" Z:"); SerialUSB.print(accData[i][2]); SerialUSB.println(); delay(100); } delay(10000); // 10秒間待ち } /*ADXL345のレジスタデータ書き込み関数*/ void adxl345_set_data(uint8_t ucReg, uint8_t ucData) { Wire.beginTransmission(ADXL345_I2C_ADRESS); Wire.write(ucReg); Wire.write(ucData); Wire.endTransmission(true); } /*ADXL345のレジスタデータ読み込み関数*/ void adxl345_get_data(uint8_t ucReg, uint8_t* ucData, uint8_t ucSize) { uint8_t cnt = 0; Wire.beginTransmission(ADXL345_I2C_ADRESS); Wire.write(ucReg); Wire.endTransmission(false); Wire.requestFrom(ADXL345_I2C_ADRESS, ucSize, true); while (Wire.available()) { ucData[cnt] = Wire.read(); cnt++; } } /*ADXL345 X,Y,Zデータ取得関数*/ void adxl345_get_axi(float* pfData) { uint8_t ucBuf[6]; int16_t acc[3]; adxl345_get_data(ADXL345_DATAX0, ucBuf, 6); acc[0] = ((int16_t)ucBuf[1] << 8) | ucBuf[0]; acc[1] = ((int16_t)ucBuf[3] << 8) | ucBuf[2]; acc[2] = ((int16_t)ucBuf[5] << 8) | ucBuf[4]; pfData[0] = acc[0] * ADXL345_SCALE_FACTOR; pfData[1] = acc[1] * ADXL345_SCALE_FACTOR; pfData[2] = acc[2] * ADXL345_SCALE_FACTOR; }

試したこと

 1回に読み出すデータの組数を変化させて、一組のデータを読むのに必要な時間を計測した。
組数が少ないうちは、一組当たり120μs程度で安定しているが、組数を増やしていくと、一組当たりの読み出し時間が急激に長くなる。

補足情報(FW/ツールのバージョンなど)

 使用している開発環境: Aruduino IDE (Ver. 1.8) (C言語)
使用しているボード:  Seeed社 Wio LTE JP Version
加速度センサ:     ACCEL ADXL345 (I2C接続、SwitchScience通販で購入)

ここにより詳細な情報を記載してください。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

ozwk

2021/09/13 06:12

Wire.setClock(1000000); // I2Cのクロックを1MHzに設定 データシートより抜粋 : > 標準(100 kHz)と高速(400 kHz)のデータ転送モードに対応します。
masay0

2021/09/13 06:20

ありがとうございます。 クロックを下げて試してみます。 CPUと外部デバイスの組み合わせによっては、クロックを上げても動作するとのことだったので、試験的に上げたり下げたりして試したのが、そのまま残っていました。
masay0

2021/09/14 04:56

有難うございました。 クロックを下げてみました。伝送速度は遅くなりましたが、結果は変わらずでした。
ozwk

2021/09/14 05:18

adxl345_get_axiの最初でも最後でもdelay(10)ぐらいを入れてみて (当然遅くはなると思いますが)読み出し数ごとの挙動を確認してみてください

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。