Forum Discussion

efurk's avatar
efurk
Icon for New Contributor rankNew Contributor
7 years ago

How to decrease the speed of a servo motor?

the servo has 1-2 ms duty cycle, and 20 ms refreshing frequency, bidirectional, non-continuous, 180 degree. It's Sg90. Using 100 Mhz Board clock and already divided it.

And this's a part of pwm code. For any help, I appreciate in advance

    process(CLK, DIR, EN)
 
constant time_high_stopped : INTEGER := (2000);--a square wave with a width of 2 milliseconds
        
        constant time_high_ccw : INTEGER := ( 3500); --counterclockwise
   --Anything wave above 2 ms will cause the servo to start to move counterclockwise. 
    --Anything below 2 will cause the servo to move clockwise. 
    constant time_high_cw : INTEGER := (500); --clockwise
    constant time_low : INTEGER := (20000);
       
   variable th_cntr : INTEGER range 0 to 3547 := 0; -- timehigh counter
   variable tl_cntr : INTEGER range 0 to 34719 := 0; --timelow counter
        
        begin
     if EN = '1' then 
    if rising_edge(CLK) then
      ---stopping the servo
   if DIR = "00" then  
      if tl_cntr <= time_low then
            tl_cntr := tl_cntr + 1;
       SERVO <= '0';
       elsif th_cntr <= time_high_stopped then
        th_cntr := th_cntr + 1;
       SERVO <= '1';      
          else
         tl_cntr := 0;
      th_cntr := 0;
    SERVO <= '0';
                                         
  end if;                             
---servo clock wise
elsif DIR = "01" then  
     if tl_cntr <= time_low then
        tl_cntr := tl_cntr + 1; 
      SERVO <= '0';
   
         elsif th_cntr <= time_high_ccw then
           th_cntr := th_cntr + 1;
         SERVO <= '1'; 
         else
         tl_cntr := 0;
         th_cntr := 0;
         SERVO <= '0';
        end if;
     ---servo counter clockwise
       elsif DIR = "10" then  
      if tl_cntr <= time_low then
      tl_cntr := tl_cntr + 1;
      SERVO <= '0';
                        
     elsif th_cntr <= time_high_cw then
        th_cntr := th_cntr + 1; 
       SERVO <= '1'; 
       else
      tl_cntr := 0;
      th_cntr := 0;
      SERVO <= '0';
       end if;                       
       end if;
     end if;
     end if; 
                
    end process;
    

3 Replies

  • SreekumarR_G_Intel's avatar
    SreekumarR_G_Intel
    Icon for Frequent Contributor rankFrequent Contributor

    Hello there ,

    I get chance to go through your RTL ,Looks only constant value for duty cycle is implemented.

    Here is the RTL attached for variable angle (i.e duty cycle) and its simulation result

    I dont know your application and how you wanted to change the different angle , but for example below I just created a port and given an input through test bench.

    Simulation result also shown increasing / decreasing angles.

    Thank you ,

    Regards,

    Sree

  • SreekumarR_G_Intel's avatar
    SreekumarR_G_Intel
    Icon for Frequent Contributor rankFrequent Contributor

    Hello there ,

    If you dont have any further question , can you please close the issue ?

    Thank you,

    Regards,

    Sree