目次
前
次
サーボモータドライブ
次のサーボモータドライブ回路をテストします。
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'を取得できる
仕様です。
目次
前
次