+ Post New Thread
Results 1 to 14 of 14
-
30th December 2017, 17:39 #1
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
How to receive PWM and edit it ?
In arduino so easy to receive PWM signal and edit it , and so many documentation, But in FPGA VHDL , I cannot find it .. Could someone help me to deal with it ?
PWM coming in std_logic, and how to make it std_logic_vector and edit this ?
-
30th December 2017, 18:54 #2
Awards:
- Join Date
- Apr 2014
- Posts
- 11,705
- Helped
- 2715 / 2715
- Points
- 57,471
- Level
- 58
Re: How to receive PWM and edit it ?
Hi,
You mean PWM = pulse width modulation?
If so, what to you mean with "receive"?
And "edit" it in which way?
With PWM one usually controls the speed of a DC motor, the brightness of a lamp....
A picture and a good description could help to clarify things.
KlausPlease don´t contact me via PM, because there is no time to respond to them. Thank you.
-
30th December 2017, 18:54
-
31st December 2017, 09:42 #3
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
Re: How to receive PWM and edit it ?
Yes it is Pulse Width Modulation, for example i have output from controller is from 1000 to 2000 impulses, ie PWM impulses, but my motor can get only from 1440 to 1850 impulses, so , to adopt it I just divide PWM from Controller to 2.7 and add 1063,,, ( pwm_in / 2.7) + 1063,,..
I have idea to convert std_logic (pwm impulses) to integer and count it , and edit it , like above and then somehow convert it to pwm output..How to convert it to std_logic again ?
-
31st December 2017, 10:06 #4
Awards:
- Join Date
- Jul 2009
- Location
- Aberdyfi, West Wales, UK
- Posts
- 11,509
- Helped
- 3807 / 3807
- Points
- 70,369
- Level
- 64
Re: How to receive PWM and edit it ?
Be very careful with wording here:
PWM implied the WIDTH of the pulses is modulated but not how frequent they are. You say the controller produces 1000 to 2000 impulses which implies it is FM (frequency modulated) not PWM.
If you divide PWM you lose the information in the modulation because division destroys the waveform shape. Please tell us exactly what your motor expects to be driven by, for example is the PWM fed directly to a DC or AC motor or does it pass through some other circuitry first.
Brian.PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.
1 members found this post helpful.
-
31st December 2017, 10:37 #5
- Join Date
- Jan 2008
- Location
- Bochum, Germany
- Posts
- 41,891
- Helped
- 12754 / 12754
- Points
- 241,334
- Level
- 100
Re: How to receive PWM and edit it ?
I would appreciate a clearer problem description, distinguishing between PWM frequency and pulse width. "PWM impulses" is inexpressive.
I guess you want to design a logic receiving an external PWM signal, extracting the pulse width and generating a PWM signal with manipulated pulse width and same(?) or different(?) frequency.
The general method is setting up a timer to measure the pulse width and possibly pulse period.
As the information represented by the pulse width is a numerical value, a straightforward VHDL approach suggests a numerical data type rather than std_logic_vector.
-
10th January 2018, 16:11 #6
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
Re: How to receive PWM and edit it ?
Dear All ,Thank you for suggestion, I spend two days to write it,because I am not good in vhdl and english,so this is working code:
Code:entity pwmedit is PORT( clk100 : IN std_logic; pwm_in : IN std_logic; mult : IN integer:=1; pwm_out: OUT std_logic); end pwmedit; architecture Behavioral of pwmedit is signal cnt: integer:=0; signal num_int: integer:=0; process(clk100,pwm_in) begin if rising_edge(clk100) then num_int <= num_int + 1; if pwm_in ='1' then num_int<=0; cnt<=cnt+1; else if num_int < (cnt+784) * mult then pwm_out <= '1'; else pwm_out <= '0'; cnt<=0; end if; end if; end if; end process;
Last edited by abimann; 10th January 2018 at 16:32.
-
10th January 2018, 16:11
-
10th January 2018, 16:39 #7
- Join Date
- Jan 2008
- Location
- Bochum, Germany
- Posts
- 41,891
- Helped
- 12754 / 12754
- Points
- 241,334
- Level
- 100
Re: How to receive PWM and edit it ?
The oscilloscope waveform suggests that the circuit generates delayed pwm pulses of same frequency. Is that what you want? If not, please give a clear specification.
-
10th January 2018, 16:55 #8
- Join Date
- Dec 2017
- Location
- Bydgoszcz - Poland
- Posts
- 22
- Helped
- 3 / 3
- Points
- 192
- Level
- 2
Re: How to receive PWM and edit it ?
Hello,
in purpose to generate PWM signal (with various PWM frequency) you can use such generic VHDL module:
Code:LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY pwm IS GENERIC( sys_clk : INTEGER := 1_000_000; --system clock frequency in Hz pwm_freq : INTEGER := 60_000; --PWM switching frequency in Hz bits_resolution : INTEGER := 8; --bits of resolution setting the duty cycle phases : INTEGER := 1); --number of output pwms and phases PORT( clk : IN STD_LOGIC; --system clock reset_n : IN STD_LOGIC; --asynchronous reset ena : IN STD_LOGIC; --latches in new duty cycle duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); --duty cycle pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --pwm outputs pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0)); --pwm inverse outputs END pwm; ARCHITECTURE logic OF pwm IS CONSTANT period : INTEGER := sys_clk/pwm_freq; --number of clocks in one pwm period TYPE counters IS ARRAY (0 TO phases-1) OF INTEGER RANGE 0 TO period - 1; --data type for array of period counters SIGNAL count : counters := (OTHERS => 0); --array of period counters SIGNAL half_duty_new : INTEGER RANGE 0 TO period/2 := 0; --number of clocks in 1/2 duty cycle TYPE half_duties IS ARRAY (0 TO phases-1) OF INTEGER RANGE 0 TO period/2; --data type for array of half duty values SIGNAL half_duty : half_duties := (OTHERS => 0); --array of half duty values (for each phase) BEGIN PROCESS(clk, reset_n) BEGIN IF(reset_n = '0') THEN --asynchronous reset count <= (OTHERS => 0); --clear counter pwm_out <= (OTHERS => '0'); --clear pwm outputs pwm_n_out <= (OTHERS => '0'); --clear pwm inverse outputs ELSIF(clk'EVENT AND clk = '1') THEN --rising system clock edge IF(ena = '1') THEN --latch in new duty cycle half_duty_new <= conv_integer(duty)*period/(2**bits_resolution)/2; --determine clocks in 1/2 duty cycle END IF; FOR i IN 0 to phases-1 LOOP --create a counter for each phase IF(count(0) = period - 1 - i*period/phases) THEN --end of period reached count(i) <= 0; --reset counter half_duty(i) <= half_duty_new; --set most recent duty cycle value ELSE --end of period not reached count(i) <= count(i) + 1; --increment counter END IF; END LOOP; FOR i IN 0 to phases-1 LOOP --control outputs for each phase IF(count(i) = half_duty(i)) THEN --phase's falling edge reached pwm_out(i) <= '0'; --deassert the pwm output pwm_n_out(i) <= '1'; --assert the pwm inverse output ELSIF(count(i) = period - half_duty(i)) THEN --phase's rising edge reached pwm_out(i) <= '1'; --assert the pwm output pwm_n_out(i) <= '0'; --deassert the pwm inverse output END IF; END LOOP; END IF; END PROCESS; END logic;
https://www.edaboard.com/showthread.php?t=373807
The entity: WEKTORY_WYPELNIEN and WEKTORY_REVERSE are used for generating varying PWM signals (soft-starter and soft-stop for 12 V DC Motor) . This proces is fully parametrized: PWM generation (clock frequency, PWM frequency, PWM timing, number of generated PWM phases) The in PWM vectors are read from ROM simulated in VHDL array.
If you want I can send you more code of this project -with some explanation (sorry for Polish comments in VHDL code).
RegardsLast edited by FlyingDutch; 10th January 2018 at 17:01.
-
11th January 2018, 06:44 #9
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
Re: How to receive PWM and edit it ?
pls send me to XXXXXXXXXX, is there tachometer also used to correct some speed or hertz or rpm ??
Last edited by KlausST; 11th January 2018 at 06:57. Reason: Removing eMail address
-
11th January 2018, 09:35 #10
- Join Date
- Dec 2017
- Location
- Bydgoszcz - Poland
- Posts
- 22
- Helped
- 3 / 3
- Points
- 192
- Level
- 2
Re: How to receive PWM and edit it ?
Hello,
no I don't use tachometer (or any sensor for measuring speed of DC Motor) I just needen't it. I am afraid that you choose bad atitiude for your problem.
Could you describe how parameters has input PWM signal ?
1) PWM frequency
2) How many bits resolution (for example : 8 bit PWM - the period is divided to 255 intervals)
3) I assumed that you have only one phase PWM signal
And after that what device you wanna to steer (output PWM signal). How the input PWM signal have to be processed to generate output PWM signal ?
What is final purpose of output PWM (what device it would be steering by tha signal)?
Your post is in many aspects unclear. Could you clarify it a bit ? I can send you all code of my project, but I am not sure if it will be useful for your needs?
BTW: I guess that you want to stabilize the speed (rpms) of DC motor using PWM signal ? In such case you have to use motors encoders (for measuring speed). Output of this encoder should be input signal to "PID Regulator" and output form PID regulator (error signal) should alter the process of generating PWM signal. This is much more complicated design, but can be achived by using that generic PWM generator (wchich code I attached). Of course you have to write much additional code by yourself. There are PID regulator free IP cores available on the net.
RegardsLast edited by FlyingDutch; 11th January 2018 at 09:50.
-
11th January 2018, 09:35
-
11th January 2018, 15:20 #11
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
Re: How to receive PWM and edit it ?
There are no any fixed data needed, just it need to modify incoming pwm signal from flight controller and send it out to motor and regulate motor speed by getting hertz or revolution per 20ms .. So problem is solved , by myself and i want if someone need this he can use above code,because googling dont give me result..and no one write this kind of code.
-
12th January 2018, 12:08 #12
- Join Date
- Dec 2017
- Location
- Bydgoszcz - Poland
- Posts
- 22
- Helped
- 3 / 3
- Points
- 192
- Level
- 2
Re: How to receive PWM and edit it ?
Hello abinam,
maybe I am not clever ehough to understand what problem you have.
So problem is solved , by myself and i want if someone need this he can use above code,because googling dont give me result..and no one write this kind of code.
First issue:
Code:entity pwmedit is PORT( clk100 : IN std_logic; pwm_in : IN std_logic; mult : IN integer:=1; pwm_out: OUT std_logic); end pwmedit;
Are you aware what are you doing?
The integer is treated as 32-bit vector what causing that multiplaying by 1 is taking huge amount of LUTs (* operator is very non effective as general).
See link:
https://forums.xilinx.com/t5/Welcome...ts/td-p/284364
You should use GENERIC construct in entity of pwmedit:
Code:entity pwmedit is generic ( mult : integer := 1); -- multiplayer PORT( clk100 : IN std_logic; pwm_in : IN std_logic; pwm_out: OUT std_logic); end pwmedit;
Code:library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity pwmedit is generic ( mult : integer := 1); -- multiplayer PORT( clk100 : IN std_logic; pwm_in : IN std_logic; pwm_out: OUT std_logic); end pwmedit; architecture Behavioral of pwmedit is signal cnt: integer :=0; signal num_int: integer :=0; begin process(clk100,pwm_in) begin if rising_edge(clk100) then num_int <= num_int + 1; if (pwm_in = '1') then num_int<=0; cnt<=cnt+1; else if (num_int < ((cnt+784) * mult)) then pwm_out <= '1'; else pwm_out <= '0'; cnt<=0; end if; end if; end if; end process; end Behavioral;
Code:LIBRARY ieee; USE ieee.std_logic_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --USE ieee.numeric_std.ALL; ENTITY pwmedit_TB IS END pwmedit_TB; ARCHITECTURE behavior OF pwmedit_TB IS -- Component Declaration for the Unit Under Test (UUT) COMPONENT pwmedit generic ( mult : integer := 1); -- multiplayer PORT( clk100 : IN std_logic; pwm_in : IN std_logic; pwm_out : OUT std_logic ); END COMPONENT; --Inputs signal clk100 : std_logic := '0'; signal pwm_in : std_logic := '0'; --Outputs signal pwm_out : std_logic; -- Clock period definitions constant clk100_period : time := 100 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: pwmedit PORT MAP ( clk100 => clk100, pwm_in => pwm_in, pwm_out => pwm_out ); -- Clock process definitions clk100_process :process begin clk100 <= '0'; wait for clk100_period/2; clk100 <= '1'; wait for clk100_period/2; end process; -- Stimulus process stim_proc: process begin -- hold reset state for 100 ns. wait for 100 ns; wait for clk100_period*10; -- insert stimulus here pwm_in <= '1'; wait for clk100_period*100; pwm_in <= '0'; wait for clk100_period*100; pwm_in <= '1'; wait for clk100_period*100; pwm_in <= '0'; wait for clk100_period*100; pwm_in <= '1'; wait for clk100_period*400; pwm_in <= '0'; wait for clk100_period*400; pwm_in <= '1'; wait for clk100_period*1000; pwm_in <= '0'; wait for clk100_period*1000; pwm_in <= '1'; wait for clk100_period*4000; pwm_in <= '0'; wait for clk100_period*4000; pwm_in <= '1'; wait for clk100_period*4000; pwm_in <= '0'; wait for clk100_period*4000; wait; end process; END;
- - - Updated - - -
This is last part of my last answer:
Result of simulation:
Maybe when coincedence of some clock frequency and incoming PWM signal frequency took place your code is doing something, you need.
Why do you think that someone wanna to use your buggy code - what purpose is unclear ?
RegardsLast edited by FlyingDutch; 12th January 2018 at 11:42.
-
12th January 2018, 16:46 #13
- Join Date
- Dec 2017
- Location
- Bydgoszcz - Poland
- Posts
- 22
- Helped
- 3 / 3
- Points
- 192
- Level
- 2
Re: How to receive PWM and edit it ?
BTW: If you using integer as input ports, you should at least apply range to it:
Code:entity pwmedit is PORT( clk100 : IN std_logic; pwm_in : IN std_logic; mult : IN integer:=1; pwm_out: OUT std_logic); end pwmedit;
Regards
1 members found this post helpful.
-
16th January 2018, 08:08 #14
- Join Date
- Jun 2016
- Posts
- 29
- Helped
- 0 / 0
- Points
- 493
- Level
- 4
Re: How to receive PWM and edit it ?
This code working , I don't know how to make simulation, i am sure smth wrong with your simulation code..but i check it in real hardware and oscilloscope..I cannot find any other vhdl code which is reads PWM in , so...
+ Post New Thread
Please login