こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

C言語 値の合計について(PICマイコン上)

C言語、値の合計について(PICマイコンを使用)

C言語のアルゴリズムについての質問です。
申し訳ございませんが、前提が長く、質問が後半にあります。

1.行いたいこと
パルス幅を取り込んで、パルス幅を足しこんでいく。この値を面積とする。

2.仕様
・500usでループを回しており、その都度、パルス幅を取得しています。
(パルス幅は1つであったり、複数であったりします。パルスの数を「Rise」という
変数で記憶しています。)

・そのパルス幅を取得し、一定ループ後に合計値を計算したい。

例)

___|¯¯|___|¯¯¯|___ Rise=1。中央のくぼみの幅を計算

___|¯¯|_|¯¯|_|¯|____ Rise=2。中央2つのくぼみを計算

3.問題点
Riseの値でif分岐をした、べた書きしたプログラムと、より一般化したプログラムの
面積の値(SUM_Areaの値)が異なる。

一般化したものの方が値が大きくなる。

/*以下プログラム*/
// べた書き

if(Rise==2){
Captime[1]=Captime_rise[2]-Captime_down[1]; //パルス幅の計算
Area[1] += Captime[1]; //面積計算
SUM_Area=Area[1]; //合計の面積
} // Rise==2 LOOP END

else if(Rise==3){
Captime[1]=Captime_rise[2]-Captime_down[1];
Captime[2]=Captime_rise[3]-Captime_down[2];

Area[1] += Captime[1];
Area[2] += Captime[2];

SUM_Area=Area[1]+Area[2];
} // Rise==3 LOOP END

else if(Rise==4){
Captime[1]=Captime_rise[2]-Captime_down[1];
Captime[2]=Captime_rise[3]-Captime_down[2];
Captime[3]=Captime_rise[4]-Captime_down[3];

Area[1] += Captime[1];
Area[2] += Captime[2];
Area[3] += Captime[3];
SUM_Area=Area[1]+Area[2]+Area[3];
}

// 一般化したもの
for(i=1;i<Rise;i++){
Captime[i]=Captime_rise[i+1]-Captime_down[i];
Area[i]+=Captime[i];
SUM_Area+=Area[i];
}

4.考察
一般化したプログラムの
SUM_Area+=・・・・
の部分のみをifで場合分けすると、
(SUM_Area=Area[1]+Area[2]+Area[3]; の様にRiseの値で分岐)

値が一致したので
この部分が悪さをしていると考えています。

5.質問
今回の場合はSUM_Areaの部分は、べた書き(Riseでの分岐)しか方法がないのでしょうか。
Riseが64個まであるので、プログラムが冗長になってしまいます。


宜しくお願いします

投稿日時 - 2015-11-10 13:41:17

QNo.9078128

すぐに回答ほしいです

質問者が選んだベストアンサー

#1です。何度もすみません。

修正プログラムには問題がありました。
例えばRize=4の次にRise=2がきてループが終了するような場合、SUM_AreaにはArea[1]と[2]しか足し込まれず、[3][4]が足し込まれないことになってしまいます。
なお、この問題は、お示しのべた書きプログラムでも同じことが言えると思います。

>一定ループ後に合計値を計算したい。
ということですので、ループ内ではSUM_Areaの計算はせずに、ループを抜ける際に、
Aera[1]~[64]の合計をSUM_Areaに格納するようにしたほうが良さそうです。

投稿日時 - 2015-11-10 17:04:27

ANo.3

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(3)

ANo.2

#1です。修正後のプログラムに書き間違いがありました。

【誤】
for(i=1;i<=Rise;i++){
【正】
for(i=1;i<Rise;i++){

です。Riseの前の = は不要です。

投稿日時 - 2015-11-10 16:55:24

-広告-

ANo.1

仕様がいまいちはっきりしないのですが、

(1)パルスを取得
こんなのや、
___|¯¯|___|¯¯¯|___

こんなの
___|¯¯|_|¯¯|_|¯|____

が取得され、
・パルス数がRiseという変数に格納される。
・Captime_rise[n]とCaptime_down[n] に、パルスの立ち上がり/立ち下がりの時刻が格納される。(n は1からRiseまで)

(2)プログラムが実行される
 ・パルス間のくぼみの時間の長さがArea[n]に「加算」される。(今回のパルスのみではなく、今までのすべてのパルスの累計)
 ・すべてのArea[n]の合計がSUM_Areaに格納される。

(3)500μsごとに(1)(2)を繰り返す。

といったことでしょうか。

一般化したプログラムを(2)の箇所で実行すると、
例えば2回ループを廻したとすると、
SUM_Area+= の箇所で、1回目のデータが2回重複して加算されてしまうことになります。
(2回目のループの際にArea[n]にはすでに1回目のデータが格納されている状態で、そこに2回目ループのデータを加算しています)

正しいプログラムは、
SUM_Area=0;
for(i=1;i<=Rise;i++){
Captime[i]=Captime_rise[i+1]-Captime_down[i];
Area[i]+=Captime[i];
SUM_Area+=Area[i];
}

とすればよいと思います。

投稿日時 - 2015-11-10 16:48:34

補足

関係の無いことなのですが、MSZ006様はガンダムがお好きなのでしょうか。ファーストのご世代なのでしょうか。(Zの形式番号な為そう推測しました。)

投稿日時 - 2015-11-10 17:35:28

お礼

MSZ006様:

アドバイスありがとうございます。
仰る通り、ループ外でSUM_Areaを計算するようにしたところ
上手く行きました。
Area[i]の計算まではforで回して計算しています。

また、私の稚拙な文章から仕様を読み取って頂きありがとうございます。

上手く言葉では言えないのですが、Riseは都度0に初期化されます。
(ラインカメラの仕様上)

for(i=1;i<Rise;i++){
Captime[i]=Captime_rise[i+1]-Captime_down[i];
Area[i] += Captime[i]; //面積計算 -> Area = Area+ Captime[1]
}
Calc_area();

void Calc_area(void){
if(Rise==2) SUM_Area=Area[1];
else if(Rise==3) SUM_Area=Area[1]+Area[2];
/*以下 Rise==64まで分岐*/
}

一応ここに全文があります。
(決して「見て頂きたい」という厚かましいお願いではございません。)
http://anasys.blog.fc2.com/blog-entry-15.html

投稿日時 - 2015-11-10 17:32:13

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-