2026年1月16日 星期五

ASK 調變模擬器程式碼

ASK 調變模擬器程式碼

為什麼第二張圖要「放大 (Zoom)」?

  • 1 kHz 的週期是 1000us

  • 如果不放大,第二張圖會因為波形太密而看起來像一塊實心的紅磚。



import tkinter as tk

from tkinter import ttk

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


# 解決中文顯示問題的替代方案:直接使用英文標籤

class ASKSidmulator:

    def __init__(self, root):

        self.root = root

        self.root.title("RFID ASK Modulation Simulator (1kHz -> 2.45MHz)")

        self.root.geometry("900x750")


        # 參數設定

        self.f_signal = 1000        # 1 kHz 基頻

        self.f_carrier = 2450000    # 2.45 MHz 載波

        self.fs = 25000000          # 25 MHz 取樣率

        

        self.setup_ui()


    def setup_ui(self):

        # 控制面板

        ctrl_frame = tk.Frame(self.root, pady=10)

        ctrl_frame.pack(side=tk.TOP, fill="x")


        info_text = "Baseband: 1kHz Sine Wave | Carrier: 2.45MHz Sine Wave"

        tk.Label(ctrl_frame, text=info_text, font=("Arial", 11)).pack()

        

        btn_generate = tk.Button(ctrl_frame, text="Generate ASK Waveforms", 

                                 command=self.plot_waves, bg="#2980b9", fg="white", padx=20)

        btn_generate.pack(pady=5)


        # 建立 Matplotlib 圖表 (不再使用中文標題)

        self.fig, (self.ax1, self.ax2, self.ax3) = plt.subplots(3, 1, figsize=(8, 9))

        self.fig.tight_layout(pad=4.0)

        

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)

        self.canvas.get_tk_widget().pack(fill="both", expand=True)


    def generate_data(self):

        # 取 2 毫秒數據

        t = np.linspace(0, 0.002, int(self.fs * 0.002))

        

        # 1. 基頻正弦波 (Baseband)

        baseband = np.sin(2 * np.pi * self.f_signal * t)

        

        # 2. ASK 邏輯:當正弦波 > 0 為 High,否則為 Low

        digital_logic = (baseband > 0).astype(float)

        

        # 3. 高頻載波 (Carrier)

        carrier = np.sin(2 * np.pi * self.f_carrier * t)

        

        # 4. ASK 調變:High 時 100% 幅度,Low 時 20% 幅度

        m_index = 0.2

        ask_output = (digital_logic + m_index * (1 - digital_logic)) * carrier

        

        return t, baseband, carrier, ask_output


    def plot_waves(self):

        t, baseband, carrier, ask_output = self.generate_data()


        # 清除舊圖

        self.ax1.clear()

        self.ax2.clear()

        self.ax3.clear()


        # 圖 1: 1kHz Baseband

        self.ax1.plot(t * 1000, baseband, color='blue')

        self.ax1.set_title("1. Baseband Signal (1 kHz Sine Wave)")

        self.ax1.set_ylabel("Amplitude")

        self.ax1.set_xlabel("Time (ms)")

        self.ax1.grid(True, alpha=0.3)


        # 圖 2: 2.45MHz Carrier (Zoomed in 20us)

        # 放大觀察,否則 2.45MHz 太密看不清

        zoom_limit = 0.00002 

        mask = t < zoom_limit

        self.ax2.plot(t[mask] * 1000000, carrier[mask], color='red')

        self.ax2.set_title("2. Carrier Waveform (Zoomed: First 20 microseconds)")

        self.ax2.set_ylabel("Amplitude")

        self.ax2.set_xlabel("Time (us)")

        self.ax2.grid(True, alpha=0.3)


        # 圖 3: ASK Modulated Output

        self.ax3.plot(t * 1000, ask_output, color='green', linewidth=0.5)

        self.ax3.set_title("3. Modulated ASK Output (1kHz data on 2.45MHz carrier)")

        self.ax3.set_ylabel("Amplitude")

        self.ax3.set_xlabel("Time (ms)")

        self.ax3.grid(True, alpha=0.3)


        self.canvas.draw()


if __name__ == "__main__":

    root = tk.Tk()

    app = ASKSidmulator(root)

    root.mainloop()

 

沒有留言:

張貼留言

ASK 調變模擬器程式碼

ASK 調變模擬器程式碼 為什麼第二張圖要「放大 (Zoom)」? 1 kHz  的週期是 1000 us 。 如果不放大,第二張圖會因為波形太密而看起來像一塊實心的紅磚。 import tkinter as tk from tkinter import ttk import n...