2025年11月9日 星期日

發射脈衝圖形 (50-90 per second at 58 kHz)

發射脈衝圖形 (50-90 per second at 58 kHz)

  • 載波頻率 (Carrier Freq): 58  kHz (高頻信號)。

  • 脈衝重複率 (Pulse Repetition Rate, PRR): 50  到 90  次/秒 (低頻率)。


這是一種突發信號 (Burst Signal),其中 58{ kHz 的載波只在 50  到 90  Hz 的低頻率下週期性地出現


 


import tkinter as tk

import math

import numpy as np

from tkinter import ttk


# --- 參數設定 ---

CARRIER_FREQ_KHZ = 58      # 載波頻率 58 kHz

PRR_HZ = 70                # 脈衝重複率 (取中間值 70 Hz)

BURST_DURATION = 0.001     # 每個脈衝的持續時間 (例如 1 毫秒)

DURATION_WINDOW = 0.05     # 繪圖的總時間長度 (50 毫秒,足以顯示 3-4 個脈衝)


class BurstSignalViewer:

    def __init__(self, master):

        self.master = master

        master.title("發射脈衝波形圖 (50-90 per second at 58 kHz)")


        main_frame = ttk.Frame(master, padding="15")

        main_frame.pack(fill='both', expand=True)


        ttk.Label(main_frame, text="⚡ 58 kHz 突發脈衝信號概念圖 ⚡", 

                  font=("Arial", 16, "bold"), foreground="#FF6600").pack(pady=5)

        

        info_text = f"**載波頻率:** {CARRIER_FREQ_KHZ} kHz\n**脈衝重複率 (PRR):** {PRR_HZ} Hz (週期約 14.3 ms)\n**單個脈衝持續:** {BURST_DURATION*1000} ms"

        ttk.Label(main_frame, text=info_text, font=("Arial", 11)).pack(pady=5)

        

        self.canvas_width = 800

        self.canvas_height = 400

        self.canvas = tk.Canvas(main_frame, width=self.canvas_width, height=self.canvas_height, bg='white', borderwidth=1, relief="solid")

        self.canvas.pack(pady=10)


        self.draw_axes()

        self.draw_burst_signal()


    def draw_axes(self):

        """繪製座標軸"""

        H, W = self.canvas_height, self.canvas_width

        mid_y = H / 2

        

        # 繪製軸

        self.canvas.create_line(50, mid_y, W - 10, mid_y, fill="black", arrow=tk.LAST)

        self.canvas.create_line(50, 10, 50, H - 10, fill="black", arrow=tk.LAST)


        # 標記時間範圍

        self.canvas.create_text(50, mid_y + 15, text="0 S", anchor=tk.N)

        self.canvas.create_text(W - 10, mid_y + 15, text=f"{DURATION_WINDOW*1000} ms", anchor=tk.E)


    def scale_time_to_x(self, t):

        return 50 + (self.canvas_width - 60) * (t / DURATION_WINDOW)


    def scale_amplitude_to_y(self, amplitude):

        mid_y = self.canvas_height / 2

        y_scale = (self.canvas_height - 60) / 2

        return mid_y - amplitude * y_scale


    def draw_burst_signal(self):

        """繪製突發信號"""

        

        T_prr = 1 / PRR_HZ  # 脈衝重複週期 (約 14.3 ms)

        

        # 為了視覺化,我們需要大量的點來繪製載波

        time_points = np.linspace(0, DURATION_WINDOW, 4000)

        points_to_draw = []

        

        carrier_freq_hz = CARRIER_FREQ_KHZ * 1000

        

        num_bursts = math.ceil(DURATION_WINDOW / T_prr)


        for t in time_points:

            # 1. 判斷當前時間是否在脈衝發射窗口內

            

            # 計算當前是在第幾個 PRR 週期

            current_cycle = math.floor(t / T_prr)

            

            # 計算該 PRR 週期開始的時間

            t_start_of_cycle = current_cycle * T_prr

            

            # 計算當前時間在週期內的位置

            t_in_cycle = t - t_start_of_cycle

            

            # 判斷是否在脈衝持續時間內

            if t_in_cycle <= BURST_DURATION:

                # 2. 如果在窗口內,繪製 58 kHz 載波

                amplitude = math.sin(2 * math.pi * carrier_freq_hz * t)

            else:

                # 3. 如果不在窗口內,振幅為 0

                amplitude = 0

            

            x = self.scale_time_to_x(t)

            y = self.scale_amplitude_to_y(amplitude)

            points_to_draw.extend([x, y])


        # 繪製突發信號線條 (橙色)

        self.canvas.create_line(points_to_draw, fill="orange", width=1, tags="burst_signal")

        

        # 標註脈衝區和靜默區

        for i in range(num_bursts):

            t_start = i * T_prr

            t_end = t_start + BURST_DURATION

            

            x_start = self.scale_time_to_x(t_start)

            x_end = self.scale_time_to_x(t_end)

            

            # 脈衝區標記

            if t_start < DURATION_WINDOW:

                self.canvas.create_text(x_start + (x_end - x_start)/2, 30, text="脈衝 ON (58kHz)", fill="darkorange")

                self.canvas.create_rectangle(x_start, 50, x_end, self.canvas_height-50, outline="", fill="#FFDDC9", stipple="gray12")

            

            # 靜默區標記

            t_silence_end = (i + 1) * T_prr

            x_silence_end = self.scale_time_to_x(t_silence_end)

            if t_silence_end < DURATION_WINDOW:

                self.canvas.create_text(x_end + (x_silence_end - x_end)/2, 30, text="靜默 OFF", fill="gray")

                self.canvas.create_line(x_end, self.canvas_height/2, x_silence_end, self.canvas_height/2, fill="red", width=2)

                

# --- 運行 Tkinter 程式 ---

if __name__ == "__main__":

     root = tk.Tk()

     app = BurstSignalViewer(root)

     root.mainloop()


沒有留言:

張貼留言

ESP32 (ESP-IDF in VS Code) MFRC522 + MQTT + PYTHON TKinter +SQLite

 ESP32 (ESP-IDF in VS Code) MFRC522 + MQTT + PYTHON TKinter +SQLite  ESP32 VS Code 程式 ; PlatformIO Project Configuration File ; ;   Build op...