Nguyên văn bởi nemesis21
Xem bài viết
Thông báo
Collapse
No announcement yet.
Project nhỏ: Bộ lọc số FIR thực hiện bằng FPGA
Collapse
This is a sticky topic.
X
X
-
Tôi nghĩ nếu bạn cá chép đang gặp vấn đề với mạch delay, những giai đoạn tất yếu trước đó đã được hoàn thành? Dù với project nhỏ, chúng ta vẫn nên làm theo trình tự để giảm thiểu vấn đề.
- Requirements / specs cho filter như thế nào? Có vài chỉ số được đưa ra, nhưng hình như thiếu sự liên kết giữa các chỉ số quan trọng. Dù với scalable design, chúng ta vẫn phải đặt ra performance bounds. Rất không nên nhảy vào coding trước khi establishing requirements / specs.
- Design cho filter như thế nào? Dựa vào requirements / specs, bạn đã chọn filter structure nào? Parallel, serial (single multiplier), hoặc semi-parallel? Nếu serial, mạch delay của bạn nên sử dụng RAM (hoặc registers và multiplexer để emulate RAM). Nếu parallel, mạch delay của bạn nên sử dụng registers. Bạn đã chọn structure / mạch delay nào? Bạn đã vẽ block diagram cho design của bạn? Generic design hay là target spefiic? Chẳng hạn như với DSP48 của Virtex-4, parallel design có thể hoàn toàn sử dụng intenal registers và routing của DSP48. Bạn đã diagram / model mạch delay của bạn?
- Giai đoạn viết VHDL nên là giai đoạn dễ dàng nhất.
Khuyến khích làm các project là một việc hay, nhưng tôi nghĩ rằng học về process và các trình tự tất yếu còn quan trọng hơn simulation output đối với những người mới.
Comment
-
Phần filter analysis / design không quá khó. Chỉ với vài dòng lệnh, bạn có thể generate filter coefficients và analyze frequency response như trong screen captures 01/02, so sánh 21/51/101 taps Hamming filters và 101 taps Boxcar filter.
Trong screen captures 03 / 04, zero-padded sine wave được filter qua 21-tap Hamming filter. Zero-padded data được dùng để chúng ta có thể dễ dàng thấy được effect của filter.
Phần FIR filter đơn giản chỉ có 3-4 dòng:
Code:for in range (len(x)) : delay_buf[1:len(filter_coeffs)] = delay_buf[0:len(filter_coeffs)-1] delay_buf[0] = x[i] y[i] = sum(delay_buf * filter_coeffs)
Code:delay_buf[1:len(filter_coeffs)] = delay_buf[0:len(filter_coeffs)-1] delay_buf[0] = x[i]
Code:for j in range(len(filter_coeffs)-1,0,-1) : delay_buf[j] = delay_buf[j-1] delay_buf[0] = x[i]
Code:DATA_SHIFT : for j in 20 downto 1 generate delay_buf(j) = delay_buf(j-1) when rising_edge(clk); end generate;
Tương tự như vậy, bạn cũng chuyển dần dòng lệnh dưới sang một dạng suitable cho HDL implementation hơn.
Code:y[i] = sum(delay_buf * filter_coeffs)
Ở đây tôi đã dùng floating-point, nhưng đại khái là, bạn nên tạo ra một functional model trước, và sau đó chuyển thể từ từ sang dạng HDL suitable hơn. Như đã từng đề cập, phần viết VHDL nên là phần dễ dàng nhất. Chúc bạn thành công.
Comment
-
Nguyên văn bởi tonyvandinh Xem bài viếtNemesis21 có thể giúp dùng Matlab để tạo ra bộ coefficient, số tap, input và output vectors được kô? Thx
Code:N = 20; cf = fir1(N, .2, hamming(N+1))
Code:freqz(cf, 1)
Code:input = sin((1:100)/10))
Comment
-
Sẵn rãnh một chút, tôi sẽ bàn tiếp về FIR filter implementation cho các bạn mới bắt đầu.
Về cấu trúc, khi nào áp dụng serial, parallel, hoặc semi-parallel?
Dựa vào các thông số number of taps N, processing clock rate C, và output sample rate S.
Serial, bạn sử dụng 1 multiplier (M = 1). Bạn cần N clock cycles để calculate 1 output. Nếu processing clock rate = 200 MHz, và number of taps = 20, bạn có thể dùng 1 multiplier để calculate 10 Msps (Megasample per second) trở xuống, N * S <= C * M
Nhưng nếu required output sample rate = 200 Msps, M = 1 không đủ. Trong trường hợp này, bạn cần fully parallel structure, M = N.
Nếu output sample rate = 50 Msps chẳng hạn, chúng ta vẫn có thể dùng M = N. Nhưng thông thường, design goal là phải sử dụng ít resources nhất, cho nên chúng ta sử dụng semi-parallel structure, với M = N / 4.
Nếu output sample rate > 200 Msps, chúng ta vẫn có thể xử lý, nhưng hơi advance cho mạch này.
=======
Sau khi chúng ta đã chọn filter structure hợp lý, cần phải model như thế nào?
Code:y[i] = sum(delay_buf * filter_coeffs)
Break down một chút:
Code:temp = 0; for k in range(len(filter_coeffs)) : temp = temp + delay_buf[k] * filter_coeffs[k]; y[i] = temp;
Code:prod = zeros(len(filter_coeffs)); for k in range(len(filter_coeffs)) : prod[k] = delay_buf[k] * filter_coeffs[k];
.......
Comment
-
......
Hãy chọn adder tree nhé? Tổng thể model như thế này:
Code:delay_buf = zeros(len(filter_coeffs)); y = zeros(len(x)); prod = zeros(len(filter_coeffs)) for i in range (len(x)) : delay_buf[1:len(filter_coeffs)] = delay_buf[0:len(filter_coeffs)-1];delay_buf[0] = x[i] for k in range (len(filter_coeffs)) : prod[k] = delay_buf[k] * filter_coeffs[k]; y[i] = adder_tree(prod)
Sau đây hãy bắt đầu so chiếu với VHDL code đơn giản dùng pre-loaded coefficients.
Code:library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity pfir is generic ( NUM_TAPS : positive range 5 to 200 := 21 ); port ( clk : in STD_LOGIC; data_in : in STD_LOGIC_VECTOR; data_out : out STD_LOGIC_VECTOR ); end pfir;
Code:type data_mem_type is array (natural range <>) of std_logic_vector(data_in'range); signal delay_buf : data_mem_type(NUM_TAPS-1 downto 0) := (others => (others => '0'));
Code:delay_buf <= delay_buf(NUM_TAPS-2 downto 0) & data_in when rising_edge(clk);
Code:constant filter_coeffs : data_mem_type(NUM_TAPS-1 downto 0) := ( std_logic_vector(to_signed(integer(-6.21115459e-19 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-2.12227115e-03 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-6.32535399e-03 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-1.16118104e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-1.23546567e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(4.19252935e-18 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(3.17744976e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(8.14359076e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(1.37493782e-01 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(1.82125490e-01 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(1.99168830e-01 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(1.82125490e-01 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(1.37493782e-01 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(8.14359076e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(3.17744976e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(4.19252935e-18 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-1.23546567e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-1.16118104e-02 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-6.32535399e-03 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-2.12227115e-03 * 2.0**(data_in'length-1)-1.0),data_in'length)), std_logic_vector(to_signed(integer(-6.21115459e-19 * 2.0**(data_in'length-1)-1.0),data_in'length)) );
Phần multiplication cũng không quá khác so với model, cũng dùng for loop.
Code:type prod_mem_type is array (natural range <>) of signed(data_in'length*2-1 downto 0); signal prod : prod_mem_type(NUM_TAPS-1 downto 0) := (others => (others => '0'));
Code:MULT_GEN : for i in 0 to NUM_TAPS-1 generate prod(i) <= signed(delay_buf(i)) * signed(filter_coeffs(i)) when rising_edge(clk); end generate MULT_GEN;
Comment
-
.......
Adder tree rất cơ bản, chẳng hạn như chúng ta có 4 inputs a, b, c, d, nhưng adder chỉ có thể cộng lại tối đa mỗi lần 2 inputs, chúng ta trước tiên phải cộng (a+b) và (c+d), và sau đó cộng (a+b)+(c+d). Không khó để các bạn model adder tree, nhưng tôi đưa lên một version ở đây để tham khảo đối chiếu với VHDL implementation.
Code:def adder_tree (data_in) : num_inputs = len(data_in); num_levels = int(ceil(log2(num_inputs))); sum_out = zeros((num_levels, num_inputs)); for l in range(num_levels) : num_adders = int(ceil(num_inputs/(2.0**(l+1)))); num_adder_prev_stage=int(ceil(num_inputs/(2.0**(l)))); if (l == 0) : for m in range (num_adders) : if (m == (num_adders - 1)) and (num_adder_prev_stage % 2 == 1) : sum_out[l][m] = data_in[m*2]; else : sum_out[l][m] = data_in[m*2] + data_in[m*2+1]; else : for m in range (num_adders) : if (m == (num_adders - 1)) and (num_adder_prev_stage % 2 == 1) : sum_out[l][m] = sum_out[l-1][m*2]; else : sum_out[l][m] = sum_out[l-1][m*2] + sum_out[l-1][m*2+1]; return sum_out[num_levels-1][0]
So sánh với phần VHDL dưới đây:
Code:type sum_mem_type is array (natural range <>, natural range <>) of signed(data_in'length*2-1 downto 0); constant num_levels : natural := integer(ceil(log(real(NUM_TAPS)) / log(2.0))); signal sum : sum_mem_type(num_levels-1 downto 0, NUM_TAPS-1 downto 0) := (others => (others => (others => '0')));
Code:ADDER_LEVELS_GEN : for l in 0 to num_levels-1 generate constant num_adders : natural := integer(ceil(real(NUM_TAPS)/(2.0**(l+1)))); constant num_adder_prev_stage : natural := integer(ceil(real(NUM_TAPS)/(2.0**(l)))); begin LEVEL_0_GEN : if (l = 0) generate ADDERS_GEN : for m in 0 to num_adders-1 generate NO_ADDER_GEN : if ((m = (num_adders-1)) and ((num_adder_prev_stage mod 2) = 1)) generate sum(l,m) <= prod(m*2) when rising_edge(clk); end generate NO_ADDER_GEN; ADDER_GEN : if ((m < (num_adders-1)) or ((num_adder_prev_stage mod 2) = 0)) generate sum(l,m) <= prod(m*2) + prod(m*2+1) when rising_edge(clk); end generate ADDER_GEN; end generate ADDERS_GEN; end generate LEVEL_0_GEN; LEVEL_X_GEN : if (l > 0) generate ADDERS_GEN : for m in 0 to num_adders-1 generate NO_ADDER_GEN : if ((m = (num_adders-1)) and ((num_adder_prev_stage mod 2) = 1)) generate sum(l,m) <= sum(l-1,m*2) when rising_edge(clk); end generate NO_ADDER_GEN; ADDER_GEN : if ((m < (num_adders-1)) or ((num_adder_prev_stage mod 2) = 0)) generate sum(l,m) <= sum(l-1,m*2) + sum(l-1,m*2+1) when rising_edge(clk); end generate ADDER_GEN; end generate ADDERS_GEN; end generate LEVEL_X_GEN; end generate ADDER_LEVELS_GEN; data_out <= std_logic_vector(sum(num_levels-1,0)) when rising_edge(clk);
Comment
-
Sang phần simulation, bạn có thể tiếp tục dùng math_real library.
Code:signal data_in : std_logic_vector(15 downto 0) := (others => '0'); signal data_out : std_logic_vector(31 downto 0) := (others => '0'); signal counter : natural := 0;
Code:data_gen_proc : process(clk) begin if (rising_edge(clk)) then if (counter mod 4 = 0) then data_in <= std_logic_vector(to_signed(integer(sin(real(counter) / 10.0) * 32767.0), data_in'length)); else data_in <= (others => '0'); end if; counter <= counter + 1; end if; end process data_gen_proc;
=======
Adder tree còn rườm rà; systolic form gọn hơn nhiều:
Code:delay_buf = zeros(len(filter_coeffs)*2-1); y = zeros(len(x)); prod = zeros(len(filter_coeffs)); sum_out = zeros(len(filter_coeffs)); for i in range (len(x)) : delay_buf[1:len(delay_buf)] = delay_buf[0:len(delay_buf)-1];delay_buf[0] = x[i] for k in range (len(filter_coeffs)) : prod[k] = delay_buf[k*2] * filter_coeffs[k]; for k in range (len(filter_coeffs)-1,-1,-1) : if (k == 0) : sum_out[k] = prod[k]; else : sum_out[k] = prod[k] + sum_out[k-1]; y[i] = sum_out[len(sum_out)-1]
Last edited by nemesis21; 08-05-2010, 07:14.
Comment
-
Nguyên văn bởi nemesis21 Xem bài viết- Design cho filter như thế nào? Dựa vào requirements / specs, bạn đã chọn filter structure nào? Parallel, serial (single multiplier), hoặc semi-parallel? Nếu serial, mạch delay của bạn nên sử dụng RAM (hoặc registers và multiplexer để emulate RAM). Nếu parallel, mạch delay của bạn nên sử dụng registers. Bạn đã chọn structure / mạch delay nào? Bạn đã vẽ block diagram cho design của bạn? Generic design hay là target spefiic? Chẳng hạn như với DSP48 của Virtex-4, parallel design có thể hoàn toàn sử dụng intenal registers và routing của DSP48. Bạn đã diagram / model mạch delay của bạn?
http://en.wikipedia.org/wiki/High-level_synthesis
Comment
-
Nguyên văn bởi tonyvandinh Xem bài viếtĐây là những câu hỏi thường có trong đầu của người làm thiết kế. Khá phức tạp để chọn lựa cái architecture nào để làm. Khi chọn rồi, làm giữa chừng mà muốn đổi thì sao? Làm sao để trade-off giữa tốc độ và tốn kém? Vì vậy cần phải giữ thiết kế nguồn kô bị lệ thuộc vào thời gian and hardware architecture rồi dùng phương pháp tự động hóa để chuyển biến qua thiết kế hiện thực mà mình muốn. Link dưới đây sẽ cho các bạn có thêm khái niệm về phương pháp này (High Level Synthesis)
http://en.wikipedia.org/wiki/High-level_synthesis
Nếu chúng ta cần gấp một configurable FIR core, chúng ta có thể bỏ ra vài phút với Coregen. FIR filter là một beginner project vừa tầm để introduce basic techniques, nhưng là một unconvincing case cho high level synthesis tools.
Mentor có một demonstration video dùng Catapult C để implement FIR:
http://www.mentor.com/products/esl/m...1-b8518e15cbbe
Phần C code cũng tương tự như bạn đã đưa lên, nhưng phần implementation lại nhắm vào ASIC, nên không thể nói rằng những biến thể đó là parallel vs semi-parallel vs serial architecture trên FPGA.
Nếu có thể thì bạn làm một high level synthesis demonstration cho FPGA. Demo của Mentor không nhắm vào FPGA cho nên chưa được convincing lắm.
System C là một chuyện, more exposure về FPGA cho "software crowd" beginners. Có khá nhiều tool để chuyển từ System C sang HDL. Nhưng "algorithm synthesis tool" có lẽ thuộc vào một phạm trù khác. Về cost và availability, nó nằm ngoài tầm với, ngay cả cho nhiều companies. Tôi cảm thấy nó là một sự phụ thuộc vào tool từ một vài specific vendor hơn là một phương pháp đại trà.
Comment
-
Tiếp theo phần simple systolic FIR hôm trước, nếu bạn thử implement adder chain và synthesize FIR cho Virtex-5 speed grade -2 device, maximum frequency sẽ vào khoảng 250 MHz.
Code:ADDER_GEN : for i in 0 to NUM_TAPS-1 generate ADDER_0_GEN : if i = 0 generate sum(i) <= prod(i) when rising_edge(clk); end generate; ADDER_X_GEN : if i > 0 generate sum(i) <= prod(i) + sum(i-1) when rising_edge(clk); end generate; end generate ADDER_GEN;
Code:Timing Summary: --------------- Speed Grade: -2 Minimum period: 3.883ns (Maximum Frequency: 257.506MHz) Minimum input arrival time before clock: 0.980ns Maximum output required time after clock: 2.910ns Maximum combinational path delay: No path found
Chúng ta bắt đầu lại với phần hoán chuyển từ adder tree sang adder chain. Đó là một well-documented technique. Hình đính kèm từ Lyrtech illustrate technique đó khá rõ. Chúng ta có thể thấy các systolic "processing elements" illustrated trong phần 3. Simplified systolic (Python) model đã được đưa ra ở trên. Nhưng chúng ta model full systolic array như thế nào?
Đại khái là, processing element có thể được model bằng class:
Code:class PE () : def __init__(self) : self.leftCell = 0; self.a1 = 0; self.a2 = 0; self.b2 = 0; self.m = 0; self.p = 0; def simClkCycle (self, a1 = 0) : if (self.leftCell == 0) : self.p = self.m + 0; self.m = self.a2 * self.b2; self.a2 = self.a1; self.a1 = a1; else : self.p = self.m + self.leftCell.p; self.m = self.a2 * self.b2; self.a2 = self.a1; self.a1 = self.leftCell.a2;
Code:peList = list(); previousPE = 0; for j in range(len(filter_coeffs)) : pe = PE(); pe.b2 = filter_coeffs[j]; pe.leftCell = previousPE; peList.append(pe); previousPE = pe;
Code:for i in range (len(x)) : for k in range (len(filter_coeffs)-1,0,-1) : peList[k].simClkCycle(); peList[0].simClkCycle(x[i]); y[i] = peList[len(peList)-1].p;
Code:type breg_type is array(natural range <>) of std_logic_vector(data_in'range); signal breg : breg_type(NUM_TAPS-1 downto 0); type preg_type is array(natural range <>) of std_logic_vector(data_in'length*2-1 downto 0); signal preg : preg_type(NUM_TAPS-1 downto 0); constant zero : std_logic_vector(47 downto 0) := (others => '0');
Code:pe_inst : entity work.pe port map ( clk => clk, a => filter_coeffs(0), bcin => data_in, bcout => breg(0), pcin => zero(preg(0)'range), pcout => preg(0) ); PE_X: for i in 1 to NUM_TAPS-1 generate pe_inst : entity work.pe port map ( clk => clk, a => filter_coeffs(i), bcin => breg(i-1), bcout => breg(i), pcin => preg(i-1), pcout => preg(i) ); end generate; data_out <= preg(NUM_TAPS-1);
Code:Slice Logic Utilization: Slice Logic Distribution: Number of LUT Flip Flop pairs used: 0 Number with an unused Flip Flop: 0 out of 0 Number with an unused LUT: 0 out of 0 Number of fully used LUT-FF pairs: 0 out of 0 Number of unique control sets: 0 IO Utilization: Number of IOs: 49 Number of bonded IOBs: 49 out of 480 10% Specific Feature Utilization: Number of BUFG/BUFGCTRLs: 1 out of 32 3% Number of DSP48Es: 21 out of 288 7%
Code:Timing Summary: --------------- Speed Grade: -2 Minimum period: 1.692ns (Maximum Frequency: 591.017MHz) Minimum input arrival time before clock: 1.190ns Maximum output required time after clock: 2.910ns Maximum combinational path delay: No path found
Comment
-
Processing element model, nếu bạn nhìn kỹ, là một partial model của DSP48 slice (hình đính kèm). Chúng ta vòng vo một chút để illustrate modeling technique, nhưng DSP48 là primitive mà bạn có thể instantiate directly. Đơn giản là một phần của DSP48 được design especially cho filter implementations.
Code:class PE () : def __init__(self) : self.leftCell = 0; self.a1 = 0; self.a2 = 0; self.b2 = 0; self.m = 0; self.p = 0; def simClkCycle (self, a1 = 0) : if (self.leftCell == 0) : self.p = self.m + 0; self.m = self.a2 * self.b2; self.a2 = self.a1; self.a1 = a1; else : self.p = self.m + self.leftCell.p; self.m = self.a2 * self.b2; self.a2 = self.a1; self.a1 = self.leftCell.a2;
FIR filter có thể là quá đơn giản để model, nhưng các algorithm với multi-dimension systolic array có lẽ sẽ interesting hơn. FIR thì vẫn còn serial và semi-parallel implementation. Chúc thành công.
Comment
-
Em kiếm được cái master thesis của bọn này triển khai FIR filter trên FPGA, show các bác xem thế nào ^^
Link download : http://hungnm.edu.vn/cupid1102/FIR_Filter_FPGA/Cupid1102 = Cupid độc nhất vô nhị
Comment
Bài viết mới nhất
Collapse
-
Comment on Đồng hồ công tơ điện tửbởi qpdt03
-
Channel: Điện tử dành cho người mới bắt đầu
23-03-2024, 17:03 -
-
Comment on Đồng hồ công tơ điện tửbởi qpdt03
-
Channel: Điện tử dành cho người mới bắt đầu
23-03-2024, 17:03 -
-
Trả lời cho Đồng hồ công tơ điện tửbởi qpdt03Hình ảnh mạch của nó đây, mình mang đồng hồ điện tử ra đo giá trị điện trở dán ghi trên lưng các con điện trở trong mạch đều đúng, mà công tơ điện tử vẫn đo sai, không biết nó hỏng chỗ nào; đã ấn nút reset lại nhưng vẫn không đc. Nhờ các bác có kinh nghiệm giúp đỡ. Thanks!
-
Channel: Điện tử dành cho người mới bắt đầu
23-03-2024, 17:03 -
-
bởi qpdt03Mình mới mua 1 cái đồng hồ công tơ điện tử trên shopee; loại hiển thị 4 thông số V,A,W và tổng số Kwh nhưng về cắm thử đc 1 hôm thì chỉ số V báo 378v, cắm về 100v cũng báo 350v có bác nào biết cách sửa chữa nó không chỉ giúp mình nhé. Xin cảm ơn mọi người đã đọc bài.
-
Channel: Điện tử dành cho người mới bắt đầu
23-03-2024, 16:46 -
-
bởi notooth1Các bạn xem giúp mình đây là tụ phân cực hay không phân cực nhé.
...-
Channel: Hướng dẫn tìm thông tin linh kiện
20-03-2024, 18:06 -
-
bởi carl22Xin chào tất cả mọi người.
Tôi hiện đang chế tạo một máy phay CNC. Máy phay được điều khiển thông qua Raspberry Pi 3 b+ và Smoothieboard v1.1 với trình điều khiển động cơ bước ACT DM 542 và động cơ 1,8° 2A.
Trục X 1,8° 3 A chạy qua trình điều khiển động cơ bước vì bảng sinh tố chỉ...-
Channel: Cơ cấu chấp hành (Actuator)
20-03-2024, 15:48 -
-
bởi ningoleChào các bác! Em là newbie về điện tử đang muốn làm một cái đèn báo cho ổ cắm nhưng chưa rành về mạch mong các bác giúp đỡ!
Nhu cầu của e là muốn làm 1 đèn báo nguồn AC 220V:
Nguồn 220v -> Phích cắm -> nối với 1 ổ cắm....-
Channel: Điện tử dành cho người mới bắt đầu
20-03-2024, 11:09 -
-
Trả lời cho có cần thiết phải lắp mạch bms cho khối pin ?bởi bao98Tất nhiên là bạn cần nó!
BMS là một phần không thể thiếu trong hệ thống ắc quy của xe điện.
nếu bạn không cài đặt BMS, có thể xảy ra vấn đề về pin, thậm chí có thể dẫn đến tai nạn-
Channel: Điện tử dành cho người mới bắt đầu
19-03-2024, 22:51 -
-
Trả lời cho [đồ án] xung đột nguồn điện 12vbởi bao98Để tìm hiểu xem bộ điều hợp UART của bạn được kết nối với cổng USB nào trên Raspberry Pi, bạn có thể sử dụng lệnh ls /dev/ttyUSB* hoặc ls /dev/ttyACM* trong thiết bị đầu cuối. Điều này sẽ liệt kê các cổng USB có sẵn để liên lạc nối tiếp. Cáp có thể được xem ở đây. Bạn cũng có thể kết nối và...
-
Channel: Hỗ trợ học tập
19-03-2024, 22:38 -
-
Trả lời cho cho hỏi move điện là g?bởi DiennuocAQLà sự tiếp xúc giữa 2 tiếp điểm không được tốt gây ra. Ví dụ như đầu dây điện cắm vào chân attomat nhưng lâu ngày ốc siết lỏng dần ra, làm dòng điện chuyển tiếp không tốt, gây ra hệ thống điện chập chờn gọi là move ạ
-
Channel: Điện tử dành cho người mới bắt đầu
19-03-2024, 12:40 -
Comment