« 2017年1月 | トップページ | 2017年3月 »

2017年2月

2017年2月26日 (日)

グルグル回る軸の角度変動の平均値を出す方法#4

回転角度の平均値計算
風向の平均計算

グルグル回る軸の角度変動の平均値を出したい
グルグル回る軸の角度変動の平均値を出す方法
グルグル回る軸の角度変動の平均値を出す方法#2
グルグル回る軸の角度変動の平均値を出す方法#3 

これのまとめです。

ひとつのルーチンで、いくつもデータを扱えるようにしてみました。
これまでのは、平均処理したい角度がいくつもある場合、
それぞれの値に対して関数を作らなくちゃなりませんでした。

これも面倒なんで、移動平均処理するそれぞれのデータを
置いておく場所を「構造体」で記述し、一つの関数でこれを
処理できるようにしました。
構造体はそれぞれの角度ごとに必要ですが、それを処理
する関数は一つだけ。
入力データ値と構造体名、それに平均する回数を指定して
関数を呼び出します。

こんな具合・・・・

//    BYTEとWORD
typedef unsigned char    BYTE;
typedef unsigned short   WORD;
#define PAI   3.141592654  // πの値

/***** 四捨五入    *****/
//   正負で±0.5して整数に変換
short rounds(float d)
{
  if(d >= 0){
    return (short)(d + 0.5);
  }else{
    return (short)(d - 0.5);
  }
}

/***** 360度1回転規制   *****/
//   0~359度を得る
WORD lim359(short d)
{
  if(d < 0){       // マイナスかもしれない
    d = -d;       // 正の数に
    d = d % 360;    // 0~359に
    d = 360 - d;    // 360から減算
  }
  d = d % 360;      // 0~359に
  return d;
}

/***** 角度スムージング処理  *****/
// 計算のための構造体
typedef struct{
  short  *bfx;      // Xスムージングバッファ
  short  *bfy;      // Y
  long  adx;      // X合計加算値
  long  ady;      // Y
  short  p;       // データポインタ
  short  f1;       // 初回チェックフラグ
}SMZ_359;

/***** 角度スムージング処理  *****/
// 浮動小数点計算での誤差を累積ささないため
// X,Yを10000倍したwordデータで計算する
// sin,cos ±1.0が最大なので2バイトで足りる
// deg : 0~359 入力角度
// smz : スムージングバッファ 構造体
// size: スムージング処理加算回数=バッファの大きさ 
WORD smz359c(short deg, SMZ_359 *smz, const WORD size)
{
short *px, *py;
short i, x, y;
float d, e;
  PH3_H;         // (!!!)PH3 17pin H/L
  d = (PAI / 180.0) * (float)(lim359(deg));  // 0~2πに
  x = rounds(cos(d) * 10000.0);    // X,Yの値
  y = rounds(sin(d) * 10000.0);    // 10000倍して整数で
  if(smz->f1 == 0){          // 初めて
    smz->bfx = malloc(sizeof(short) * size); // バッファ確保
    smz->bfy = malloc(sizeof(short) * size);
    if((smz->bfx == NULL) ||         // メモリ確保失敗なら
      (smz->bfy == NULL))   return deg; // 元数値を持ってリターン
    smz->adx = (long)x * size;   // X,Y合計加算値
    smz->ady = (long)y * size;
    px = smz->bfx;         // バッファの先頭
    py = smz->bfy;
    for(i = 0; i < size; i++){   // バッファを初期値で埋める
      *px++ = x;
      *py++ = y;
    }
    smz->p = 0;          // データポインタ先頭に
    smz->f1 = 1;          // 初回処理終了
  }
  else{                // 2回目以降
    px = smz->bfx + smz->p;
    py = smz->bfy + smz->p;
    smz->adx = smz->adx - *px + x; // 古い値を引いて
    smz->ady = smz->ady - *py + y; // 新値を加算
    *px = x;            // 新値をセット
    *py = y;
    smz->p++;            // ポインタを後ろに
    if(smz->p >= size) smz->p = 0; // 最後まで来たらゼロに
  }
  e = 10000.0 * (float)size;     // スケーリング
  d = (180.0 / PAI) *         // 角度に
     atan2((float)smz->ady / e,  // X,Y平均値
        (float)smz->adx / e);
  PH3_L;               // (!!!)PH3 17pin H/L
  return lim359(rounds(d));      // 0~359
}

// ★使用例
BYTE f_tm10ms;    // A/D値が10mSごとに確定 (0/1)
WORD ad_deg;     // A/D値から算出した角度データ (0~359度)
SMZ_359 smz_deg;   // 角度データ平均用配列:構造体
    :
    :
// 1秒ごとに平均角度を出力
  if(f_tm10ms){  // 10mSごとにA/D値が確定
    printf("%3d deg\n",           // 3桁で出力
        smz359c(ad_deg, &smz_deg, 100)); // スムージング処理
    f_10ms = 0;
    :
  }

※全角スペースを使ってます。

移動平均データを置いておく配列は「malloc」でメモリーを確保。
メモリー不足だった場合は平均処理は行わず、元データを持って
リターンするようにしています。

メモリー不足のエラーは出していません。
smz.bfx、smz.bfyがNULLじゃないことを、この関数実行後に
別場所で調べればと。
あるいは、smz.f1が1ならメモリー確保成功していると判断で
きます。

| | コメント (0) | トラックバック (0)

2017年2月25日 (土)

2月の撃墜数

月末の金曜日は瓶出し。
2月は、
  一升瓶:25本
  四合瓶:13本 (ワイン含む)
でした。

11


| | コメント (0) | トラックバック (0)

2017年2月24日 (金)

グルグル回る軸の角度変動の平均値を出す方法#3

グルグル回る軸の角度変動の平均値を出す方法#2 は、
「移動平均」(関数を呼ぶたびに平均値を更新)でしたが、
単純な「加算平均」(一定期間ごとに平均値が出る)で
よければ、こんな方法をどうぞ。
例えば、0.1秒ごとにこれを呼び出して、2秒したら
結果が出るなんていうことでよければ、移動平均の
ためのバッファ(過去データを保持して新値で更新)
は不要です。

 

/***** 角度を加算平均化    *****/
// in/out deg:0~359度を得る
// 平均回数を過ぎて結果が出るまでは0を返す
#define AVR_SIZ   20     // 平均回数

 

WORD avr359(short deg)
{
static float ttl_x = 0.0;        // X,Y合計値
static float ttl_y = 0.0;
static short cnt = 0;          // 加算回数
static short avr = 0;          // 平均値
float d, x, y;
  PH3_H;               // (!!!)PH3 17pin H/L
  d = (PAI / 180.0) * (float)(lim359(deg));  // 0~2πに
  x = cos(d);             // X,Yの値
  y = sin(d);
  ttl_x = ttl_x + x;         // 新値を加算
  ttl_y = ttl_y + y;
  cnt++;               // 回数+1
  if(cnt >= AVR_SIZ){
    x = ttl_x / AVR_SIZ;      // X,Y平均値
    y = ttl_y / AVR_SIZ;
    cnt = 0;            // 次処理のために
    ttl_x = ttl_y = 0.0;      // 合計値をゼロクリア
    d = (180.0 / PAI) * atan2(y, x);  // 角度 ±π
    avr = lim359(round(d));       // 0~359
  }
  PH3_L;               // (!!!)PH3 17pin H/L
  return avr;             // 0~359
}

 

※全角スペースを使ってます。
平均回数経過でフラグを立てるなどすれば、
値が確定したことがわかります。

 

この場合、「atan2」は毎回実行されませんので、
(sin、cosは毎回)平均値算出以外の処理時間はざっと
20~30μSです。  (32MHzのRX220マイコンで)

※検索:角度の平均値計算

 

※元記事:グルグル回る軸の角度変動の平均値を出したい:居酒屋ガレージ日記

 

※これでまとめかな:
  グルグル回る軸の角度変動の平均値を出す方法#4

| | コメント (0) | トラックバック (0)

グルグル回る軸の角度変動の平均値を出す方法#2

グルグル回る軸の角度変動の平均値を出す方法 の続き。

浮動小数点でX、Y値と合計値を保持するのが不安
(誤差の累積)なので、整数で保持するように変えて
みました。

sin、cosで出たXとYの値は0~±1.0。
一万倍して±10000なので、ワードデータに納まります。

// 浮動小数点計算での誤差を累積ささないため
// X,Yを10000倍したwordデータで計算する
// sin,cos ±1.0が最大なので2バイトで足りる
WORD smz359b(short deg)
{
static short smz_x[SMZ_SIZ];      // Xスムージングバッファ
static short smz_y[SMZ_SIZ];      // Y ★
static long ttl_x, ttl_y;       // 合計値 ★
static BYTE f1 = 0;           // 初めての処理
static short p = 0;           // データポインタ
short i;
short x, y;
float d;
  PH3_H;               // (!!!)PH3 17pin H/L
  d = (PAI / 180.0) * (float)(lim359(deg));  // 0~2πに
  x = round(cos(d) * 10000.0);    // X,Yの値 ★
  y = round(sin(d) * 10000.0);    // 10000倍して整数で
  if(f1 == 0){            // 初めて
    ttl_x = x * SMZ_SIZ;      // X,Y合計値 ★
    ttl_y = y * SMZ_SIZ;
    for(i = 0; i <SMZ_SIZ; i++){  // バッファを初期値で埋める
      smz_x[i] = x;
      smz_y[i] = y;
    }
    p = 0;             // データポインタ
    f1 = 1;             // 初回処理終了
  }
  else{                // 2回目以降
    ttl_x = ttl_x - smz_x[p] + x;  // 古い値を引いて ★
    ttl_y = ttl_y - smz_y[p] + y;  // 新値を加算
    smz_x[p] = x;          // 新値をセット
    smz_y[p] = y;
    p++;              // ポインタを後ろに
    if(p >= SMZ_SIZ)  p = 0;   // 最後まで来たら先頭に
  }
  d = (180.0 / PAI) * atan2(         // 角度
      (float)ttl_y / (10000.0 * SMZ_SIZ), // X,Y平均値 ★
      (float)ttl_x / (10000.0 * SMZ_SIZ));
  PH3_L;               // (!!!)PH3 17pin H/L
  return lim359(round(d));      // 0~359
}

※全角スペースを使ってます。

★の所が変更点。
shortの整数に。
intと書くと、チップが32ビットなのでlongのデータになって
しまいます。

それと、atan2()のX、Yを求めている所、
    (float)ttl_y / 10000.0 / SMZ_SIZ
と書くと、コンパイラは除算を2回繰り返していました。
    (float)ttl_y / (10000.0 * SMZ_SIZ)
だと、( )内が定数になって、除算は1回だけ。

※検索:角度の平均値計算

※続き:グルグル回る軸の角度変動の平均値を出す方法#3

| | コメント (0) | トラックバック (0)

2017年2月23日 (木)

グルグル回る軸の角度変動の平均値を出す方法

2016年09月07日:グルグル回る軸の角度変動の平均値を出したい  で
話題にしました「0~359度」ぐるぐる回る軸の回転角度の平均値算出。
これをまとめておきます。

関連するのは初めての「部品」は失敗するかも  の
「ストッパー無しのボリューム」。
この抵抗値から「0~359度」を得たい時の平均値の算出方法です。
単純な加算平均だと「359←0→1」を行き来すると、「180」なんて
値が出てしまいます。

そこで、角度をsinとcosでXとY値に分解して、2つ値を移動平均。
平均値として出てきたXとYから「atan2」で角度を得るという手法です。

sin、cos、atan2関数をそれぞれ1回ずつ実行します。
値により実行時間は変動しますが、32MHzのRX220マイコン
(非力なんでハード的な浮動小数点機能は無い)で処理時間
は100~130μSくらいでした。
  (空きの出力ポートにパルスを出してオシロで時間確認)

// 非力なマイコンなので浮動小数点はfloatで。 doubleではない
// BYTEとWORDの定義
typedef unsigned char    BYTE;
typedef unsigned short   WORD;
// πの値
#define PAI   3.141592654

/***** 四捨五入    *****/
//   正負で±0.5して整数に変換
short round(float d)
{
  if(d >= 0){
    return (short)(d + 0.5);
  }else{
    return (short)(d - 0.5);
  }
}

/***** 360度1回転規制   *****/
//   0~359度を得る
WORD lim359(short d)
{
  if(d < 0){       // マイナスかもしれない
    d = -d;       // 正の数に
    d = d % 360;    // 0~359に
    d = 360 - d;    // 360から減算
  }
  d = d % 360;      // 0~359に
  return d;
}

/***** 角度をスムージング   *****/
// in/out deg:0~359度を得る
#define SMZ_SIZ   20     // スムージング回数

WORD smz359(short deg)
{
static float smz_x[SMZ_SIZ];      // Xスムージングバッファ
static float smz_y[SMZ_SIZ];      // Y
static float ttl_x, ttl_y;       // 合計値
static BYTE f1 = 0;           // 初めての処理
static short p = 0;           // データポインタ
short i;
float x, y, d;
  PH3_H;               // (!!!)PH3 17pin H/L
  d = (PAI / 180.0) * (float)(lim359(deg)); // 角度を0~2πに
  x = cos(d);             // X,Yの値
  y = sin(d);
  if(f1 == 0){            // 初めて
    ttl_x = ttl_y = 0.0;      // バッファを初期値で埋める
    for(i = 0; i <SMZ_SIZ; i++){
      smz_x[i] = x;
      smz_y[i] = y;
      ttl_x += x;         // 合計値
      ttl_y += y;
    }
    p = 0;             // データポインタ
    f1 = 1;             // 初回処理終了
  }
  else{                // 2回目以降
    ttl_x = ttl_x - smz_x[p] + x;  // 古い値を引いて新値を加算
    ttl_y = ttl_y - smz_y[p] + y;
    smz_x[p] = x;          // 新値をセット
    smz_y[p] = y;
    p++;              // ポインタを後ろに
    if(p >= SMZ_SIZ)  p = 0;   // バッファの最後まで来たら先頭に
  }
  x = ttl_x / SMZ_SIZ;        // X,Y平均値
  y = ttl_y / SMZ_SIZ;
  d = (180.0 / PAI) * atan2(y, x);  // atan2でX,Yから角度に
  PH3_L;               // (!!!)PH3 17pin H/L
  return lim359(round(d));      // 0~359
}

※半角スペースだと見にくくなるんで全角スペースを使っています。

★:整数で計算すると・・・グルグル回る軸の角度変動の平均値を出す方法#2

※検索:角度の平均値計算

| | コメント (1) | トラックバック (0)

2017年2月22日 (水)

初めての「部品」は失敗するかも

部品の選定ミスというか、「使ってみないとわからない」
状態でした。

可変抵抗:ボリュームを「360度グルグル回したい」とい
うことから、ストッパーの無いボリュームを買ってきました。

選んだのは『コパル電子のJC10』
こんな小さなのです。
11

軸は間違いなく360度グルグル回ります。
しかし問題が・・・・

端子2番がスライダーです。
左に回すと、端子1-2間の抵抗値が減ってきて、
最終的にショートして0Ωになります。
そのまま回し続けると、1-2間が最大抵抗値に
なって、端子3-2が短絡状態になります。

問題なのはこの遷移状態。
くるっと回した時、端子2が「浮く」(1あるいは3と
つながらない)角度があるんです。

端子1か3かへの短絡が継続してくれれば
いいのですが、2番端子:スラーダーが「オープン」に
なっちゃう場所があるのです。

ちょいと困りました。
簡単な対策は、1-2間に高抵抗を並列に入れて、
オープンにならないようにするしかないですわな。

解決方法、何かありますかな?

※関連:グルグル回る軸の角度変動の平均値を出す方法

| | コメント (0) | トラックバック (0)

2017年2月18日 (土)

「よくある質問」

時間を忘れて、じっと見!

    

★よくある質問 秋月電子通商 電子部品 ネット通販

あれこれトラブルとその解決方法が面白いです。

| | コメント (0) | トラックバック (0)

2017年2月16日 (木)

破壊者「ペコ」、4GBをダメに

ペコがまたまたやってくれました。
長男:浩平のUSBメモリー。
これで、3つ目かな。
「こんなとこ置いておいたら、またペコにやらでるで~」
っと、言っていたやさき。
前の2つは電気的に無事でしたが、今回のはアウト。

Image000

物理的にアウトなのがUSBのコネクタ部。
これくらいなら、こじって修復できそうです。

Image001

しかし・・・・
コンデンサ:C9は完全に飛んでいます。
上右部のハンダ、ガニッっとした痕跡。
Image002

基板上のメモリーチップを見ると、微妙に傾いています。

Image003

傾きの原因は、1番ピン付近を強く噛んだからでしょう。
チップの足が曲がって押されています。

Image004

ICの下で、基板パターンが剥離しているかも。

なかなかのヤンチャ娘:ペコ、やってくれます。


| | コメント (1) | トラックバック (0)

2017年2月13日 (月)

ちょいと珍しいパーツ「シンクロ」

こんなのがやってきました。

11

多摩川精機のシンクロ

電子回路の助けを借りず、5本の線で「回転角度」を伝達
できます。
枯れた技術ですが、ノイズには強いです。
そして、原点復帰の必要がありません。

| | コメント (2) | トラックバック (0)

2017年2月 9日 (木)

初めてのRX220マイコン

48ピンのRX220マイコンでちょいと工作中。
ツールはE1エミュレータにHEWを利用。

11_2

初めてのチップを使う時、あれやこれやら慣れるまでが
たいへん。
で、プログラムの肝をメモ。 (RX210でも同じようなことが)

●I/Oイニシャルでの注意点

・クロックやらの重要レジスタを触る時は
 プロテクトレジスタ:PRCRの操作が必須。
   SYSTEM.PRCR.WORD=0xA503;  // プロテクト一時解除

・ポートの機能を切り替える(単純入出力から周辺内蔵I/O端子が
 使えるように)ときは、PFSレジスタ書き込み許可をオンにしな
 いといけない。
  MPC.PWPR.BIT.B0WI=0;   // B0WIを0にしてから
  MPC.PWPR.BIT.PFSWE=1;   // PFS変更可に

・タイマーやシリアル、A/Dを使うときはモジュールストップ
 を解除しなければならない。
  SYSTEM.MSTPCRA.BIT.MSTPA9=0;  // MTU0
  SYSTEM.MSTPCRA.BIT.MSTPA17=0;  // A/D
  SYSTEM.MSTPCRB.BIT.MSTPB26=0;  // SCI5
  SYSTEM.MSTPCRB.BIT.MSTPB30=0;  // SCI1

これらをしておかないと、周辺I/Oのイニシャルができません。
RX210マイコンでも同様。

タイマーやらA/Dが動かないな~っという時は、これらを
思い出してください。

※追記
例えばMTU0で1mSタイマー割込みを得て、確認のために
500Hz方形波をポートに出したい時。(クロックは16MHzで)
こんな具合に書きます。
             (フォントで文字ずれが出ますが)
// タイマー0, 1ms割込み
  MTU0.TCR.BYTE = b01000010;
  //        |||||+++-------- TPSC 1/16 1MHz
  //        |||++----------- CKEG ↑エッジ
  //        +++------------- CCLR TGRBコンペアマッチ
  MTU0.TIORH.BYTE = b00110000;
  //         ++++------- MTIOC0B トグル
  MTU0.TGRB      = 1000-1;    // 1kHz PA1には500Hz出力
  MTU.TSTR.BIT.CST0  = 1;      // タイマー0開始

  MPC.PA1PFS.BYTE   = 0x01;     // PA1:MTIOC0B ★1
  PORTA.PMR.BIT.B1  = 1;      // PA1周辺機能 ★2

  MTU0.TIER.BIT.TGIEB = 1;      // TGRB割込み許可
  IPR(MTU0, TGIB0) = 0x0F;      // プライオリティ ★3
  IEN(MTU0, TGIB0) = 1;        // 割り込み ★4

PA1に500Hz方形波を出すにはMTU0をイニシャルするだけ
ではだめで、★1、2の処理が必要です。

また、タイマー割込みも、★3、4のように割込みレジスタを
操作しなくちゃなりません。

慣れるまでは、なかなか言うことをきいてくれないマイコンチップです。

| | コメント (0) | トラックバック (0)

2017年2月 8日 (水)

初めてのパーツは要注意!

「秋月」の買い物(通販)で、ついでに買ったのがこの半固定抵抗。
・[3386T-EY5-103TR]
初めて使う部品です。

11

試作でよくつかうのが↓の左側2つ。

12
「TOCOS」の「GF063P」  と 「RGP102」
秋月のはツマミが付いているんで回しやすそうです。
TOCOSのは三角形に足が並んでいますが、秋月のは
一直線。
13

TOCOSの二つ、中央の端子:スライダーを回したその方向が
左右の端子の「1:CCW、3:CW」が直感的に想像できます。
右に回せば「CW」で、端子「3」にスライダーが近づきます。

TOCOSのカタログにはこんな注意書。

A1
・GF063Pの形状図 (クリックで拡大↓)
A2

・RGP102 (クリックで拡大↓)
A3

裏から見ても、表から見ても間違いは無いでしょう。
ところが秋月のTSR-3386は要注意。
ユニバーサル基板へハンダする時に気が付いたのが、
このマーク。
14

『1:CCWと3:CWの位置が直感と逆!』
思わずテスターで確認しました。
この刻印が正解です。
秋月のTSR-3386のPDF を見ても、間違いなく直感と逆の
足ピン配置です。

裏から見たところ↓
A4

これ、ピン配置を確認せず、直感で配線してたら、ハンダ付け
やり直しになるところでした。

昔はこんなこともありました。
   ・TMS9914:恐ろしいピン名称

| | コメント (1) | トラックバック (0)

2017年2月 4日 (土)

電池の自販機

「ペコ」と散歩してて見つけた、電池の自販機。

B1

『パナソニック乾電池』。
昔は良く見ましたが、最近は珍しい(稼働しているのが)
んじゃないでしょか。

しかしこの自販機、良く見ると、電池のサンプルが
こんな状態に。

B2

こんなのを見せられると、あまし買いたくはありません。

・単一
B3

・単二
B4

| | コメント (1) | トラックバック (0)

2017年2月 3日 (金)

エクセルが悪いんじゃない!

パソコンに対する怒りじゃないんです、
これを仕込んだ「担当者」への怒りでっす。

画像はMSエクセルの画面。
セル「A11」には「A1~A9」の合算値が出てくるはず・・・
ところが・・・  結果は空白。

A1

これ、今回のトラブルをガレージPCのエクセルで再現したのです。
このトラブルの被害者は「生野区のある連合の町協・会計」を担っている人。
来年度の予算申請の書式(役所から来た)にのっとり、数値を入力したのに、
結果の数字が出ない。
なぜなの?
これを再現した画面です。

その人は、
   「PCがおかしくなったのか?」
   「入力を間違ったのだろか?」
っと、何度も試行錯誤。

どれだけ無駄な時間を使ったのか。
この時間を「役所」から返してもらいたいぞっ。

今夜のガレージ、このエクセルのトラブルで盛り上がりました。
この原因、みなさんわかりますか?
私には、無理。
でも、単純な話なんですよ。

※追記
「全選択 ctrl-A」すると、白色数字が反転して見えそう
なんですが、カーソルが「=SUM( )」のある「A11」にし
たままですと、白のままで見えません。
ところが、A12まで降ろすとこんな具合にA11の
合算値が出てきます。

Ex0052

なんとなく不思議。
しかし、よくこんなトラップを仕掛けたもんですわ。

| | コメント (6) | トラックバック (0)

2017年2月 1日 (水)

さよならZAQのブログ・・・・

1月末=昨日でおしまいだったはずのZAQのブログ:BLOGari。
2月1日、今朝8時に「居酒屋ガレージ日記」 をアクセスしてみたら、
まだ見えてました。

で、最後にキャプチャしたアクセス数記録がこれ。
(クリックで拡大↓)
A1

そして、この1年の月別アクセス、こんな具合に変化。
(クリックで拡大↓)
A2

こちら に移って、更新しなくなった11月頃から
のアクセス数減少が現れています。

先ほど12時過ぎにアクセスしたら、こんなメッセージが
出ていました。

A0

そして、居酒屋ガレージ 本店(HP) のほうにも
こんなメッセージ。

A3

そのうちこれ↑も出なくなっちゃうのでしょうね。

| | コメント (1) | トラックバック (0)

« 2017年1月 | トップページ | 2017年3月 »