FAMOS
シーケンス / 関数top
└ シーケンス / 関数
Qヒルベルト変換の関数はありますか?
FAQ ID:s029
Ver4.0の時点では存在しません。メーカーに問い合わせたところ、バージョンアップで対応するという回答をもらいました。
バージョンアップでサポートされるまで以下のシーケンスで代用してください。
;--------------------------------------------- ; ヒルベルト変換 ;--------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; サンプルデータの読み込み Famos Load C:\imc\dat\slope.dat __data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 演算 FftOption 0 0 _fan = fft( __data ) _fan.p = _fan.p - 90 _t1 = ifft ( _fan ) hilbert = Sqrt(Sqr(__data)+Sqr(_t1)) < 包落線 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 瞬間周波数 angle = atan2(_t1, __data) angle1 = cutIndex(angle, 1, leng?(angle)-1) angle2 = cutIndex(angle, 2, leng?(angle)) angle2=xoff(angle2,0) angle = angle2-angle1 i=1 while i<=leng?(angle) if angle[i]<-pi angle[i]=angle[i]+pi2 end if angle[i]>pi angle[i]=angle[i]-pi2 end i=i+1 end Freq = angle/pi2 delete _t1 delete _fan
Q変数名の命名方法
FAQ ID:s027
変数はその名前で認識されます。
大文字と小文字の区別はありません。
使用可能な変数名は、
- 最大255文字以下
- 数字で始まらない
- 他の変数名と同じでない
- シーケンス(マクロ)コマンドと同じでない
- 定数の名前と同じでない
- 演算シンボルと同じでない
以下のシンボルは変数名には使用できません。
- + - ( ) * / ^ = { } [ ] < > |
- スペース、セミコロン、クォーテーションマーク、カンマなども使用できません
注意
日本語、クエスチョンマーク(?)やイクスクラメーションマーク(!)などの特別な文字を名前に使用することは、できるだけ避けて下さい。
例えば、クエスチョンマークは、変数名に使うことを許可されていますが、場合によっては予想できない結果をもたらす場合があります。一般的に、変数名とファイル名は同じになりますが、クエスチョンマークはファイル名には使用できません。なぜなら、パラメータ付きでマクロシーケンスを呼び出す場合、ク エスチョンマークをワイルドカードとしてファイル名に使うからです。
関数の名前を変数名に使用することは可能ですが、混乱を避けるために使用しないでください。
Q関数"Smo"の係数の求め方
FAQ ID:s024
次のシーケンスから求めることができます。
例えば、7点の係数を求めます。
imp = Ramp( 0, 1, 100) * 0 imp = Set( imp, 50, 1) Res = Smo( imp, 7 )
この結果より次の係数を取得することができます。
0.04 | 0.12 | 0.20 | 0.28 | 0.20 | 0.12 | 0.04 |
これらの係数は以下のように反映されます。
y[u] = 0.04 * u[k-3] + 0.12 * u[k-2] + 0.20 * u[k-1] + 0.28 * u[k] + 0.20 * u[k+1] + 0.12 * u[k+2] + 0.04 * u[k+3]
Q単位の自動計算
FAQ ID:s023
FAMOSは演算を行う際に単位を考慮します。
Example1
例えば、I=3[A],V=12[V]であれば、Wat=36[W]となります。
I = 3 'A' ;シングルクォーテーションです
V = 12 'V'
Wat = I * V
Show Wat
Example2
単位系にはSI単位系が使用されます。
Weight=60 'kg' g=9.80665 'm/s^2' Force = Weight * g
Example3
ユーザー単位系を使用したい場合、ダブルクォーテーションを使用してください。
Weight=60 '"kg"' g=9.80665 '"m/s^2"' Force = Weight * g
Qエンジンの回転角度毎に取得したデータを平均化する
FAQ ID:s020
エンジンの回転角度(1[deg])毎に1分間のデータを取得しました。
例えば1000[rpm]で回転していたとすると、1回転分360データ×1000=360000データを測定したことになります。
このデータを0-360[deg]毎に切り出して、1000回分の平均を求めるにはどのようにすればよいでしょうか?
_K_SegLeng = 100 ;切り出すセグメント長さを指定してください SetSegLen( DATA, _K_SegLeng) Temp = TransposeMatrix( DATA) i=1 RESULT = Leng( 0, 0) While i<=_K_SegLeng RESULT = Join( RESULT, Mean( temp[i])) i=i+1 End
グループ変数内の全ての変数に対して処理する場合のサンプルです。
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ;_/ 長時間のデータを指定したセグメントに切り出して平均化する ;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ;******************************* ;サンプルデータを作成します。 ;データはグループ変数とします。 ;******************************* Del * dat1 = Ramp(0,1,1000) dat2 = Ramp(0,1,1000) GROUP = GrNew() GrChanAppend( GROUP, dat1) GrChanAppend( GROUP, dat2) Del dat* ;******************************* ;シーケンスを実行します。 _K_SegLeng = 100 ;切り出すセグメント長さを指定してください ;******************************* ;------------------------------------- ;変数リスト内の変数の総数を取得して ;全ての変数に対して実行します ;------------------------------------- _K_VarTotal = VarGetInit(0) _K_VarIdx = 1 While _K_VarIdx<=_K_VarTotal ;各グループ変数のループ _K_VarName = VarGetName?( _K_VarIdx ) SetSegLen(<_K_VarName>, _K_SegLeng) ;--------------------------------------- ;グループ内の変数全てに対して処理を行います ;--------------------------------------- _K_GrTotal = GrChanNum?(<_K_VarName>) _K_GrIdx = 1 While _K_GrIdx<=_K_GrTotal _K_GrName = GrChanName?( <_K_VarName>, _K_GrIdx) ;グループ変数名の生成 FAQ S015参照 _K_GrName = TAdd(_K_VarName, TAdd(":", _K_GrName)) ;--------------------------------------- ;各変数を平均化します ;--------------------------------------- _K_SegTotal = Leng?(<_K_GrName>)/SegLen?(<_K_GrName>) _K_SegIdx = 1 _K_Result = Leng(0,SegLen?(<_K_GrName>)) While _K_SegIdx<=_K_SegTotal ;平均化 _K_Result=_K_Result+<_K_GrName>[_K_SegIdx] _K_SegIdx=_K_SegIdx+1 End <_K_GrName>=_K_Result/_K_SegTotal _K_GrIdx=_K_GrIdx+1 End _K_VarIdx=_K_VarIdx+1 End Del _K_*
Q2組以上の並び替え
FAQ ID:s019
以下のデータについて並び替えを行います
;--------------------------
;サンプルデータの作成
;--------------------------
DataX = Leng(0,5)
DataX[1] = 1
DataX[2] = 4
DataX[3] = 3
DataX[4] = 9
DataX[5] = 8
DataY = Leng(0,5)
DataY[1] = 3
DataY[2] = 8
DataY[3] = 4
DataY[4] = 9
DataY[5] = 5
Xの昇順で並び替える
X_Mono = Sort( Data.X, 1) ;X軸データを単調増加へ
Y_Sort = Value( Data.Y, Sort( Data.X, 3))
Res = XYof( X_Mono, Y_Sort)
Yの昇順で並べ替える
Y_Mono = Sort( Data.Y, 1) ;X軸データを単調増加へ
X_Sort = Value( Data.X, Sort( Data.Y, 3))
Res = XYof( X_Sort, Y_Mono)
Qデータロガーのサンプリングタイムをインデックスで管理しています。 これをサンプリングタイムに変換するには?
FAQ ID:s017
データロガーのサンプリングレートが以下のようなインデックス番号で管理されています。
このインデックスからサンプリングタイムに変換するにはどうすればよいでしょうか?
Index | ⊿X | |
---|---|---|
0 |
10 |
μsec |
1 |
20 |
μsec |
2 |
50 |
μsec |
3 |
100 |
μsec |
4 |
200 |
μsec |
5 |
500 |
μsec |
6 |
1 |
msec |
7 |
2 |
msec |
8 |
5 |
msec |
9 |
10 |
msec |
10 |
20 |
msec |
11 |
50 |
msec |
12 |
100 |
msec |
13 |
200 |
msec |
14 |
500 |
msec |
15 |
1 |
sec |
サンプリングレートは1-2-5と繰り返されています。
関数”MOD”を利用します。
以下のシーケンスを参考にしてください。
IF MOD( Index, 3) = 0 ;1[usec], 10[umsec],...の場合
temp = 1
END
IF MOD( Index, 3) = 1 ;2[usec], 20[umsec],...の場合
temp = 2
END
IF MOD( Index, 3) = 2 ;5[usec], 50[umsec],...の場合
temp = 5
END
RESULT = temp * 10^(-5 + Floor( Index/3 ))
Q3Dデータの作り方
FAQ ID:s013
以下のデータは、室内の平面座標位置XZで測定した温度などのデータです。データの値をYとします。
このデータをカラーマップで表現させたいのですが、どうすればいいのでしょうか?
X | |||||
---|---|---|---|---|---|
3 | 5 | 7 | 9 | ||
Z | 1 | 48 | 50 | 51 | 52 |
5 | 49 | 52 | 53 | 54 | |
9 | 51 | 53 | 54 | 55 |
方法1:3つのデータを作成
以下のように3つのデータを作成します。
Ch1 | Ch2 | Ch3 |
---|---|---|
48 | 49 | 51 |
50 | 52 | 53 |
51 | 53 | 54 |
52 | 54 | 55 |
これらの3つの波形をまとめて表示させ、カラーマップで表示させます。
方法2:セグメント
(1)Yデータの作成
Yデータを以下のように定義します。
ydata
48
50
51
52
49
52
53
54
51
53
54
55
(2)データ形式の変換
カラーマップで表示するためにはデータの形式を標準波形からセグメント波形に定義しなおします。
関数”SetSegLen”を使ってセグメント波形にします。
SetSegLen( ydata, 4) ;セグメント波形へ
(3)X・Z座標の定義
Xデータ(3・5・7・9)はサンプリングレート2、オフセット3です。
ydata = XDel( ydata, 2) ;Xサンプリング設定
ydata = XOff( ydata, 3) ;Xオフセット設定
Zデータ(1・5・9)はサンプリングレート4、オフセット1です。
SetZDel( zdata, 4) ;Yオフセット設定
SetZoff( zdata, 1) ;Yオフセット設定;
(4)結果の表示
変数”ydata”をカーブウィンドウに表示させます。
カーブウィンドウメニュー<オプション/表示>でダイアログを表示させ、カラーマップを選択してください。
ここで、Z軸の値に注目してください。設定した値で表示されていません。これを希望の形式で表示させるためには、
カーブウィンドウメニュー<オプション/3D>でダイアログを表示させ、”データのZ座標を加える”を選択してください。
Q等級線を使ったレベル判定
FAQ ID:s014
データロガーやFFTアナライザーを使って測定したデータに対して、等級線を使用して良否判定する方法を紹介します。
上図において、波形Speedは測定データです。波形は等級線です。
等級線は以下のようなデータを設定しています。
Limit.X | Limit.Y |
---|---|
0.5 | 5 |
2 | 3 |
3 | 3 |
3.5 | 4 |
例えば、測定波形が等級線を越えた場合、不良品であると仮定します。
設定したレベルを超えたかどうか判断するために関数Subを利用してください。
Judge = Sub( Speed, Limit, 0
結果は以下のようになります。
注意:
ここで、結果JudgeのX軸範囲に注目してください。
等級線で設定された範囲のみで計算します。
結果Judgeが0より大きい値を持つとき、不良であることを示します。
0より大きい値を持つかどうかは以下のように簡単に判定することができます。
IF ?Max( Judge) > 0
Err = BoxMessage( "良否判定","この製品は規格を満たしていません", "!1")
End
サンプル
測定波形は既に用意されているとします。
;*************************************** ;等級線を作成します ;*************************************** tempX = Leng( 0, 4) tempX[1] = 0.5 tempX[2] = 2 tempX[3] = 3 tempX[4] = 3.5 tempY = Leng( 0, 4) tempY[1] = 5 tempY[2] = 3 tempY[3] = 3 tempY[4] = 4 Limit=XYof( tempX, tempY) ;*************************************** ;判定 ;*************************************** Judge = Sub( Speed, Limit,0) IFMax( Judge) > 0 Err = BoxMessage( "良否判定","この製品は規格を満たしていません", "!1") End
サンプル
さらに数段階の等級を設定し、等級判定することもできます。
測定波形は既に用意されているとします。
;*************************************** ;等級線を作成します ;*************************************** i=1 While i<=7 tempX = Leng( 0, 4) tempX[1] = 0.5 tempX[2] = 2 tempX[3] = 3 tempX[4] = 3.5 tempY = Leng( 0, 4) tempY[1] = 2+i tempY[2] = 0+i tempY[3] = 0+i tempY[4] = 1+i FName = TAdd( "Level", TForm( i, "F00")) = XYof( tempX, tempY) GrChanAppend( Limit, ) Del i=i+1 End ;*************************************** ;判定 ;*************************************** i=1 While i<=7 FName = TAdd( "Level", TForm( i, "F00")) Judge = Sub( Speed, Limit:,0) IF Max( Judge) < 0 Mes = TAdd( "この製品のレベルは", TForm( i, "F00")) Mes = TAdd( Mes, "です。") Err = BoxMessage( "レベル判定",Mes, "!1") i=7 End i=i+1 End
Q変数がグループ変数かどうか調べる
FAQ ID:s015
変数リスト内の変数がグループ変数かどうか調べる方法を紹介します。
変数リストを見ればその変数がグループ変数かどうかは一目瞭然です。
しかし、シーケンスから変数を参照しているときにはどうでしょうか?
次のサンプルコードは変数リストの変数を取り出すコードです。
ListTotalNumber = VarGetInit(0) While cnt<=ListTotalNumber DataName = VarGetName?(cnt) ret = BoxMessage("",DataName,"!1") cnt=cnt+1 End
このコードを実行させると以下のように変数リストの変数名を表示できます。しかし、この変数がグループ変数なのかどうかはわかりません。
例えば、この変数がグループ変数でその中に”Ch1”という変数が格納されていた場合、以下のようにアクセスする必要があります。
GroupData:Ch1
しかし、この変数がもしグループ変数でなければこのような表現はエラーとなってしまいます。このようにシーケンスで変数を扱う場合にはグループ変数かどうかを調べないといけません。
グループ変数かどうかは関数”GrChanNum?”を使用すればわかります。
本来、グループ変数内のチャンネル数を求める関数ですが、指定した変数がグループ変数でなければエラー値が返ります。このエラーで判定すればグループ変数かどうか判断できます。
以下にサンプルコードを示します。サンプルでは上の例のようにメッセージボックスで変数名を表示させると大変なのでファイルに出力しています。
;******************************************************************** ; 変数リスト内の変数名をファイルに書き出す ; ********************************************************************* FileID = FileOpenASCII( "c:\test.txt",1) cnt=1 ;リスト内の変数の総数を取得 ListTotalNumber = VarGetInit(0) While cnt<=ListTotalNumber DataName = VarGetName?(cnt) GrVarNum = GrChanNum?( <DataName>) if GrVarNum<>-1 ;データがグループ変数の場合 gcnt=1 While gcnt<=GrVarNum ;グループ内の変数名を取得 GrVarName = GrChanName?( <DataName>, gcnt) TEXT = TAdd( DataName, ":") TEXT = TAdd( TEXT, GrVarName) Ferr = FileLineWrite( FileID, TEXT, 0) gcnt=gcnt+1 End Else ;通常の変数の場合、そのまま出力 TEXT = DataName Ferr = FileLineWrite( FileID, TEXT, 0) End cnt=cnt+1 End Ferr = FileClose(FileID)
Qデータ間が不等間隔のXY波形を等間隔データに変換するには?
Q極大値を検出する方法
FAQ ID:s058
以下のような波形に対するピーク値を検出します。
検出方法は波形の極大値を検出します。
ピーク値の検出には、関数”xMax”が便利です。この関数は、スレッショルド以上の極大値のX値を返します。
サンプル波形に対して、スレッショルド0.9でこの関数を適用します。
PkValue = xMax(arches, 0.9 )
結果は以下のようになります。
4.24e-005
0.0001848
0.0003112
0.0004368
0.0005624
0.0006872
この値をサンプル波形に重ねて表示する場合には、ここで求めたX値に対応したY値を求め、XY波形を作成しなければなりません。これは、先に説明した関数”Value”を利用します。
PK = XY( PkValue,Value( arches, PkValue ))
Qノイズが多い場合のピーク値の検出
FAQ ID:s059
以下の波形のようにノイズが多く含まれた信号のピーク値を求めます。
ピークとして、0.7[sec]付近の正側のピークと0.8[sec]付近の負側のピークを求めます。
最初にノイズ成分に影響されないようにオリジナル波形にローパスフィルターを適用した波形を適用します。
S_100 = Smo( ORIGINAL, 0.10)
次に信号が0を横切ったときを検出します。このとき関数”All0”をします。All0は0を横切ったときのX座標(Array)を返します。
さらに、この結果の何番目(index)が正側のピークを表しているか求めます。
Array = All0( S_100) ;0点を横切る全ての点を抽出 max_x = Pos( S_100, Max(S_100)) ;最大値のX座標を取得 index = Floor( Pos(Array, max_x))+1 ;この変数にピークに対応 するインデックス番号が入力されます。 ;X座標に相当するインデックス番号を取得
この変数にピークに対応 するインデックス番号が入力されます。 ;X座標に相当するインデックス番号を取得
この後、正側と負側のピークを検出する区間を切り出します。
p_peak = cut( Original, ValueIndex(Array,index-1), ValueIndex(Array,index)) m_peak = cut( Original, ValueIndex(Array,index ), ValueIndex(Array, index+1 ))
切り出された波形に対して、ピーク値を求めます。
plus = Max(p_peak) minus = Min(p_peak)
以上でピーク値を求めることができます。この結果をカーブウィンドウにプロットするには以下のコマンドを適用すると表示できます。
plus_G = XYof( Pos( p_peak , Max(p_peak)), Max(p_peak)) minus_G = XYof( Pos( m_peak , Min(m_peak)), Min(m_peak))
Q微分からピークを求める方法
QDDE通信でExcelにデータを転送できますか?(シーケンスを使用:FAMOS ⇒ Excel)
QDDE通信でExcelにデータを転送できますか?(シーケンスを使用:Excel ⇒ FAMOS)
Qエンジンの回転パルスを計測しました。各回転パルス間の時間を求めることはできますか?
FAQ ID:s007
関数“SearchLevel”を使用すると簡単に求めることができます。
以下のようなコマンドでパルス間隔を求めることができます。
res = SearchLevel(data, 2, 5, 0, 2, 1, 0, 1)
res1 = CutIndex( res.X, 1, leng?(res.X)-1)
res2 = CutIndex( res.X, 2, leng?(res.X))
DiffTime = Res2-Res1
解説
最初に関数“SearchLevel”を使用して、5Vになった部分を検索します。
結果resには、検索された時間とそのときの値がX、Yのデータとして出力されます。
この結果に対して、インデックスを1つずらした波形を作成します。
これは以下のような処理を行っています。
res1 | 1個目のX座標 | 2個目のX座標 | 3個目のX座標 | 4個目のX座標 |
---|---|---|---|---|
res2 | 2個目のX座標 | 3個目のX座標 | 4個目のX座標 | 5個目のX座標 |
これらの値を減算することにより、各パルス時間間隔を求めることができます。以下にサンプルを示します。
;----------------------------------------------------------------
;サンプルパルスデータ作成
;各パルスの間隔が異なるように設定しています。
;----------------------------------------------------------------
;****************************
; Low=0, High=5のパルスデータを作成します。
;****************************
p=0 ;データ処理経過を%で表示
YUnit p %
show p
data = Leng(0,0)
i=1
While i<=720
data = Join( data, Leng(0,10+2*Mod(i,5))+0) ;0のデータを作成
data = Join( data, Leng(0,10+2*Mod(i,5))+5) ;5のデータを作成
p = i/720*100
i = i+1
End
data = XDel( data, 0.001);サンプルレートの設定
XUnit data s
Show data
CvXAxis( data, 0, 0.2, 0)
CvYAxis( data, data, 0, -1, 6, 10000, -2)
;----------------------------------------------------------------
;
これ以降が実際の処理です。
;----------------------------------------------------------------
;****************************
;トリガーポイントの検出
; 関数"SearchLevel"を使用します。
; 結果は立ち上がりエッジのX,Yデータとなります。
;****************************
res = SearchLevel(data, 2, 5, 0, 2, 1, 0, 1)
CvYAxis( data, Res, 0, -1, 6, 10000+5000+400, -2);データ表示。
実際の処理では必要なし
;****************************
;パルス間隔の計算
;****************************
res1 = CutIndex( res.X, 1, leng?(res.X)-1)
res2 = CutIndex( res.X, 2, leng?(res.X))
DiffTime = Res2-Res1
Show DiffTime ;データ表示。実際の処理では必要なし
CvYAxis( DiffTime, DiffTime, 0, 0, 0, 3000+300, -2)
;データ表示。実際の処理では必要なし
CvXAxis( DiffTime, 1, 20, 0)
;データ表示。実際の処理では必要なし