目次

サーボモータドライブ

 次のサーボモータドライブ回路をテストします。




 IchigoJamの出力は、4ビットが基本なので、4ビットでは
 パルスカウント(100から200)を出力できないので
 表を用意し対応します。

 対応は、次表とします。
 (左がデコーダの入力値、右を出力値)

 0 : 100
 1 : 105
 2 : 110
 3 : 120
 4 : 130
 5 : 140
 6 : 150
 7 : 160
 8 : 170
 9 : 180
10 : 190
11 : 200
12 : 150
13 : 150
14 : 150
16 : 150

 パルスカウントはCPLD、FPGA内部で変換されると
 すればIchigoJamは、4ビットデータを時間間隔を
 入れて出力するだけ。

10 ' test Servo motor
20 FOR I=0 TO 15
30   LET J,I:GOSUB 100
40   FOR K=1 TO 4:OUT K,[K]:NEXT
50   FOR K=1 TO 10:WAIT 60:NEXT
60 NEXT
70 FOR K=1 TO 4:OUT K,0:NEXT
80 END
100 '
110 FOR K=1 TO 4
120   LET [K],J % 2:LET J,J >> 1
130 NEXT
135 ? [4],[3],[2],[1]
140 RTN

 0から15の整数を4ビットに変換するために
 サブルーチンで配列にビットを構成する1と0
 を計算して保存します。

 ラベルを使えば、次のようにも書けます。

10 ' test Servo motor
20 FOR I=0 TO 15
30   LET J,I:GSB @HND
40   FOR K=1 TO 4:OUT K,[K]:NEXT
50   FOR K=1 TO 10:WAIT 60:NEXT
60 NEXT
70 FOR K=1 TO 4:OUT K,0:NEXT
80 END
100 @HND
110 FOR K=1 TO 4
120   LET [K],J % 2:LET J,J >> 1
130 NEXT
135 ? [4],[3],[2],[1]
140 RTN

 4ビット入力で、カウント値(8ビット)を生成するVHDL
 コードは、以下。

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

entity decx is
  port (
    -- input
    DDIN  : in  std_logic_vector(3 downto 0) ;
    -- enable
    DDOUT : out std_logic_vector(7 downto 0) --;
  );
end decx ;

architecture behavioral of decx is
  -- input
  signal iDDIN  : integer range 0 to 15 ;
  -- output
  signal iDDOUT : integer range 0 to 200 ;
begin
  -- output
  DDOUT <= conv_std_logic_vector(iDDOUT,8) ;

  -- input
  iDDIN <= conv_integer(DDIN) ;

  -- decode
  iDDOUT <= 105 when ( iDDIN =  1 ) else
            110 when ( iDDIN =  2 ) else
            120 when ( iDDIN =  3 ) else
            130 when ( iDDIN =  4 ) else
            140 when ( iDDIN =  5 ) else
            150 when ( iDDIN =  6 ) else
            160 when ( iDDIN =  7 ) else
            170 when ( iDDIN =  8 ) else
            180 when ( iDDIN =  9 ) else
            190 when ( iDDIN = 10 ) else
            200 when ( iDDIN = 11 ) else
            150 when ( iDDIN = 12 ) else
            150 when ( iDDIN = 13 ) else
            150 when ( iDDIN = 14 ) else
            150 when ( iDDIN = 15 ) else
            100 ;

end behavioral;

 パルスカウントに対応した波形生成は、次の記述で。

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

entity svmx is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- enable
    ENX    : in  std_logic ;
    -- duty ratio
    DUTYX  : in  std_logic_vector(7 downto 0) ;
    -- enable
    WOUT   : out std_logic --;
  );
end svmx ;

architecture behavioral of svmx is
  -- counter
  signal iPCNT : integer range 0 to 1999 ;
  -- internal register
  signal iDCNT : integer range 0 to 200 ;
  -- internal register
  signal iWOUT : std_logic ;
begin
  -- output
  WOUT <= iWOUT when ( ENX = '1' ) else '0' ;

  -- convert
  iWOUT <= '1' when ( iPCNT < iDCNT ) else '0' ;

  -- counter
  process (nRESET,CLOCK)
  begin
    if ( nRESET = '0' ) then
      iPCNT <= 0 ;
      iDCNT <= 0 ;
    elsif rising_edge(CLOCK) then
      if ( iPCNT = 100 ) then
        iPCNT <= 0 ;
        iDCNT <= conv_integer(DUTYX) ;
      else
        iPCNT <= iPCNT + 1 ;
      end if ;
    end if ;
  end process ;

end behavioral;

 2つの回路を動かすためのドライバは、以下。

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

entity mcrc is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ; -- 4MHz
    -- monitor
    MCLK   : out std_logic ;
    -- input
    DIN    : in  std_logic_vector(3 downto 0) ;
    ENX    : in  std_logic ;
    -- pulse out
    DOUT   : out std_logic --;
  );
end mcrc ;

architecture behavioral of mcrc is
  -- constant
  CONSTANT CNTMAX  : integer := 39 ;
  CONSTANT CNTHALF : integer := 20 ;
  -- clock divider
  signal iCNT : integer range 0 to CNTMAX ;
  signal iCLK : std_logic ;
  --
  signal iDUTY : std_logic_vector(7 downto 0) ;
  -- decoder
  component decx is
    port (
      -- input
      DDIN  : in  std_logic_vector(3 downto 0) ;
      -- enable
      DDOUT : out std_logic_vector(7 downto 0) --;
    );
  end component ;
  -- pwm generator
  component svmx is
    port (
      -- system
      nRESET : in  std_logic ;
      CLOCK  : in  std_logic ;
      -- enable
      ENX    : in  std_logic ;
      -- duty ratio
      DUTYX  : in  std_logic_vector(7 downto 0) ;
      -- enable
      WOUT   : out std_logic --;
  );
  end component ;
  -- internal register
  signal iFOUT : std_logic ;
begin
  -- output
  MCLK <= not iCLK ;
  DOUT <= iFOUT ;

  -- clock divider
  process (nRESET,CLOCK)
  begin
    if ( nRESET = '0' ) then
      iCNT <= 0 ;
    elsif rising_edge(CLOCK) then
      if ( iCNT = CNTMAX ) then
        iCNT <= 0 ;
      else
        iCNT <= iCNT + 1 ;
      end if ;
    end if ;
  end process ;
  iCLK <= '1' when ( iCNT < CNTHALF ) else '0' ;

  -- module instance (decoder)
  DECXinst : decx port map (
      -- input
      DDIN  => DIN ,
      -- enable
      DDOUT => iDUTY
  );

  -- module instance
  SVMXxinst : svmx port map (
      -- system
      nRESET => nRESET ,
      CLOCK  => iCLK ,
      -- enable
      ENX    => ENX ,
      -- duty ratio
      DUTYX  => iDUTY ,
      -- enable
      WOUT   => iFOUT
  );

end behavioral;

 ピンアサインは、次のUCFファイルでまとめておきます。

# system
NET "CLOCK"  LOC = "P5"  ;
NET "nRESET" LOC = "P39" ;

# input
NET "DIN<0>"  LOC = "P1" ;
NET "DIN<1>"  LOC = "P2" ;
NET "DIN<2>"  LOC = "P3" ;
NET "DIN<3>"  LOC = "P4" ;
NET "ENX"     LOC = "P6" ;

# output
NET "DOUT" LOC = "P11" ;

# monitor
NET "MCLK" LOC = "P44" ;

 IchigoJamのBASICでは、乱数を利用できます。

 サーボモータが作り出す角度を乱数で決めると
 面白い動きを見られます。

 出力は4ビットなので、0から15の乱数を発生させ
 制御回路に与えます。

10 ' test Servo motor
20 LET J,RND(16):GOSUB 100
30 FOR K=1 TO 4:OUT K,[K]:NEXT
40 FOR K=1 TO 10:WAIT 60:NEXT
50 IF BTN() GOTO 70
60 GOTO 20
70 FOR K=1 TO 4:OUT K,0:NEXT
80 END
100 '
110 FOR K=1 TO 4
120   LET [K],J % 2:LET J,J >> 1
130 NEXT
135 ? [4],[3],[2],[1]
140 RTN

 サーボモータにパルス波形を与える場合、クロックを利用します。
 このクロックは、100kHzとしています。

 クロックの有無を目視するために、フリップフロップICを
 利用します。

 回路は単純。
 フリップフロップICのクロックに、サーボモータを
 動かすもとになるクロック100kHzを接続します。
 IchigoJamから2HzのクロックをD入力に与えます。



 IchigoJamのプログラムは、以下。

10 ' test Servo motor 2
20 OUT 1,1 : WAIT 60
30 OUT 1,0 : WAIT 60
40 IF BTN() GOTO 60
50 GOTO 20
60 ?"exit"
70 END

 次のように、2つのプッシュボタンを利用して、角度を
 0、90、180度にするためのBASICコードを作成し
 テストしてもよいでしょう。

10 ' servo motor control
20 S = 0 : GSB @POUT
30 @LOOP
40 GSB @GETS
50 ? S
60 GSB @POUT
70 ? T
80 GOTO @LOOP
90 END
100 @GETS
110 S = IN(4)*2 + IN(1)
120 RTN
200 @POUT
210 T = 1500
220 IF S = 1 THEN T = 2000
230 IF S = 2 THEN T = 1000
240 PWM 4,T
250 WAIT 60
260 RTN

 プッシュボタンを押すと、論理値の'1'を取得できる
 仕様です。




目次

inserted by FC2 system