Build Thread Matsuura MC-500V Dynomotion Retrofit


Results 1 to 3 of 3

Thread: Matsuura MC-500V Dynomotion Retrofit

  1. #1
    Registered
    Join Date
    Feb 2017
    Location
    Netherlands
    Posts
    0
    Downloads
    0
    Uploads
    0

    Default Matsuura MC-500V Dynomotion Retrofit

    Hi everyone!

    This is my first post to this forum, so go easy on me .

    About three months ago we (three guys in a mancave) bought an old Matsuura MC-500V with a very old computer and control system, from the beginning we planned to retrofit the CNC to be controlled by a modern controller. From experience in the past with Dynomotion we knew that the universality of the KFlop should be sufficient for a successful retrofit. In this topic ill keep track of the progress, success, difficulties and failures. Lets start with pictures of the self claimed "MINI-MASTER":



    And its computer + servo drives and IO:


    We were impressed by the neatly ordered wiring + interfacing system and planned to keep as much as possible intact. By reading the documentation we quickly learned that the axes are actuated by 200V DC servo's with analog controlled servo drives. With this knowledge we ordered a KFlop and Kanalog. We will be designing PCB's to realise the wire to connector interfaces for all the analog interfacing. The other 80% of the IO is connected to two IO interface boards like this (the green one):


    The two interfaces interface between the (old)computer (adres/data bus) and the IO (most of the MDI / user interface buttons, indicator LEDs, spindle, tool changer pneumatics and some to be determined stuff). We thought; what if we could design a coupler between the adres/data bus of the IO interface card and the adres/data bus of the KFlop (that is supposed to go to the Konnect extension). This would satisfy our goal to keep almost all of of the wiring of the machine intact and would by far be the most universal (we could gradually expand the implemented functionality by only firmware updates ). So the reverse engineering started:




    After a couple of evenings fiddling and measuring around with the card in the Matsuura and a logic analyser on the original bus I was able to write a test program to control all reed relays ( 6*8Bits output ) and for what I have seen also the filtered inputs (4*8bits) on the bench with a Arduino. This was enough result to motivate me to start with the next step: try and interface with the KFlop. I did some measurements on the KFlop + I found the konnect protocol description here:

    https://en.industryarena.com/forum/s...g--340204.html
    and
    http://www.cnczone.com/forums/dynomo...ect-kflop.html

    My first go-to attempt was to try (with some help of interrupts) connect the KFlop directly to a STM32F303, I was confident that a STM32 running at 72MHz would be fast enough to interface with the adres/data bus of the KFlop, I was wrong . As m_c in the second link claimed; "However, even with an STM32 clocked to 172MHz, I couldn't get it to respond fast enough. It should be a reasonably simple thing to implement in a FPGA for those with the skills to program such things." the STM was indeed WAY TO SLOW. With the need / desire to still interface the KFlop with the IO board I had no other (easy) option than to refresh my VHDL skill and implement the KFlop interface side on an FPGA. I ordered a Cyclone 2 dev board on ebay and started practicing VHDL:

    Altera Cyclone II EP2C5T144 FPGA CPLD Entwicklungs board DevelI2Copment IO SPI | eBay

    After a couple of days being confronted with how far my skills had rusted I was able to realise and simulate the interface in Modelsim with the delays as if it was all implemented on the FPGA (gate level simulation):



    The VHDL Code - Still in very very very early stage but good enough to evaluate its ability to interface with the KFlop:
    Code:
    library ieee ;
    use ieee.std_logic_1164.all;
    use work.all;
    
    
    entity KonnectToSpi is
      port(	
        RST      : in std_logic;                          -- ToKFLOP
        CLK      : in std_logic;                          -- ToKFLOP
        CLKIN    :	in std_logic;                          -- ToKFLOP
        STARTIN  :	in std_logic;                          -- ToKFLOP
        dataBus  :	inout std_logic_vector (7 downto 0);   -- ToKFLOP
    	 LEDs     : out std_logic_vector (2 downto 0);     -- Debug output LEDS to visualise example output
        konnectSelectedOut : out std_logic := '0';        -- Debug output, goes high when adress m
    	 outputEnable :  out std_logic := '0'              -- Debug output
      );
    end KonnectToSpi;
    
    
    architecture behaviour of KonnectToSpi is
      signal STARTINRisingEdge  : std_logic := '0';
      signal STARTINFallingEdge : std_logic := '0';
      signal konnectSelected    : std_logic := '0';
      signal statePointer       : integer range 0 to 16;
      signal statePointerBuffer : integer range 0 to 16;  
      
      signal input0              : std_logic_vector(7 downto 0) := x"00";   -- Will receive data from desired output
      constant input1            : std_logic_vector(7 downto 0) := x"01";   -- Sample fake data
      constant input2            : std_logic_vector(7 downto 0) := x"03";   -- Sample fake data
      constant input3            : std_logic_vector(7 downto 0) := x"07";   -- Sample fake data
      constant signature         : std_logic_vector(7 downto 0) := x"A5";   -- Signature
     
      signal dataBusBuffer       : std_logic_vector(7 downto 0) := x"00";
      
    begin
      process(CLK, RST)
        variable resyncCLKIN   : std_logic_vector(2 downto 0) := b"111";
        variable resyncSTARTIN : std_logic_vector(2 downto 0) := b"000";
      begin
        if RST = '0' then
          dataBus <= "ZZZZZZZZ";
    		LEDs    <= "111";
    		outputEnable <= '0';
        elsif rising_edge(CLK) then
    	   resyncCLKIN        :=  resyncCLKIN(1 downto 0) & CLKIN;
    	   resyncSTARTIN      :=  resyncSTARTIN(1 downto 0) & STARTIN;
    		
    		if (((resyncSTARTIN(1) and not resyncSTARTIN(2)) = '1') OR (statePointer = 15)) then
    			statePointer <= 0;
    			konnectSelected <= '0';
    		end if;
    		
    		if ((resyncSTARTIN(2) and not resyncSTARTIN(1)) = '1') and (dataBus = "00001111") then
    			konnectSelected <= '1';
    		end if;
    		
    		if ((resyncCLKIN(1) XOR resyncCLKIN(2)) = '1')  and (statePointer < 16) and (konnectSelected = '1') then
    		  statePointer <= statePointer + 1;
    		  
    		  if(statePointerBuffer = 1) then
    		    input0 <= dataBus;
    		    LEDs <= not dataBus(2 downto 0);
    		  end if;
    		  
    		  if(statePointerBuffer = 3) then
    		    --output1 <= dataBus; -- Nothing to output to yet
    		  end if;
    
    
    		  case statePointerBuffer is
    		    when 4 =>  dataBusBuffer <= not input0;
    		    when 6 =>  dataBusBuffer <= not input1;
    		    when 8 =>  dataBusBuffer <= not input2;
    		    when 10 => dataBusBuffer <= not input3;
    		    when 12 => dataBusBuffer <= signature;
    		    when others => dataBusBuffer <= x"00";
    		  end case;
    		else
    		  statePointerBuffer <= statePointer;
    		end if;
    		
          if (CLKIN = '1') AND (statePointerBuffer > 3) AND (statePointerBuffer < 14) then
            dataBus <= dataBusBuffer;
            outputEnable <= '1';
          else
            dataBus <= "ZZZZZZZZ";
            outputEnable <= '0';
          end if;
     	 end if;
      end process;	
      
      konnectSelectedOut <= konnectSelected;
    end behaviour;
    In the future I will update this to act as multiple Konnects and add an interface to SPI.

    And its corresponding testBench:
    Code:
    library ieee ;
    use ieee.std_logic_1164.all;
    use work.all;
    
    
    entity interfacetestbench is
    end interfacetestbench;
    
    
    architecture behaviour of interfacetestbench is 
      procedure wait_until_rising_edges(signal clk : in std_logic; n : in integer) is
      begin
        for i in 1 to n loop
          wait until rising_edge(clk);
    		wait for 1 ns;
        end loop;
      end procedure;
    
    
      component KonnectToSpi
        port(	
          RST      :  in std_logic;
    	   CLK      :  in std_logic;
          CLKIN    :  in std_logic;
          STARTIN  :  in std_logic;
          dataBus  :  inout STD_LOGIC_VECTOR (7 DOWNTO 0);
    	   LEDs     :  out std_logic_vector (2 downto 0);
    		konnectSelectedOut :  out std_logic;
    		outputEnable :  out std_logic
        );
      end component;
      
      -- Inputs
      signal RST      :	std_logic := '0';
      signal CLK      :  std_logic := '0';
      signal CLKIN    :	std_logic := '1';
      signal STARTIN  :	std_logic := '0';
      
      -- Outputs
      signal dataBus :	STD_LOGIC_VECTOR (7 DOWNTO 0);
      signal LEDs    :   std_logic_vector (2 downto 0);
      signal konnectSelectedOut : std_logic;
      signal outputEnable   : std_logic;
      
    begin
      UUT: KonnectToSpi port map (
        RST     => RST,
        CLK     => CLK,
        CLKIN   => CLKIN,
    	 STARTIN => STARTIN,
        dataBus => dataBus,
        LEDs    => LEDs,
    	 konnectSelectedOut => konnectSelectedOut,
    	 outputEnable => outputEnable
      );
      
      resetPulse: process
      begin
        RST <= '1';
        wait for 10 ns;
        RST <= '0';
        wait for 10 ns;
        RST <= '1';
        wait;
      end process;
      
      xtal:  process 
      begin
        CLK <= '0';
        wait for 20 ns;
        CLK <= '1';
        wait for 20 ns;
      end process;
      
      WaveformInput: process
      begin
    	 dataBus <= "LLLLLLLL";
        wait_until_rising_edges(CLK,20);
        CLKIN <= '0';
        wait_until_rising_edges(CLK,5);
    	 dataBus <= "00000000";
        wait_until_rising_edges(CLK,10);
    	 STARTIN <= '1';
        wait_until_rising_edges(CLK,10);
    	 dataBus <= "0000" & "1111";      -- Set addres on the bus over here
        wait_until_rising_edges(CLK,10);
    	 STARTIN <= '0';                  -- Addres maching should be sampled on this falling edge
        wait_until_rising_edges(CLK,10);
        CLKIN <= '1';                    -- Command bits should be read by the interface on this rising edge
        wait_until_rising_edges(CLK,4);
    	 dataBus <= "00000000";           -- Reset the databits
        wait_until_rising_edges(CLK,4);
    	 dataBus <= "00010101";           -- Ouput(0) should be presented to the interface here
        wait_until_rising_edges(CLK,12);
        CLKIN <= '0';                    -- Output(0) should be sampled on this falling edge by the interface
    	 wait_until_rising_edges(CLK,10);
        CLKIN <= '1';
        wait_until_rising_edges(CLK,4);
    	 dataBus <= "11000011";           -- Ouput(1) should be presented to the interface here
        wait_until_rising_edges(CLK,16);
        CLKIN <= '0';                    -- Output(1) should be sampled on this falling edge by the interface
    	 wait_until_rising_edges(CLK,4);
    	 dataBus <= "LLLLLLLL";
    	 wait_until_rising_edges(CLK,8);
        CLKIN <= '1';
        wait_until_rising_edges(CLK,20); -- Input (0) interface should tell first inputs 
        CLKIN <= '0';
    	 wait_until_rising_edges(CLK,10);  -- Interface should go the high impedance
        CLKIN <= '1';
        wait_until_rising_edges(CLK,20); -- Input (1)
        CLKIN <= '0';
    	 wait_until_rising_edges(CLK,10);  -- Interface should go the high impedance
        CLKIN <= '1';
        wait_until_rising_edges(CLK,20); -- Input (2)
        CLKIN <= '0';
    	 wait_until_rising_edges(CLK,10);  -- Interface should go the high impedance
        CLKIN <= '1';
        wait_until_rising_edges(CLK,20); -- Input (3)
        CLKIN <= '0';
    	 wait_until_rising_edges(CLK,10);  -- Interface should go the high impedance
        CLKIN <= '1';
        wait_until_rising_edges(CLK,50); -- Interface should present signature 0xA5
    	 wait;
      end process;
    end;
    And once implemented on the FPGA the proof of concept worked!


    https://www.youtube.com/embed/bPkRl1-i5uc

    In the meantime the guys worked on cleaning, reverse engineering and experimenting with the machine:





    More updates to come!

    Similar Threads:
    Attached Thumbnails Attached Thumbnails Matsuura MC-500V Dynomotion Retrofit-img_20170826_021928-jpg   Matsuura MC-500V Dynomotion Retrofit-img_20170722_155644-jpg   Matsuura MC-500V Dynomotion Retrofit-img_20170221_230142-jpg   Matsuura MC-500V Dynomotion Retrofit-img_20170319_143635-jpg  

    Matsuura MC-500V Dynomotion Retrofit-img_20170826_021933-jpg   Matsuura MC-500V Dynomotion Retrofit-modelsim-jpg   Matsuura MC-500V Dynomotion Retrofit-modelsim01-jpg   Matsuura MC-500V Dynomotion Retrofit-img_20170909_003106-jpg  

    Last edited by DieBie; 09-09-2017 at 10:04 AM.


  2. #2
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4045
    Downloads
    0
    Uploads
    0

    Default Re: Matsuura MC-500V Dynomotion Retrofit

    Hi DieBie,

    You certainly win the award for being most clever

    Thanks for sharing. Especially the VHDL code.

    Did you consider having KFLOP more directly control the original system's Address/Data Bus?

    Let us know how things progress.

    Regards

    Regards
    TK http://dynomotion.com


  3. #3
    Member
    Join Date
    Jun 2004
    Location
    Scotland
    Posts
    355
    Downloads
    0
    Uploads
    0

    Default Re: Matsuura MC-500V Dynomotion Retrofit

    Good project.

    I'm glad it wasn't just me who couldn't get a STM to respond fast enough. IIRC even at 172MHz, the KFlop was onto it's second or third clock pulse by the time the STM had responded to the start pulse.



Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


About CNCzone.com

    We are the largest and most active discussion forum for manufacturing industry. The site is 100% free to join and use, so join today!

Follow us on


Our Brands

Matsuura MC-500V Dynomotion Retrofit

Matsuura MC-500V Dynomotion Retrofit