

SpresenseとBMI160という加速度センサを使って、microSDカード上にセンサ出力値を記録するコードを作成したいのですが、上手くいっていません。

指定のサンプリングレートでセンサ出力値をcsvファイル上に128データごとに記録させたいです。  
下記のコードで試しているですが、どのような問題点がありますでしょうか？  
実際に動かすと、128データがすべて同じ値となってしまいます。

arduinoに関する知見が浅いので、参考コード等ございましたら丁寧に説明してくださると大変助かります。

[code]

    #include <BMI160Gen.h>
    #include <CurieIMU.h>
    #include <SDHCI.h>
    SDClass SD;
    
    #define FFT_LEN 1024
    
    void saveData(float* pDst, int dsize, int quantity) {
      //　savedata関数の内容
      //　pDstはデータへのポインタ、次項は記録データのサイズ、次項はデータ保存数
      static int gCounter = 0;  // ファイル名につける追番
      char filename[16] = {};
    
      // 指定された保存数以上に達したら何もせずにリターン
      if (gCounter > quantity) {
        Serial.println("Data accumulated");
        return;
      }
    
        // データ保存用ファイルを開く
      sprintf(filename, "data%03d.csv", gCounter++);
      // すでにファイルがあったら削除する
      if (SD.exists(filename)) SD.remove(filename);
      // ファイルをオープン
      File myFile = SD.open(filename, FILE_WRITE);
      // データの書き込み
      for (int i = 0; i < dsize; ++i) {
        myFile.println(String(pDst[i],6));
      }
      myFile.close();  // ファイルをクローズ
      Serial.println("Data saved as " + String(filename));
    }
    
    
    void setup() {
      Serial.begin(230400);
      while (!Serial);
    
        // SDカードの挿入を待つ
      while (!SD.begin()) {
        Serial.println("Insert SD card");
        };
    
      Serial.println("Initializing IMU device...");
      BMI160.begin();
    
      BMI160.setAccelerometerRange(2);
      BMI160.setAccelerometerRate(1600);
    
      // 計測開始前に加速度測定範囲、加速度出力レート確認  
      float a = BMI160.getAccelerometerRate();
      float b = BMI160.getAccelerometerRange();
      Serial.println(a);
      Serial.println(b);
    }
    
    void loop() {
      float *ax;
      float *ay;
      float *az;   //scaled accelerometer values
      BMI160.readAccelerometerScaled(*ax, *ay, *az);
    
      //シリアルモニタ上に加速度をそのまま表示
      //Serial.print("a:\t");
      //Serial.print(ax);
      //Serial.print("\t");
      //Serial.print(ay);
      //Serial.print("\t");
      //Serial.print(az);
      //Serial.println();  
    
      //microSDにFFT_LEN/8分のデータを記録したcsvファイルを10回保存
      saveData(az, FFT_LEN/8, 9);//z軸の出力を保存
    }
    
[/code]


CC BY-SA 4.0
2023-01-20T07:36:46.573
93471
2023-01-24T08:42:16.577
2023-01-20T08:08:07.483
3060
55839
question
spresense arduino
microSDカードへのデータ収集コードが上手く動作しない


`void loop()` 内ですが `float *ax;` ということは `float`
を格納する変数は存在せず、ポインタしかありません。ポインタが有効なメモリを指していないので誤動作しています。組み込みマイコンの場合、メモリ空間のほとんどには何もマップされていないうえに保護機構もない場合が多く、そうなると無効なアドレスには書き込めず読んだらゴミ値（たいてい同じ値）が得られるので提示な挙動を示すでしょう。

具体的にどう直せばよいかは `readAccelerometerScaled()`
の仕様次第なのでなんともいえないのですが、まあ普通には真に配列（なり普通に `float` 変数なり）を用意することになるでしょう。

# 提示 `readAccelerometerScaled()` の使い方が極めておかしいっス。そっちも要デバッグかもしれない。

* * *

[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") なんだったら非 const
参照な引数もアリなのか。 `readAccelerometerScaled(float& x, float& y, float& z)`
なのだったら今のコードでも別におかしくないっスね（オイラなら書かないけど）。まあ結論は変わらないです。ポインタ変数でなく真に `float`
な変数を用意するように直してください。

[code]

    float ax, ay, az;
    BMI160.readAccelerometerScaled(ax, ay, az);
    
[/code]


CC BY-SA 4.0
2023-01-20T07:58:42.940
93473
2023-01-20T22:02:44.370
2023-01-20T22:02:44.370
8589
8589
93471
answer


microSDカードへ書き込むためのデータをメモリに保持しておく必要があるので、  
`saveData()`関数や`setup()`関数はそのままで、`loop()`関数を次のように変えれば  
やりたいことが実現できると思います。

[code]

    float az[FFT_LEN/8];
    void loop() {
      float ax;
      float ay;
      static int cnt = 0;
      BMI160.readAccelerometerScaled(ax, ay, az[cnt]);
      cnt++;
    
      //microSDにFFT_LEN/8分のデータを記録したcsvファイルを10回保存
      if (cnt == FFT_LEN/8) {
        saveData(az, FFT_LEN/8, 9);//z軸の出力を保存
        cnt = 0;
      }
    }
    
[/code]

128データ分のメモリ配列`az[FFT_LEN/8]`を用意して、  
128個のデータが溜まったら`saveData()`でmicroSDカードへ書き込んでいます。


CC BY-SA 4.0
2023-01-24T08:42:16.577
93544
2023-01-24T08:42:16.577
31378
93471
answer