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

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

ただいまの
回答率

88.33%

Arduinoプログラムの高速化

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 5,341

delaxzone

score 8

こんにちは.

Arduinoに関する質問です.

私は今,加速度センサで読み取った値をSDカードに保存するという電子工作をしています.
SDへの保存は5000Hzを目標としていますが,現在のスケッチでは約50Hz(1秒間に50個)程のデータ取得が限界です.
そこで現在のスケッチを改善したいと考えています.

delay(20)にして実験すると,SDにはきちんとデータが書き込まれまずが,
それ以下の数値になると,処理が追い付かず保存が間に合いません.
現在はサイクル毎にファイルを書き込むようなスケッチにしています.
今後は,

加速度センサから数秒間(例えば3秒)データ採取→SD保存

といったプログラムを作成したいのですが,それは可能なのでしょうか.

使用したものは以下のとおりです.

・Arduino UNO
・SD Card Shield
・SDカード 32GB - FAT32
・三軸加速度センサ ADXL375
・I2Cバス用双方向電圧レベル変換モジュール

です.

以下にスケッチを掲載します.

お手数だとは思いますが,改善点などご指摘いただければ幸いです.
よろしくお願いします.

※以下スケッチ掲載

include <SD.h>

include <Wire.h>

//ファイル名をrecordFileで定義
File myFile;

//シールドの番号指定
const int chipselect = 4;

//演算用変数型の定義
float senX , senY , senZ = 0;

//デバイスアドレス(スレーブ)
uint8_t DEVICE_ADDRESS = 0x1D;

//XYZレジスタ用のテーブル(6byte)
uint8_t RegTbl[6];

void setup()
{
//SSピンを出力に設定
pinMode(SS,OUTPUT);

Serial.begin(9600);
//マスタとしてI2Cバスに接続する
Wire.begin();

//DATA_FORMAT(データ形式の制御)
Wire.beginTransmission(DEVICE_ADDRESS);

//DATA_FORMATのアドレス
Wire.write(0x31);

//最大分解能モードに「±200G」
Wire.write(0x0b);
Wire.endTransmission();

//POWER_TCL(節電機能の制御)
Wire.beginTransmission(DEVICE_ADDRESS);
//POWER_CTLのアドレス
Wire.write(0x2d);
//測定モードにする
Wire.write(0x08);
Wire.endTransmission();

//SDカードスロットのチップセレクト番号にてSDライブラリを初期化
//初期化に失敗したらエラーを出す
if(!SD.begin(chipselect))
{
Serial.println(F("カードが見つかりません"));
return;
}

//成功したら完了を表示する
Serial.println("カード初期化に成功しました");
}

void loop()
{
//XYZの先頭アドレスに移動する
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(0x32);
Wire.endTransmission();

//デバイスへ6byteのレジスタデータを要求する
Wire.requestFrom(DEVICE_ADDRESS,6);

//6byteのデータを取得する
int i;
for(i=0;i<6;i++)
{
while(Wire.available()==0){}
RegTbl[i]=Wire.read();
}

//データを各XYZの値に変換する(LSB単位)
int16_t x = (((int16_t)RegTbl[1]) << 8) | RegTbl[0];
int16_t y = (((int16_t)RegTbl[3]) << 8) | RegTbl[2];
int16_t z = (((int16_t)RegTbl[5]) << 8) | RegTbl[4];

//SDに書き込むためにSDB値をm/s^2値に変換
senX = x * 0.6533;
senY = y * 0.6533;
senZ = z * 0.6533;

//ログを書き込むためにファイルを開く
myFile = SD.open("test.txt",FILE_WRITE);
if(myFile)
{
Serial.println("test.txtをSDに書き込んでいます");
myFile.print( senX );
myFile.print(",");
myFile.print( senY );
myFile.print(",");
myFile.println( senZ );

myFile.close();
Serial.println("書き込みが完了しました");
}
else
{
Serial.println(F("error opening test.txt"));
}

delay(20);
}

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

まず、
1.SDカードの書き込みでどれだけ時間かかるかを測定
この時点で5000点/秒の書き込み速度が確保できないとどーしよーもありません。
これをクリアできるめどがついたなら、

2.IICアクセスを割り込み駆動形に作り変えて、バックグランドでデータ取得できるようにする
と、これを実装し、0.2ms 以内でのデータ取得できるのを確認
これまたこれを満足できなければムリムリ

3.内蔵タイマで0.2msec周期のトリガでIIC起動をかける

という手順になります。
まあ、おそらくはCPUと周辺デバイスのデータシートを睨みながらスクラッチでのプログラムとなりますが、頑張ってください

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/03 17:22

    ご回答ありがとうございます.
    y_waiwaiさんから頂いた手順のもと実験を行ってみようと思います!

    キャンセル

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

  • ただいまの回答率 88.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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