目次
前
次
メカ変更
試走を繰り返しているうちに、モータを入れたギア
ボックスの固定エリアが破損してしまいました。
予備のギアボックスがありますが、遊んでいた移動
メカに同じギアボックスが使われていたので、代用
します。
タイヤを交換し、前方に小さなキャスターを入れました。
大量のデジタル回路を入れられるFPGA基板と
モータドライブ回路を載せた基板を実装可能
になりました。
前方を左右に振る動作を最小限に抑えるために
サーボモータを利用した舵角メカを加えます。
舵角メカには、サーボモータを入れることにし
CPLD/FPGA基板上に、制御回路とDCDCコンバータ
を載せます。
前方に、制御回路とDCDCコンバータをいれても
充分余裕があります。
外部回路の動作確認に利用したVHDLコードは以下。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mcrtsty is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- trigger
TRG : in std_logic ;
-- DIP switch inputs
DIN : in std_logic_vector(1 downto 0) ;
-- logic
BKWTIN : in std_logic ;
-- monitor output
MLOUT : out std_logic_vector(1 downto 0);
MBKT : out std_logic ;
-- monitor output
PWMOUT : out std_logic_vector(1 downto 0);
-- rotary encoder
ENC : out std_logic_vector(1 downto 0);
RENC : in std_logic ;
LENC : in std_logic ;
-- output
LOUT : out std_logic_vector(7 downto 0);
LOUTX : out std_logic -- ;
);
end mcrtsty ;
architecture Behavioral of mcrtsty is
-- clock generator
signal iCNT : std_logic_vector(27 downto 0) ;
signal iMCLK : std_logic ;
-- trigger handling
signal iTRG_SFT : std_logic_vector(2 downto 0) ;
signal iTRG : std_logic ;
-- decoder
signal iLOUTX : std_logic ;
signal iLOUT : std_logic_vector(7 downto 0);
-- sequencer
signal iSTATE : std_logic_vector(1 downto 0) ;
signal iENABLE : std_logic ;
signal iPWMOUT : std_logic_vector(1 downto 0) ;
-- DIP switch inputs
signal iDIN : std_logic_vector(1 downto 0) ;
signal iREG : std_logic_vector(1 downto 0) ;
--
signal iBKWTIN : std_logic ;
-- rotary encoder
signal iRENC : std_logic ;
signal iLENC : std_logic ;
signal iRENC_SFT : std_logic_vector(2 downto 0) ;
signal iLENC_SFT : std_logic_vector(2 downto 0) ;
signal iRENC_TRG : std_logic ;
signal iLENC_TRG : std_logic ;
signal iRENC_CNT : std_logic_vector(11 downto 0) ;
signal iLENC_CNT : std_logic_vector(11 downto 0) ;
signal iRENC_CNTX : std_logic_vector(11 downto 0) ;
signal iLENC_CNTX : std_logic_vector(11 downto 0) ;
signal iROT_STATE : std_logic_vector(1 downto 0) ;
signal iROT_CNT : integer range 0 to 100 ;
signal iROT_CLR : std_logic ;
signal iROT_DISTANCE : integer range 0 to 65535 ;
begin
-- outputs
LOUTX <= not iLOUTX ;
LOUT <= not iLOUT ;
MLOUT <= iREG ;
PWMOUT <= iPWMOUT ;
MBKT <= iBKWTIN ;
ENC <= iLENC & iRENC ;
-- inputs
iDIN <= DIN ;
iBKWTIN <= BKWTIN ;
iRENC <= not RENC ;
iLENC <= not LENC ;
-- clock generator
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iCNT <= (others => '0') ;
elsif rising_edge(CLOCK) then
iCNT <= iCNT + '1' ;
end if ;
end process ;
iMCLK <= iCNT(18) ;
-- trigger
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iTRG_SFT <= "000" ;
elsif rising_edge(iMCLK) then
iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ;
end if ;
end process ;
iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;
-- sequencer
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
elsif rising_edge(iMCLK) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iTRG = '1' ) then
iSTATE <= "01" ;
else
iSTATE <= "00" ;
end if ;
-- dummy skip
when 1 => iSTATE <= "11" ;
-- wait trigger
when 3 => if ( iTRG = '1' ) then
iSTATE <= "10" ;
else
iSTATE <= "11" ;
end if ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
iENABLE <= iSTATE(0) ;
-- decoder
iLOUTX <= iCNT(20) when ( iENABLE = '1' ) else '0' ;
iLOUT <= iCNT(27 downto 20) ;
-- DIP switch inputs
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iREG <= "00" ;
elsif rising_edge(iMCLK) then
iREG <= iDIN ;
end if ;
end process ;
iPWMOUT(0) <= iCNT(22) when ( iENABLE = '1' ) else '0' ;
iPWMOUT(1) <= iCNT(23) when ( iENABLE = '1' ) else '0' ;
-- rotary encoder
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iRENC_SFT <= "000" ;
iLENC_SFT <= "000" ;
elsif rising_edge(iMCLK) then
iRENC_SFT <= iRENC_SFT(1 downto 0) & iRENC ;
iLENC_SFT <= iLENC_SFT(1 downto 0) & iLENC ;
end if ;
end process ;
iRENC_TRG <= '1' when ( iRENC_SFT = "011" or iRENC_SFT = "001" ) else '0' ;
iLENC_TRG <= '1' when ( iLENC_SFT = "011" or iLENC_SFT = "001" ) else '0' ;
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iRENC_CNT <= (others => '0') ;
iLENC_CNT <= (others => '0') ;
elsif rising_edge(iMCLK) then
-- right side
if ( iRENC_TRG = '1' ) then
iRENC_CNT <= iRENC_CNT + '1' ;
elsif ( iROT_CLR = '1' ) then
iRENC_CNT <= (others => '0') ;
end if ;
-- left side
if ( iLENC_TRG = '1' ) then
iLENC_CNT <= iLENC_CNT + '1' ;
elsif ( iROT_CLR = '1' ) then
iLENC_CNT <= (others => '0') ;
end if ;
end if ;
end process ;
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iROT_STATE <= "00" ;
iRENC_CNTX <= (others => '0') ;
iLENC_CNTX <= (others => '0') ;
iROT_CNT <= 0 ;
iROT_DISTANCE <= 0 ;
elsif rising_edge(iMCLK) then
case conv_integer(iROT_STATE) is
-- transfer
when 0 => iROT_STATE <= "01" ;
iRENC_CNTX <= iRENC_CNT ;
iLENC_CNTX <= iLENC_CNT ;
-- clear and add
when 1 => iROT_STATE <= "11" ;
iROT_CNT <= 99 ;
iROT_DISTANCE <= iROT_DISTANCE + conv_integer(iRENC_CNTX ) ;
-- wait
when 3 => if ( iROT_CNT = 0 ) then
iROT_STATE <= "10" ;
else
iROT_STATE <= "11" ;
iROT_CNT <= iROT_CNT - 1 ;
end if ;
-- return first state
when 2 => iROT_STATE <= "00" ;
-- default
when others =>
iROT_STATE <= "00" ;
end case ;
end if ;
end process ;
iROT_CLR <= '1' when ( iROT_STATE = "01" ) else '0' ;
end Behavioral;
ピンアサインは、以下としてあります。
BLOCK RESETPATHS;
BLOCK ASYNCPATHS;
#
BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;
IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;
# system
LOCATE COMP "nRESET" SITE "70" ;
LOCATE COMP "CLOCK" SITE "50" ; # 10MHz
# trigger input
LOCATE COMP "TRG" SITE "68" ;
# Black or White logic value select
LOCATE COMP "BKWTIN" SITE "57" ;
# LED output
LOCATE COMP "LOUTX" SITE "71" ;
LOCATE COMP "MBKT" SITE "38" ;
# rotary encoder
LOCATE COMP "RENC" SITE "52" ;
LOCATE COMP "LENC" SITE "54" ;
LOCATE COMP "ENC[0]" SITE "48" ;
LOCATE COMP "ENC[1]" SITE "55" ;
#
LOCATE COMP "LOUT[0]" SITE "97" ;
LOCATE COMP "LOUT[1]" SITE "98" ;
LOCATE COMP "LOUT[2]" SITE "99" ;
LOCATE COMP "LOUT[3]" SITE "100" ;
LOCATE COMP "LOUT[4]" SITE "104" ;
LOCATE COMP "LOUT[5]" SITE "105" ;
LOCATE COMP "LOUT[6]" SITE "106" ;
LOCATE COMP "LOUT[7]" SITE "107" ;
# DIP switch inputs
LOCATE COMP "DIN[0]" SITE "62" ;
LOCATE COMP "DIN[1]" SITE "67" ;
# monitor outpus
LOCATE COMP "MLOUT[0]" SITE "61" ;
LOCATE COMP "MLOUT[1]" SITE "65" ;
# PWM_OUT
LOCATE COMP "PWMOUT[0]" SITE "60" ; # right
LOCATE COMP "PWMOUT[1]" SITE "58" ; # left
サーボモータの動作は、Arduinoを利用しました。
Arduinoから、0、90、180度の3つの角度に
相当するパルスを出力してテストしました。
スケッチは、以下です。
#include <Servo.h>
// pin assignment
#define SERVOPIN 3
#define DMAX 179
#define DMID 90
#define DMIN 0
#define INTERV 200
// create servo object to control a servo
Servo oneservo;
int val;
char cmd ;
int xinterval ;
void show_help()
{
Serial.println("? help");
Serial.println("s 0 degree");
Serial.println("m 90 degree");
Serial.println("l 180 degree");
}
void setup()
{
// serial
Serial.begin(9600);
// attaches the servo
oneservo.attach(SERVOPIN);
// place 90 degree
val = DMID ;
oneservo.write(val);
// delay counter
xinterval = INTERV ;
}
void loop()
{
// serial handling
if (Serial.available() > 0) {
// get command
cmd = Serial.read();
// judge
if ( cmd == '?' ) { show_help() ; }
if ( cmd == 's' ) { val = DMIN ; }
if ( cmd == 'm' ) { val = DMID ; }
if ( cmd == 'l' ) { val = DMAX ; }
// feed back
switch ( val ) {
case DMID : Serial.println(" 90 degree"); break ;
case DMAX : Serial.println("180 degree"); break ;
default : Serial.println(" 0 degree"); break ;
}
}
// impress
oneservo.write(val);
// delay
delay(xinterval);
}
トランジスタによる発振回路で作ったDCDCコンバータは
電流が取れないので、サーボモータを接続するとモニタ
用LEDが即座に消灯しました。
5V前後で動作するサーボモータに交換して
電源を直結すると、Arduinoのパルスで問題
なく動きました。
次にBarCodeScannerを接続して、動作確認しました。
コネクタは、次のように前方に取り付けています。
前方にサーボモータを取り付け、メカ変更終了。
サーボモータの上に、櫓を組んでBarCodeScannerを
実装します。
目次
前
次