Vol.851 26.Aug.2022

電磁波・電磁場放射テスター (N-8)加減速自動運転

E 電磁波・電磁場放射テスター 〜RT-100(EMFmeter)

by fjk

 携帯電話やパソコンなど電気製品を使っていると、機器から電磁波が出ていて「人体に影響がないか」と思うことがある。そこで、ERICKHILLのEMFテスターRT-100(1,914円)を入手した。

【RT-100の主な仕様】(USB充電)
  • 電界の測定範囲:0.1〜1999 V/m
  • 磁界の測定範囲:0.01 μT〜99.999 μT
  • 測定周波数:5〜3500 MHz
  • アラーム、電界:40 V/m、磁界0.4 μT(画面が赤くなり、ブザー鳴動)
  • その他:AVR/VPP、HOLD、無操作OFF
【身近な電界の値】(距離:0 cm)
雷雲時の地表: 3000〜20000 V/m
送電線の下: 100〜3000 V/m
(液晶)モニタ: 50〜200 V/m
パソコン: 300〜800 V/m
スマホ: 15〜25 V/m

 測定値は結構変動し、意外と大きいと感ずるが、距離を離すと大きく減少する。ちなみの複数のパソコンのモニタに囲まれ、30cm離れた所では、93 V/m、0.16μT程度であった。
 電磁界による健康影響については、被曝をうけている間のみの「短期的被爆」と、「長期的な被爆」によるガンなどの病気が引き起こされる可能性が考えられているが、いずれも科学的な結論が出ていない。
 身の回りの電磁界の強さ電磁界情報センター などを参考に。


スマホの測定例

モニタテレビの測定例

★【参考】


N Nゲージ列車のデジタル運転(8) 〜加減速自動運転

by fjk

 前報(abc850)までに列車の走行制御と列車センサの動作確認ができたので、列車の速度を変化させて自動加減速運転を試みる。レールレイアウトは C103レールを使用したループで、磁気センサを1個設置したものを用いた。ハードウェア(制御回路)は PIC16F18325 を使った abc850 と同じ。
 列車の走行パターンは、加減速を繰り返しながら、指定された速度で定速走行を行うもので、センサを感知する毎にステップを進め、速度の切替を行っている。なお、徐行時にセンサが列車を検知すると列車は停止し、一定の時間経過後に再び(最初から)走行を繰り返す自動運転パターンである。

【列車の運行】
@ 電源投入後しばらくは停車したままで、0.1秒カウンタが 0となったら走行を開始する。
A その後、センサが列車を検出すると、次の運転条件に変わる。
B 速度が指令速度に満たない場合は加速し、指令速度以上なら減速する。
C 徐行時にセンサが列車を検出(立ち上がりエッジ)すると列車は停止する。
D 列車停止後、指定された時間が経過する(0.1秒カウンタが 0になる)と再び走行を開始する。
C 脱線などで過電流が流れるとPWM出力を停止し、赤LEDが点灯。解除はリセットボタンを押す。

列車の運行パターン図
【主な変数】
【ハードウェア】
MCLR端子(RA3)を汎用入出力端子ではなく Reset入力のままにした他は abc850と(回路図も)同じ。なお、VR(RC5)は利用していない・・・。
 
【プログラムの概要】
個別列車の走行条件はtrain_p(列車パラメータ)構造体として保存。
    struct train_p{
    	uint8_t   acf;	// 加速係数
    	uint8_t   dcf;	// 減速係数
    	uint16_t  rsL;	// 走行停止PWMパルス幅
    	uint16_t  upL;	// 走行上限PWMパルス幅
    	uint16_t  slw;	// 徐行時PWMパルス幅(停止準備)
    };	
運転に必要な条件はdrv_val(列車制御変数)構造体配列に保存。条件が揃えば次のステップへ移動。
    struct drv_val{
    	uint8_t   nxt;	// 次ステップ番号
    	uint16_t  spd;	// 指令走行PWMパルス幅
    	uint8_t   drc;	// 指令走行方向
    	uint16_t  stm;	// 停止時間 (100ms単位)
    };

 走行テストに用いた列車は「C103レール」に対応する「TM-03動力ユニット」を付けた「デキ100」で、「粘着付き超強力 ネオジウムマグネットシート」(RMG-026、t = 0.8mm、和気産業、1,500円)を5mm角(60 mT)に切って床下に貼付けた。なお、同じ厚みの強力フェライトシート(1cm角で15 mT)では磁気センサが列車を検知せず。
 今回の例では、周回レール長が短いので、センサーを1個しか使わなかったが、周回レール長が長い場合や単線往復運転の場合、複数のセンサ(最大4個)をセットし、それに併せて状態変化割り込み処理を記述することで、ホーム停車・往復運転などの自動運転が可能となる。
 なお、関数のプロトタイプ宣言は、同じファイル内で関数を使用する前に記述することで省略している。必要であればヘッダーファイル(train.h)中で宣言して下さい。また、PICでのデバッグを容易にするためグローバル変数を多用したが、ローカル変数に変更も可能。


デキ100の床下に磁石を貼付

LCDを外した試作回路

自動運転中の様子

状態表示例1(加速)

状態表示例2(定速)

状態表示例3(停止)
/*======================
 *	train.h
 *=====================*/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include <stdio.h>
#include "i2cLCD_AQM0802A.h"

#define _XTAL_FREQ 32000000
#define PWM_OUT(x) (PWM5_LoadDutyValue(x))

enum {
    BREAK = 0,
    LOWLM,
    SLWSP,
    CNTSP,
    ACCEL,
    DECEL,
    UPRLM,
    TRABL
}Drv_Stat;

struct train_p{
    uint8_t   acf;	// 加速係数
    uint8_t   dcf;	// 減速係数
    uint16_t  rsL;	// 走行停止PWMパルス幅
    uint16_t  upL;	// 走行上限PWMパルス幅
    uint16_t  slw;	// 徐行時PWMパルス幅(停止準備)
};	

struct drv_val{
    uint8_t   nxt;	// 次ステップ番号
    uint16_t  spd;	// 指令走行PWMパルス幅
    uint8_t   drc;	// 指令走行方向
    uint16_t  stm;	// 停止時間 (100ms単位)
};

/*====================
 *	main.c	(abc851)
 *====================*/
#include "train.h"

#define STP_L   200		// 走行停止最大PWMプルス幅
#define SL_SP   300		// 徐行時PWMパルス幅

/*--- Drive Sequence array ---*/
struct drv_val s[] = {
        {1,   0,   0,  30},
        {2, 400,   1,   0},
        {3, 500,   1,   0},
        {4, 400,   1,   0},
        {5, SL_SP, 1,   0},
        {1, STP_L, 0, 100}};

struct train_p t = {0, 0, STP_L, 800, SL_SP};
struct drv_val *a;

/*--- Global Variables ---*/
    uint8_t 	TMd = 0;	// 走行モード(reserved)
    uint8_t 	Sts = 0;	// 走行ステータス
    uint8_t 	Snm = 0;	// ステップ番号
    uint16_t 	Spd = 0;	// 現在走行PWMパルス幅
    uint8_t 	Drc = 0;	// 現在進行方向
    uint8_t 	Vct = 0;	// 加減速用カウンタ
    uint16_t 	Tmc = 0;	// 停止時間カウンタ
    uint8_t 	IrFlg = 0;	// 状態割り込みフラグ
    char    	sBuf[10];	// 文字列関数作業用

/*--- LCD Functions ---*/
void dsp_sts(uint8_t n){
    Sts = n;   				// ステータス番号セット
    LCD_cursor(0,0);
    switch(n){
        case 0:
            LCD_str("Brak!");	break;
        case 1:
            LCD_str("LowLm");	break; 
        case 2:
            LCD_str("SlwSp");	break; 
        case 3:
            LCD_str("CntSp");	break; 
        case 4:
            LCD_str("Acccl");	break; 
        case 5:
            LCD_str("Decel");	break; 
        case 6:
            LCD_str("UppLm");	break; 
        case 7:
            LCD_str("Trbl!");	break; 
    }
}

void dsp_pwm(uint8_t x, uint16_t n){
    sprintf(sBuf,"%4d",n);
    LCD_cursor(x,1);
    LCD_str(sBuf);    
}

void dsp_stp(uint8_t n){
    sprintf(nBuf,"%2d",n);
    LCD_cursor(6,0);   
    LCD_str(nBuf);
}

/*--- speed up/down functions ---*/
void speed_up(){
    if(Vct == 0){
        Spd++;
        Vct = t.acf;
    }else{
        Vct--;
    }
}

void speed_dwn(){
    if(Vct == 0){
        Spd--;
        Vct = t.dcf;
    }else{
        Vct--;
    }
}

/*--- CWG controle function --*/
void set_CWG(uint8_t x){
    LCD_cursor(5,0);
    switch(x){
        case 0:
            CWG1STR = 0xF5;		// ブレーキ
            LCD_dat('*');
            break;
        case 1:
            CWG1STR = 0xF1;		// 前進走行
            LCD_dat(0x7E);
            break;
        case 2:
            CWG1STR = 0xF4;		// 後進走行
            LCD_dat(0x7F);
            break;
    }
}

/*==== Main application =====*/
void main(void)
{
    SYSTEM_Initialize();
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();

    uint16_t tSp;				// 目標走行PWMパルス幅

    LCD_init();
    DACCON1 = 0x03;				// 過電流閾値セット(DAC)
    dsp_sts(BRAEK);

    do{
        dsp_stp(Snm);			// 現在ステップ値を表示
        a = &s[Snm];    		// 走行データ配列ポインタセット
        Tmc = a->stm;
        if(Spd <= t.rsL){		// 列車が停止中なら進行方向セット
            Drc = a->drc;
            set_CWG(Drc);
        }
        if(a->spd > t.upL){		// 指令PWM値が最大値を超えているか
            tSp = t.upL;
        }else if(a->spd < t.rsL){
            tSp = t.rsL;
        }else{
            tSp = a->spd;
        }
        dsp_pwm(4,tSp);
        do{
            if(CWG1AS0bits.CWG1SHUTDOWN){
                dsp_sts(TRABL);			// 過電流トラブル発生
                dsp_pwm(0, 0);
                Led_A5_SetHigh();
                break;      			// トラブルでループ脱出
            }
            if(Tmc > 0){    			// 停止中タイマー処理
                __delay_ms(100);
                Tmc--;
                dsp_pwm(4,Tmc);
                if(Tmc == 0){
                     break;			// タイマー=0ならループ脱出
                }
            }else{
                if(Spd < tSp){
                    dsp_sts(ACCEL);	    	// 加速中
                    speed_up();
                }else if(Spd > tSp){
                    dsp_sts(DECEL);	    	// 減速中
                    speed_dwn();
                }else{
                    if(Spd == t.slw){
                        dsp_sts(SLWSP);		// 徐行中
                    }else if(Spd == t.upL){
                        dsp_sts(UPRLM);		// 最速走行中
                    }else{
                        dsp_sts(CNTSP);		// 定速走行中
                    }
                }
            }
            PWM_OUT(Spd);
            dsp_pwm(0, Spd);
        }while((IrFlg == 0)||(Tmc > 0)); // センサ入力無し又はタイマー残あれば

        if(Sts == SLWSP){      		// 徐行中にセンサ入力があれば
            Spd = t.rsL;
            PWM_OUT(Spd);       	// 走行停止
            dsp_pwm(0, t.rsL);
            dsp_sts(LOWLM);
        }
        if(Sts == TRABL){  		// トラブル発生中なら
             break;        		// ループ脱出
        }
        IrFlg = 0;      		// 割り込みフラグをクリア
        Snm = a->nxt;   		// 次ステップへ
    }while(Snm < 100);  		// ステップ値が99より大きいと終了

    set_CWG(0);     			// PWM出力停止
    if(Sts != TRABL){
        dsp_sts(BREAK);
    }
}


※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。


電磁波・電磁場放射テスター (N-8)加減速自動運転