2026年1月21日 星期三

IOS14443B 讀取器至電子標籤 調變及編碼方式

 IOS14443B  讀取器至電子標籤 調變及編碼方式

根據 ISO 14443-B 標準,ASK 10% 的調變指數實務上通常落在 8% 到 14% 之間。

核心原理解析

  1. NRZ 編碼 (Non-Return-to-Zero):逻辑 '1' 代表高電位,逻辑 '0' 代表低電位。在位元持續時間內,電平保持不變。

  2. ASK 10% 調變:載波(Carrier)在邏輯低位時不會歸零,而是下降到最大振幅的約 90%。

    • 計算公式:m =  {A - B} / {A + B},其中 A  是最大振幅, B 是最小振幅。

    • m = 10%,則 B  ≈ 0.818  *   A




Python 實作程式碼

import tkinter as tk

from tkinter import messagebox

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


class ISO14443BSimulator:

    def __init__(self, root):

        self.root = root

        self.root.title("ISO 14443-B ASK 10% 模擬器")

        

        # --- UI 介面佈局 ---

        control_frame = tk.Frame(root)

        control_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=10)


        tk.Label(control_frame, text="二進位位元流 (Bit Stream):").pack(side=tk.LEFT)

        self.bit_entry = tk.Entry(control_frame, width=25)

        self.bit_entry.insert(0, "101101")

        self.bit_entry.pack(side=tk.LEFT, padx=5)


        self.btn_plot = tk.Button(control_frame, text="繪製波形", command=self.plot_waveform, bg="#e1e1e1")

        self.btn_plot.pack(side=tk.LEFT, padx=5)


        # Matplotlib 畫布設定

        # tight_layout 確保標籤不會被切到

        self.fig, self.ax = plt.subplots(figsize=(8, 4.5), dpi=100)

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

        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)


    def plot_waveform(self):

        bits_str = self.bit_entry.get().strip()

        

        # 檢查輸入是否合法

        if not bits_str or not all(b in '01' for b in bits_str):

            messagebox.showerror("錯誤", "請輸入有效的二進位字串 (僅限 0 與 1)")

            return


        bits = [int(b) for b in bits_str]

        

        # 模擬參數

        fs = 500  # 每個 bit 的取樣點數

        carrier_freq = 10  # 載波頻率

        total_points = len(bits) * fs

        t = np.linspace(0, len(bits), total_points)

        

        # 1. 生成 NRZ 信號 (用於包絡線)

        # ISO 14443-B: 1 = 高振幅 (A), 0 = 低振幅 (B)

        # 若指數為 10%, 則 B ≈ 0.82 * A

        A = 1.0

        B = 0.818 

        envelope = np.repeat([A if b == 1 else B for b in bits], fs)

        

        # 2. 生成載波並進行 ASK 調變

        carrier = np.sin(2 * np.pi * carrier_freq * t)

        ask_signal = envelope * carrier


        # --- 開始繪圖 ---

        self.ax.clear()

        

        # 繪製 ASK 調變波形 (藍色實線)

        self.ax.plot(t, ask_signal, color='#1f77b4', label='ASK 10% (ISO 14443-B)', linewidth=1)

        

        # 繪製原始 NRZ 數據參考線 (紅色虛線)

        # 為了美觀,將 0/1 映射到對應的振幅高度

        nrz_display = np.repeat([A if b == 1 else B for b in bits], fs)

        self.ax.plot(t, nrz_display, color='red', linestyle='--', alpha=0.7, label='NRZ Data')


        # 設定圖表格式

        self.ax.set_ylim(-1.3, 1.5)

        self.ax.set_title(f"ISO 14443-B Modulation Simulation", fontsize=12)

        self.ax.set_xlabel("Bit Period")

        self.ax.set_ylabel("Amplitude")

        self.ax.grid(True, which='both', linestyle=':', alpha=0.6)


        # --- 關鍵修改:將圖例移至右下角 ---

        # loc='lower right' 指定位置

        # frameon=True 加上外框以利辨識

        self.ax.legend(loc='lower right', frameon=True, shadow=True, fontsize='small')

        

        self.fig.tight_layout()

        self.canvas.draw()


if __name__ == "__main__":

    root = tk.Tk()

    # 設定視窗初始大小

    root.geometry("850x550")

    app = ISO14443BSimulator(root)

    # 啟動時先畫一次預設值

    app.plot_waveform()

    root.mainloop()


沒有留言:

張貼留言

經由MQTT協定的2個WOKWI ESP32 雙向通訊 (ESP32 to ESP32 MQTT Communication )

 經由MQTT協定的2個WOKWI ESP32 雙向通訊  (ESP32  to ESP32 MQTT Communication ) 使用兩個 ESP32 建立一個遠端控制系統。 MQTT Broker: mqtt-dashboard.com Topic (主題): ale...