+ Post New Thread
Results 1 to 7 of 7
  1. #1
    Member level 1
    Points: 1,169, Level: 7

    Join Date
    Apr 2013
    Location
    Bangalore
    Posts
    33
    Helped
    0 / 0
    Points
    1,169
    Level
    7

    Spartan-6 Servo Control

    Hi ,

    Very recently I tried to learn VHDL using some online courses. With my limited knowledge and using the help of some experts online I wrote below code.

    I am using ALINIX SPARTAN 6 XILINX board and Servo KS-3527

    (https://www.aliexpress.com/item/KS35...877907004.html)

    My system clock is 50MHz.

    Below program is to generate 64kHz from 50mHz frequency.

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    -----------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
     
    entity clk64kHz is
        Port (
            clk    : in  STD_LOGIC;
            reset  : in  STD_LOGIC;
            clk_out: out STD_LOGIC
        );
    end clk64kHz;
     
    architecture Behavioral of clk64kHz is
        signal temporal: STD_LOGIC;
        signal counter : integer range 0 to 780 := 0;
    begin
        freq_divider: process (reset, clk) begin
            if (reset = '1') then
                temporal <= '0';
                counter  <= 0;
            elsif rising_edge(clk) then
                if (counter = 780) then
                    temporal <= NOT(temporal);
                    counter  <= 0;
                else
                    counter <= counter + 1;
                end if;
            end if;
        end process;
        clk_out <= temporal;
    end Behavioral;

    Below program is generate PWM pulse.In order to have a frequency of 20ms->20 * 64=1280--> which is done by implementing counter from 0 to 1279


    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
     
    entity servo_pwm is
        PORT (
            clk   : IN  STD_LOGIC;
            reset : IN  STD_LOGIC;
           -- pos   : IN  STD_LOGIC_VECTOR(6 downto 0);
            servo : OUT STD_LOGIC
        );
    end servo_pwm;
     
    architecture Behavioral of servo_pwm is
     
    constant pos : std_logic_vector(6 downto 0):= "1111111";     ---Servo Position(pos) I kept constant just to check the program.
     
        -- Counter, from 0 to 1279.
        signal cnt : unsigned(10 downto 0);
        -- Temporal signal used to generate the PWM pulse.
        signal pwmi: unsigned(7 downto 0);
         
    begin
        -- Minimum value should be 0.5ms.
        pwmi <= unsigned('0' & pos) + 32;
        -- Counter process, from 0 to 1279.
        counter: process (reset, clk) begin
            if (reset = '1') then
                cnt <= (others => '0');
            elsif rising_edge(clk) then
                if (cnt = 1279) then
                    cnt <= (others => '0');
                else
                    cnt <= cnt + 1;
                end if;
            end if;
        end process;
        -- Output signal for the servomotor.
        servo <= '1' when (cnt < pwmi) else '0';
    end Behavioral;

    Mapping both the above codes

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
     
    entity servo_pwm_clk64kHz is
        PORT(
            clk  : IN  STD_LOGIC;
            reset: IN  STD_LOGIC;
            --pos  : IN  STD_LOGIC_VECTOR(6 downto 0);
            servo: OUT STD_LOGIC
              
        );
    end servo_pwm_clk64kHz;
     
    architecture Behavioral of servo_pwm_clk64kHz is
        COMPONENT clk64kHz
            PORT(
                clk    : in  STD_LOGIC;
                reset  : in  STD_LOGIC;
                clk_out: out STD_LOGIC
            );
        END COMPONENT;
        
        COMPONENT servo_pwm
            PORT (
                clk   : IN  STD_LOGIC;
                reset : IN  STD_LOGIC;
                --pos   : IN  STD_LOGIC_VECTOR(6 downto 0);
                servo : OUT STD_LOGIC
            );
        END COMPONENT;
             
        signal clk_out : STD_LOGIC := '0';
    begin
        clk64kHz_map: clk64kHz PORT MAP(
            clk, reset, clk_out
        );
        
        servo_pwm_map: servo_pwm PORT MAP(
            clk_out, reset, servo
        );
             
    end Behavioral;

    Test bench:

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
     
     
    ENTITY servo_pwm_clk64kHz_tb IS
    END servo_pwm_clk64kHz_tb;
     
    ARCHITECTURE behavior OF servo_pwm_clk64kHz_tb IS 
     
        -- Component Declaration for the Unit Under Test (UUT)
     
        COMPONENT servo_pwm_clk64kHz
        PORT(
             clk : IN  std_logic;
             reset : IN  std_logic;
             servo : OUT  std_logic
            );
        END COMPONENT;
        
     
       --Inputs
       signal clk : std_logic := '0';
       signal reset : std_logic := '0';
     
        --Outputs
       signal servo : std_logic;
     
       -- Clock period definitions
       constant clk_period : time := 10 ns;
     
    BEGIN
     
        -- Instantiate the Unit Under Test (UUT)
       uut: servo_pwm_clk64kHz PORT MAP (
              clk => clk,
              reset => reset,
              servo => servo
            );
     
       -- Clock process definitions
       clk_process :process
       begin
            clk <= '0';
            wait for clk_period/2;
            clk <= '1';
            wait for clk_period/2;
       end process;
     
     
       -- Stimulus process
       stim_proc: process
       begin        
          -- hold reset state for 100 ns.
          wait for 100 ns;  
     
          wait for clk_period*10;
     
          -- insert stimulus here 
            
        reset <= '1';
            wait for 50 ns;
            reset <= '0';
     
          wait;
       end process;
     
    END;
    ---------------------
    I could able to simulate the above code and got the servo pulse as expected. But the actual servo is not working when connected to FPGA.
    Servo is connected to separate 5Volt supply and control signal is connected to FPGA output pin.

    Please help to rectify this issue.

    Thanks.Attachment 150251Attachment 150250Attachment 150251Attachment 150250


    .
    Last edited by ads-ee; 28th November 2018 at 17:09. Reason: improved syntax tag placement for readability

    •   AltAdvertisment

        
       

  2. #2
    Member level 4
    Points: 1,611, Level: 9

    Join Date
    May 2012
    Location
    Maryland, USA
    Posts
    74
    Helped
    26 / 26
    Points
    1,611
    Level
    9

    Re: Spartan-6 Servo Control

    Have you tried checking the signals to the servo with a scope to see if they are there? Are you using the correct pins on the header?

    Also, search for info on using clock enables with one clock (or few clocks) instead of dividing clocks and trying to use those (your "temporal" signal). The structure of the FPGA wants to use dedicated clock routes for the registers and the way you are doing it will lead to timing issues at higher speeds.


    1 members found this post helpful.

  3. #3
    Member level 1
    Points: 1,169, Level: 7

    Join Date
    Apr 2013
    Location
    Bangalore
    Posts
    33
    Helped
    0 / 0
    Points
    1,169
    Level
    7

    Re: Spartan-6 Servo Control

    Click image for larger version. 

Name:	J4 Clk pin.JPG 
Views:	1 
Size:	87.6 KB 
ID:	150261Click image for larger version. 

Name:	T8 Clk pin.JPG 
Views:	3 
Size:	70.3 KB 
ID:	150262hi bking,

    thank you for your reply,
    No I haven't tried with Scope,I don't have one . Yes I am using correct I/O pins in the FPGA. . About clock enables can you explain me bit in detail.

    Also I have noticed 2 things,
    1) When I compile the program in ISE design Suite 14.7 , for clock it assigns automatically pin J4, However as per the datasheet FPGA's global clock Pin is T8. should I assign the clock to T8 or J4?.anyway I tried both pins it dint work. What is the difference between these two clocks?

    https://www.scribd.com/document/3579...d-Users-Manual

    2) when my servo is connected to 5V supply with control signal open, the servo moves in random direction when I move my hand or mobile phone closer to it. If I am not wrong servo should not function if there is No control signal correct?. Is it my servo itself is faulty?
    Last edited by prakash_kadri; 29th November 2018 at 02:48.



    •   AltAdvertisment

        
       

  4. #4
    Super Moderator
    Points: 49,865, Level: 54

    Join Date
    Apr 2011
    Location
    Minneapolis, Minnesota, USA
    Posts
    12,306
    Helped
    2431 / 2431
    Points
    49,865
    Level
    54

    Re: Spartan-6 Servo Control

    Quote Originally Posted by prakash_kadri View Post
    when my servo is connected to 5V supply with control signal open, the servo moves in random direction when I move my hand or mobile phone closer to it.
    A servo shows 'jittery' behavior when exposed to inconsistent control signals. (R/C operators often see it when a second operator is transmitting on the same radio channel nearby.)

    Do you leave the control wire unconnected? Then it is at high impedance. It can be like an antenna, responding to unknown waveforms reaching it.
    (Normally you control a servo by sending pulses between 1 and 2 mSec long.) If you ground the control wire then I believe the jittery behavior should stop.


    1 members found this post helpful.

  5. #5
    Member level 1
    Points: 1,169, Level: 7

    Join Date
    Apr 2013
    Location
    Bangalore
    Posts
    33
    Helped
    0 / 0
    Points
    1,169
    Level
    7

    Re: Spartan-6 Servo Control

    Quote Originally Posted by BradtheRad View Post
    A servo shows 'jittery' behavior when exposed to inconsistent control signals. (R/C operators often see it when a second operator is transmitting on the same radio channel nearby.)

    Do you leave the control wire unconnected? Then it is at high impedance. It can be like an antenna, responding to unknown waveforms reaching it.
    (Normally you control a servo by sending pulses between 1 and 2 mSec long.) If you ground the control wire then I believe the jittery behavior should stop.

    yes the control wire is unconnected.



  6. #6
    Super Moderator
    Points: 29,649, Level: 41
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,839
    Helped
    1628 / 1628
    Points
    29,649
    Level
    41

    Re: Spartan-6 Servo Control

    Quote Originally Posted by prakash_kadri View Post
    Click image for larger version. 

Name:	J4 Clk pin.JPG 
Views:	1 
Size:	87.6 KB 
ID:	150261Click image for larger version. 

Name:	T8 Clk pin.JPG 
Views:	3 
Size:	70.3 KB 
ID:	150262hi bking,

    thank you for your reply,
    No I haven't tried with Scope,I don't have one . Yes I am using correct I/O pins in the FPGA. . About clock enables can you explain me bit in detail.

    Also I have noticed 2 things,
    1) When I compile the program in ISE design Suite 14.7 , for clock it assigns automatically pin J4, However as per the datasheet FPGA's global clock Pin is T8. should I assign the clock to T8 or J4?.anyway I tried both pins it dint work. What is the difference between these two clocks?

    https://www.scribd.com/document/3579...d-Users-Manual

    2) when my servo is connected to 5V supply with control signal open, the servo moves in random direction when I move my hand or mobile phone closer to it. If I am not wrong servo should not function if there is No control signal correct?. Is it my servo itself is faulty?
    Are you saying you didn't write or use an existing ucf file to assign the pins of your design?

    If the documentation of the board says the clock comes in on pin T8 then your clock input should be assigned T8 as the pin the clock comes in on in the UCF file. If you didn't do all the assignments or use an existing UCF file provided by the vendor (and having a top-level file that has the same signal names) then don't expect ISE to place the pins where they need to be to work on your board.


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  7. #7
    Member level 1
    Points: 1,169, Level: 7

    Join Date
    Apr 2013
    Location
    Bangalore
    Posts
    33
    Helped
    0 / 0
    Points
    1,169
    Level
    7

    Re: Spartan-6 Servo Control

    Quote Originally Posted by ads-ee View Post
    Are you saying you didn't write or use an existing ucf file to assign the pins of your design?


    If the documentation of the board says the clock comes in on pin T8 then your clock input should be assigned T8 as the pin the clock comes in on in the UCF file. If you didn't do all the assignments or use an existing UCF file provided by the vendor (and having a top-level file that has the same signal names) then don't expect ISE to place the pins where they need to be to work on your board.
    I wrote .ucf file myself and assigned the pins for each inputs/outputs.

    Only Clock input pin I had some doubt. Thank you for clarifying that it should be T8. However, in .ucf file I tried with T8 as clock input and assigned pins for other inputs and outputs, but still the servo dint work. I am unable to find out where I am doing mistake. Let me know if you need more details.
    Unfortunately I don't have Scope to measure the PWM at output pin. The board output(PWM) is at 3.3 volts, do I need to use level shifter to bring it to 5 volt before connecting it to servo?



--[[ ]]--