目次

チョッパ回路と位相制御回路

 チョッパ回路は、発振回路を利用して、AC電源を負荷に
 接続するか、負荷から切断するかを制御します。

 AC電源と負荷の接続か切断では、負荷が必要とする
 電力を調整できないので、位相を調整して電力制御
 します。

 チョッパ回路で、照明器具の照度を制御する場合を
 考えてみます。

 AC電源は、アウトレットにある実効値100Vを使います。



 照明器具には、白熱電球を使います。



 AC電源の周波数は、50Hzか60Hzなのでチョッパ回路で
 位相制御しやすいように、トランスを利用してゼロクロス
 ポイントを取り出します。



 トランスから、ゼロクロスポイントを取り出す回路は
 以下です。



 原理は単純で、AC100Vを降圧してAC10V前後にします。
 このAC10Vを全波整流し、脈流としてフォトカプラに
 与えます。フォトカプラ内部のLEDで光に変換後、
 フォトトランジスタをON/OFFします。

 タイミングチャートで示すと、以下です。



 フォトカプラ出力のエッジをトリガーに使えば
 ゼロクロスポイントから、指定時間だけ論理値
 のHかLを出力させられます。

 指定時間だけ、AC電源電圧を負荷に与えると
 電力制御ができます。



 ゼロクロスポイントから指定時間だけ、制御信号
 を出力する回路を考えます。



 DIPスイッチで指定するカウント値を取り出し
 電力制御信号を、その時間だけゲートトリガー
 出力を遅らせる仕様を考えます。

 PLDを利用する場合、VHDLコードは以下です。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pconx is
  generic (
    TOPX : integer := 14  ;
    RMAX : integer := 9217 -- ; 1.8434MHz => 10kHz
  );
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- AC cross point input
    ACP    : in  std_logic ;
    -- counter value input
    CNTV   : in  std_logic_vector(5 downto 0) ;
    -- controlo out
    COUT   : out std_logic ;
    LED    : out std_logic -- ;
  );
end pconx;

architecture Behavioral of pconx is
  -- component clock generator
  component clkgenx is
    generic (
      TOPX : integer ; 
      RMAX : integer --;
    );
    port (
      -- system
      nRESET : in  std_logic ;
      CLOCK  : in  std_logic ;
      -- output
      CLKOUT : out std_logic -- ;
    );
  end component ;
  -- clock 
  signal iMCLK  : std_logic ;
  -- master sequencer
  signal iSTATE   : std_logic_vector(1 downto 0) ;
  signal iCNTVX   : std_logic_vector(5 downto 0) ;
  signal iTRG     : std_logic ;
  signal iTRG_SFT : std_logic_vector(2 downto 0) ;
begin
  -- component clock generator (1.8434MHz/9217 = 20kHz)
  CLKX : clkgenx generic map (TOPX,RMAX) port map (nRESET,CLOCK,iMCLK);

  -- output
  COUT <= '1' when ( iSTATE = "11" ) else '0' ;
  LED  <= not iMCLK ;

  -- master sequencer
  process (nRESET,iMCLK)
  begin
    if ( nRESET = '0' ) then
      iTRG_SFT <= "000" ;
    elsif rising_edge(iMCLK) then
      iTRG_SFT <= iTRG_SFT(1 downto 0) & ACP ;
    end if ;
  end process ;
  iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;

  -- master sequencer
  process (nRESET,iMCLK)
  begin
    if ( nRESET = '0' ) then
      iSTATE <= "00" ;
      iCNTVX <= (others => '0') ;
    elsif rising_edge(iMCLK) then
      case conv_integer(iSTATE) is
        -- wait trigger
        when 0 => if ( iTRG = '1' ) then
                    iSTATE <= "01" ;
                    iCNTVX <= CNTV ;
                  else
                    iSTATE <= "00" ;
                  end if ;
        -- delay
        when 1 => if ( conv_integer( iCNTVX ) = 0 ) then
                    iSTATE <= "11" ;
                  else 
                    iCNTVX <= iCNTVX - '1' ;
                    iSTATE <= "01" ;
                  end if ;
        -- send trigger
        when 3 => iSTATE <= "10" ;
        -- return first state
        when 2 => iSTATE <= "00" ;
        -- default
        when others =>
                  iSTATE <= "00" ;
      end case ;
    end if ;
  end process ;

end Behavioral;

 ゼロクロスポイントの立上がりエッジを利用し
 DIPスイッチの値を記憶します。カウンタが
 ゼロになったなら、トリガーを出力します。

 マイクロコンピュータで実現する場合は
 次のようなファームウエアを使います。

#include <avr/io.h>
#include <avr/interrupt.h>

#define OFF 0
#define ON  OFF+1

#define MASK3F 0x3F

#define ACBIT 0x40

typedef unsigned char  UBYTE ;
typedef unsigned short UWORD ;
typedef   signed char  SBYTE ;
typedef   signed short SWORD ;

volatile UBYTE eflag ;
volatile UBYTE tflag ;
volatile UBYTE cflag ;

volatile UBYTE count  ;
volatile UBYTE countx ;

/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void  user_initialize(void);

/*------*/
/* main */
/*------*/
int main(void)
{
  /* initialize port and variables */
  user_initialize();
  /* enable interrupt */
  sei();
  /* endless loop */
  while ( ON ) {
    /* set value */
    if ( eflag ) {
      /* clear flag */
      eflag = OFF ;
      /* get count value */
      count  = PINB & MASK3F ;
      countx = count ;
      /* enable */
      tflag = ON ;
    }
    /* AC phase handling */
    if ( cflag ) {
      /* clear flag */
      cflag = OFF ;
      /* judge */
      if ( tflag == OFF ) { PORTD &= ~ACBIT ; }
      else {
        /* count down */
        countx-- ;
        if ( countx == 0 ) {
          tflag = OFF ;
          /* send H signal */
          PORTD |= ACBIT ;
          /* send H signal */
          PORTD &= ~ACBIT ;
        }
      }
    }
  }
  /* dummy */
  return 0 ;
}

/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
  /* PORT B */
  PORTB = 0b00111111 ; /* 00000000 */
  DDRB  = 0b11000000 ; /* oooooooo */
  /* PORT D */
  PORTD = 0b00000100 ; /* 00000000 */
  DDRD  = 0b11111011 ; /* oooooioo */
  /* clear flags */
  eflag = OFF ;
  tflag = OFF ;
  cflag = OFF ;
  /* clear counters */
  count  = 0 ;
  countx = 0 ;
  /* initialize INT0 */
  {
    /* clear counter */
    MCUCR = (3 << ISC00) ;
    /* Enable interrupt */
    GIMSK = (1 << INT0) ;
  }
  /* initialize timer1 */
  {
    /* clear counter */
    TCNT1 = 0 ;
    /* initialize counter */
    OCR1A = 49 ;
    OCR1B = 99 ;
    /* set prescaler (/8) */
    /* select clock and prescaler (generate 10kHz) */
    TCCR1B = (1 << WGM12) | (1 << CS11) ;
    /* Enable interrupt */
    TIMSK = (1 << OCIE1A) ;
  }
}

/* INT0 */
ISR(INT0_vect)
{
  eflag = OFF ;
}

/* Timer1 interrupt */
ISR(TIMER1_COMPA_vect)
{
  cflag = ON ;
}

 外部割込みをゼロクロスポイントの
 トリガー入力に接続します。

 PLDあるいはマイクロコンピュータで
 チョッパ回路を実現しても、AC電源を
 接続、切断する回路は、ソリッドステート
 リレーを使います。



 位相制御で使うトリガーの出力タイミング
 を、固定してもよい場合に、タイマーICの
 555を使うこともできます。



 発振回路の周波数が低い場合は、PUT(Programmable Unijunction Transistor)
 を、使うこともできます。



 PUTは、稼動させる電源電圧の範囲が広いので
 使いやすい発振回路を実現できます。

 PUTは、電圧を分割している2本の抵抗のうちの片側の
 抵抗値を可変にすると、発振周波数を変えられます。


目次

inserted by FC2 system