プロが教えるわが家の防犯対策術!

加速度センサADXL345、mbedを用いた速度計測を行いたいのですが、うまくいきません。
下記サイトを参考に加速度センサから値を抽出しました。加速度センサ静止時、Z軸は256を出力していた為、プログラミングより9.8を出力するようにしました。
https://developer.mbed.org/users/suupen/notebook …

その後、加速度センサをY軸上に動かした時の速度を計測する為、加速度を積分するプログラムを作成しました。
プログラミング一部

while(true){
double as =0;
double a =0;
double v =0;
accelerometer.getOutput(readings);
as = (int16_t)readings[1]*(9.8/256); //加速度センサY軸からの値256を9.8にする
v += as*0.1*1000; //加速度センサY軸からの値を時間で積分
printf("%0.1f[ms]\r\n",v);
wait(0.1);
}

このようにしてミニ四駆に加速度センサを取り付けましたが、速度は誤差が多くうまくとれませんでした。
どのようにすれば移動中の物体速度を抽出できるのでしょうか。

質問者からの補足コメント

  • 回答ありがとうございます。
    double v =0; をwhileの外に出してしまうと、速度値が常に足しあわされてしまいます。どのようにすればよいのでしょうか。

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/10/04 14:45
  • Y軸の加速度0の時は0と表示されます。(平らの床に加速度センサを置いた場合)
    Y軸上に90度傾けると256と表示されます。
    128とはどういうことでしょうか。

    また、Whileの外に出してしまうと常に足しあわされるため、加速度センサを動かさなくても値が足しあわされてしまいます。

    No.3の回答に寄せられた補足コメントです。 補足日時:2015/10/04 16:36
  • アドバイスしていただき有難うございます。
    加速度センサは水平である物体に設置します。
    物体はX軸上を動きますので、この時の速度を加速度センサで抽出したいと考えています。
    どのようにすれば速度が抽出出来るのでしょうか。加速度が取れているので時間で積分すれば出るはずなのですが、うまくいかず。

    よろしくお願い致します。

    No.4の回答に寄せられた補足コメントです。 補足日時:2015/10/04 17:29
  • 以下のようなプログラム修正にしました。
    int main()
    {
     ~省略~
    int readings[3] = {0, 0, 0};
    double v =0;
    while(true){
    double as =0;
    double a =0;
    accelerometer.getOutput(readings);
      as = readings[1]
    as *= 9.8/256;
    a += (0.11111)*(as-a);
    v += a*0.01*1000;
    printf("%0.1f[ms]\r\n",v);
    wait(0.01);
    }
    }
    こちらで宜しいでしょうか。

      補足日時:2015/10/04 23:44
  • なお、readingsはintで宣言しています。
    実は加速度センサの値が安定しない為、 a += (0.11111)*(as-a);でLPFを掛けているのですが物体を動かさずに値が足されてしまうのはLPFが原因なのでしょうか。

    No.6の回答に寄せられた補足コメントです。 補足日時:2015/10/04 23:45
  • なお、*=とはどういうプログラムなのでしょうか。

      補足日時:2015/10/04 23:49

A 回答 (11件中1~10件)

センサーには誤差が必ずあります。

更に、誤差にもさまざまの誤差があります。
(1)オフセット
 現在貴方が経験していますように、設置条件により何もないのにあるかのように0ではない値が検出される。
(2)線形誤差
 加速度が10の時に、センサー出力値が100だとして、加速度が2倍の20になった場合、センサー出力値が200にはならず、199の場合もあれば、201かもしれない
(3)シンメトリー
 加速度が10の時に、、センサー出力値が100だとして、加速度が-10(減速)になった場合、センサー出力値がー200にはならず、ー199の場合もあれば、ー201かもしれない
(4)環境によるブレ
 その時の温度により同じ加速度でも検出される値が異なる。あるいは振動によっても値が異なることがある。
(5)量子化誤差
 定期的にセンサー値を取得していますが、取得していない時のセンサー値は無視されています。その影響が反映されていません。

 このように様々な誤差を含んだセンサー値を積算するということは、誤差をどんどんと増やしているということです。
つまり、加速度センサーから速度を求めるのはとても難しいということです。これを経験させるために、課題を与えられたのかと思っていました。
    • good
    • 0

Vを求めてから


if(fabs(v) < 0.2){
v = 0.0;
}
で、いかがでしょうか。
fabs()が使えなければ
if((v > -0.2) && (v < 0.2)){
v = 0.0;
}

ところで、貴方のやられていることは、学校か何かの課題でやられていると思い、指導者の方の意思を尊重して決定的な事は申し上げないでいたのですが、その私の認識であっていますでしょうか。
趣味でとか、仕事でとかですと、申し上げなければならないことがあるのですが。
    • good
    • 0
この回答へのお礼

いえ趣味でやっております。
なお、教えていただいたようにプログラム変更しました。
水平時値はでなくなりましたが、速度はうまく測定できませんでした。
同じ速度のはずですが、速度波形はその都度違いました。
やはり加速度センサで速度計測は難しいのでしょうか。

お礼日時:2015/10/08 23:28

別IDからです。


足しあわされる原因はセンサが水平でも出力0以外が出力される為でした。
不感帯で-0.2~+0.2までの不感帯にしたいのですがどういうプログラムにすれば良いのでしょうか。
    • good
    • 0

解決いたしましたでしょうか。


センサーの微動対策ですが、センサー出力値に不感帯を設ける方法もあります。
センサー値の絶対値がある値以下なら0とするということです。
    • good
    • 0
この回答へのお礼

足しあわされる原因はセンサが水平でも出力0以外が出力される為でした。
不感帯で-0.2~+0.2までの不感帯にしたいのですがどういうプログラムにすれば良いのでしょうか。
ifではうまくいかず

お礼日時:2015/10/06 23:49

加速度センサーを完璧に水平に設置することは不可能です。

従って、停止中も0出ない値を出力します。
readings[1]を10サンプルくらい取得し、平均値を求め、仮にavとします。
  as = readings[1]-av;
としてみて下さい。
as *= 9.8/256;

as = as * 9.8/256;
と同じです。
    • good
    • 0

回答が小出しで申し訳ありません。


(int16_t)のキャストを行っていますが、これでは、ほどんど0になってしまいます。
readings[]をintで宣言し、
as=readings[1];
と浮動小数変数に格納後,下記のように単位変換を行ってください。
as *= 9.8/256;
この回答への補足あり
    • good
    • 0

お使いの加速度センサーは2の補数で出力されるようですので、最初にアドバイスさせていただいた通り、変数Vの初期化はループに入る前に一度だけ行えば、速度が求められるはずです。


センサーを常に水平にしておくことが前提ですが。
    • good
    • 0

加速度は、プラスとマイナスがあります。

加速時はプラス、減速時はマイナスです。
ADXL345の仕様をインターネットで確認したところ、2の補数表示をしているようなので、減速時はマイナスになります。
従って、accelerometer.getOutput(readings); のreadingsを符号付き変数として宣言すれば、減速時にはマイナスになると思われます。
>加速度センサを動かさなくても値が足しあわされてしまいます。
当然です。加速度とは加重です。動いているかどうかではなく、力が加わっているかどうかです。重力も認知されます。
どのような使用方法を考えているのか分かりませんが、自動車のようなものなら水平に置くことを仮定してプログラミングするか、飛行機のようなものでしたら姿勢状態の把握もしなければなりません。差し支えなければ応用内容を提示された方が、回答しやすいと思います。
制御プログラム作成に翻弄されているようですが、是非解決して回答を見つけて下さい。我が国の資源は貴方がたの物づくり能力そのものです。頑張ってください。私があなたの力になれるのでしたら光栄です。
この回答への補足あり
    • good
    • 0

すみません、よくプログラムを見ずに投稿しました。


accelerometer.getOutput(readings); でreadingsに入る値はAD値のようですが、加速度0の時の値は128ではないですか?
もしそうなら
as = ((int16_t)readings[1]-128)*(9.8/256);
とする必要があります。
この回答への補足あり
    • good
    • 0

>double v =0; をwhileの外に出してしまうと、速度値が常に足しあわされてしまいます。


"常に足しあわされ"ることによって積分が成立します。積分するためには、wtileのたびに0クリアしてはいけません。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!