EmbDev.net

Forum: FPGA, VHDL & Verilog Servomotor. PWM and VHDL


Author: Soko Loko (Company: sokoban) (gilgamesh)
Posted on:

Rate this post
0 useful
not useful
Hi:

I'm trying to control a servomotor HS-645MG with the Altera FPGA DE0 
using VHDL. According to my limited knowledge (and according to other 
programmers) these are the code for frequency dividing and pwm:

Frequency divider:
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 4999 := 0;
begin
    freq_divider: process (reset, clk) begin
        if (reset = '1') then
            temporal <= '0';
            counter  <= 0;
        elsif rising_edge(clk) then
            if (counter = 4999) then
                temporal <= NOT(temporal);
                counter  <= 0;
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;
 
    clk_out <= temporal;
end Behavioral;

PWM

library IEEE;

use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;

-----------------------------------------------------

entity pwm is
  port(
    clr : in std_logic;
    clk : in std_logic;
    duty : in std_logic_vector (7 downto 0);
    period : in std_logic_vector (7 downto 0);
    pwm : out std_logic
  );

end pwm;

-----------------------------------------------------

architecture pwm of pwm is

signal count : std_logic_vector(7 downto 0);

begin

  cnt: process(clk, clr) -- 4 bit counter
  begin
    if clr = '1' then
      count <= "00000000";
    elsif clk'event and clk = '1' then
      if count = period -1 then
        count <= "00000000";
      else
        count <= count +1;
      end if;
    end if;
  end process cnt;

  pwmout: process(count, duty)
  begin
    if count < duty then
      pwm <= '1';
    else
      pwm <= '0';
    end if;
  end process pwmout;

end pwm;

Top-design code
-----------------------------------------------------

library IEEE;

use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;

-----------------------------------------------------

entity pwm_top is
  port(
    clr : in std_logic;
    clk : in std_logic;
    duty : in std_logic_vector (7 downto 0);
    pwm : out std_logic
  );

end pwm_top;

-----------------------------------------------------

architecture pwm_top of pwm_top is

signal new_clock : std_logic;

begin

clk_div: entity work.clk64kHz
    port map(
      clk => clk, reset => '0', clk_out => new_clock);

Pulse: entity work.pwm
    port map(
      clr => clr, clk => new_clock, duty => duty, period => "11001000", pwm => pwm);      
      
end pwm_top;

Described with my own words, the frequency is divided by a 5000 factor 
which yields to a new frequency of 10000Hz (0.1ms). Then the period of 
the pwm is assigned as 200 so the frequency of pwm will be 20ms and the 
duty cycle will be controlled with the DE0 built-in switches.

Unfortunately this doesnt work very well when the servo is connected, 
for example, if the duty cycle is 0.5ms the servo is supposed to moved 
to one end but instead, it seems to take a 45º position. For every other 
position, the servo also moves but it doesnt move accordingly to the 
duty cycle.

I have tested the servo with an arduino uno and works wonders.

What could be the problem?

Any ideas are welcomed.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:
Attached files:

Rate this post
0 useful
not useful
What does the simulation tell you? Do you get what you expect?

What output level do you have? What level does the servo need?

Soko Loko wrote:
> clk64kHz
This ist NOT the way Clocks are generated in FPGA. Use the ONE and ONLY 
50MHz clock in the entire design and use clock enable signals for all 
slower counters.
Have a look at the attached file. Its does almost the same like yours. I 
made it for playing a little with such a servo: the 4 buttons change the 
PWM...

Author: FPGA advisor (Guest)
Posted on:

Rate this post
0 useful
not useful
did you figure out already if you PWM physical suits your application? 
typically servo motor controls wor with PDM rather PWM in order to 
overcome certain issues caused by non linear torque behaviour.

Author: Ankit Patel (Guest)
Posted on:

Rate this post
0 useful
not useful
please share something useful for cyclon 3 to servo motor programming.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.