2025年10月29日 星期三

無線電頻率分配表--python

 無線電頻率分配表


程式功能摘要

功能區描述
輸入頻率允許輸入數值,並從下拉選單選擇單位:KHz, MHz, GHz
輸出波長單位允許從下拉選單選擇波長的輸出單位:公尺, 公分, 公釐
計算按鈕點擊後執行計算 $ \lambda = c / f $。
計算結果顯示最終的波長數值(保留三位小數)。
頻帶命名根據國際標準 (ITU) 的頻率範圍顯示對應的中文名稱和縮寫 (例如:特低頻 (VLF) - 3 至 30 KHz)。
錯誤處理如果輸入不是有效數字或頻率小於等於零,會彈出錯誤視窗。

900 MHz 計算結果範例

當您運行此程式並使用預設值 900 MHz$900 \times 10^6$ Hz)時,計算結果如下:

  1. 波長 (公尺):

    $$\lambda = \frac{3 \times 10^8 \text{ m/s}}{900 \times 10^6 \text{ Hz}} = \frac{3}{9} \text{ m} = 0.3333 \text{ 公尺}$$
  2. 頻帶命名:

    • 900 MHz 轉換為 KHz 為 $900,000  KHz

    • 頻率範圍落在 $300,000 KHz 到 $3,0 00,000 KHz 之間。

    • 結果: 超高頻 (UHF) - 300 MHz 至 3 GHz






import tkinter as tk
from tkinter import ttk, messagebox

# 真空中的光速 (根據使用者要求設定為 3 x 10^8 公尺/秒)
SPEED_OF_LIGHT = 3e8  # 300000000.0 公尺/秒

def calculate_wavelength(frequency_value, freq_unit):
    """根據頻率值和單位計算波長 (單位為公尺)。"""
    
    # 頻率單位轉換為 Hertz (Hz)
    if freq_unit == "KHz":
        frequency_hz = frequency_value * 1e3
    elif freq_unit == "MHz":
        frequency_hz = frequency_value * 1e6
    elif freq_unit == "GHz":
        frequency_hz = frequency_value * 1e9
    else: # 預設為 Hz
        frequency_hz = frequency_value

    if frequency_hz <= 0:
        return 0, "無效頻率"

    # 計算波長 (公尺)
    # 公式: 波長(λ) = 光速(c) / 頻率(f)
    wavelength_m = SPEED_OF_LIGHT / frequency_hz
    
    # 判斷頻帶名稱
    band_name = get_band_name(frequency_hz)

    return wavelength_m, band_name

def get_band_name(frequency_hz):
    """根據頻率 (Hz) 判斷頻帶名稱 (參照 ITU 無線電頻帶標準)。"""
    
    # 轉換為 KHz 以便於與頻帶範圍進行比較
    f_khz = frequency_hz / 1e3

    # 頻帶命名 (特低頻 VLF, 低頻 LF, 中頻 MF, 高頻 HF, 特高頻 VHF, 超高頻 UHF, 極高頻 SHF, 特高頻 EHF, 極端高頻 THF)
    if 3 <= f_khz < 30:
        return "特低頻 (VLF) - 3 至 30 KHz"
    elif 30 <= f_khz < 300:
        return "低頻 (LF) - 30 至 300 KHz"
    elif 300 <= f_khz < 3000: # 300 KHz 至 3 MHz
        return "中頻 (MF) - 300 KHz 至 3 MHz"
    elif 3000 <= f_khz < 30000: # 3 MHz 至 30 MHz
        return "高頻 (HF) - 3 至 30 MHz"
    elif 30000 <= f_khz < 300000: # 30 MHz 至 300 MHz
        return "特高頻 (VHF) - 30 至 300 MHz"
    elif 300000 <= f_khz < 3000000: # 300 MHz 至 3 GHz
        return "超高頻 (UHF) - 300 MHz 至 3 GHz"
    elif 3000000 <= f_khz < 30000000: # 3 GHz 至 30 GHz
        return "極高頻 (SHF) - 3 至 30 GHz"
    elif 30000000 <= f_khz < 300000000: # 30 GHz 至 300 GHz
        return "特高頻 (EHF) - 30 至 300 GHz"
    elif f_khz >= 300000000: # 300 GHz 以上
        return "極端高頻 (THF) - 300 GHz 以上"
    else: # 3 KHz 以下
        return "超低頻 (SLF) 或更低 - 3 KHz 以下"

def convert_wavelength(wavelength_m, wavelength_unit):
    """將波長 (公尺) 轉換為所需的單位。"""
    
    if wavelength_unit == "公里":
        return wavelength_m / 1000
    elif wavelength_unit == "公尺":
        return wavelength_m
    elif wavelength_unit == "公分":
        return wavelength_m * 100
    elif wavelength_unit == "公釐":
        return wavelength_m * 1000
    else:
        return wavelength_m # 預設為公尺

class WavelengthCalculator(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("頻率波長計算器與頻帶顯示")
        self.geometry("600x350")
        
        # 設定樣式和主框架
        style = ttk.Style(self)
        style.configure('TFrame', padding=10)
        style.configure('TLabel', font=('Arial', 10))
        style.configure('TButton', font=('Arial', 10, 'bold'))

        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill='both', expand=True)
        
        # --- 輸入區 ---
        input_frame = ttk.LabelFrame(main_frame, text="輸入頻率", padding="10")
        input_frame.grid(row=0, column=0, padx=5, pady=5, sticky='ew')
        
        ttk.Label(input_frame, text="頻率值 (f):").grid(row=0, column=0, padx=5, pady=5, sticky='w')
        self.freq_entry = ttk.Entry(input_frame, width=15)
        self.freq_entry.insert(0, "900") # 預設值為 900
        self.freq_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')

        ttk.Label(input_frame, text="頻率單位:").grid(row=1, column=0, padx=5, pady=5, sticky='w')
        self.freq_unit = tk.StringVar(value="MHz")
        self.freq_unit_combo = ttk.Combobox(input_frame, textvariable=self.freq_unit, values=["KHz", "MHz", "GHz"], width=12, state="readonly")
        self.freq_unit_combo.grid(row=1, column=1, padx=5, pady=5, sticky='w')

        # --- 輸出單位選擇 ---
        output_frame = ttk.LabelFrame(main_frame, text="輸出波長單位", padding="10")
        output_frame.grid(row=0, column=1, padx=5, pady=5, sticky='ew')
        
        ttk.Label(output_frame, text="波長單位 (λ):").grid(row=0, column=0, padx=5, pady=5, sticky='w')
        self.wave_unit = tk.StringVar(value="公尺")
        
        # ***** 調整波長單位選項順序 *****
        self.wave_unit_combo = ttk.Combobox(output_frame, textvariable=self.wave_unit, 
                                           values=["公里", "公尺", "公分", "公釐"], 
                                           width=12, state="readonly")
        self.wave_unit_combo.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        
        # --- 計算按鈕 ---
        calc_button = ttk.Button(main_frame, text="計算波長與頻帶 (光速=3e8 m/s)", command=self.do_calculation)
        calc_button.grid(row=1, column=0, columnspan=2, padx=5, pady=10, sticky='ew')

        # --- 結果顯示區 ---
        result_frame = ttk.LabelFrame(main_frame, text="計算結果", padding="10")
        result_frame.grid(row=2, column=0, columnspan=2, padx=5, pady=5, sticky='ew')

        self.wave_result_label = ttk.Label(result_frame, text="波長: 請輸入頻率並計算", font=('Arial', 12, 'bold'), foreground='blue')
        self.wave_result_label.pack(anchor='w', pady=5)
        
        self.band_result_label = ttk.Label(result_frame, text="頻帶命名:", font=('Arial', 12, 'bold'), foreground='green')
        self.band_result_label.pack(anchor='w', pady=5)
        
        # 網格配置
        main_frame.grid_columnconfigure(0, weight=1)
        main_frame.grid_columnconfigure(1, weight=1)
        main_frame.grid_rowconfigure(2, weight=1)

    def do_calculation(self):
        """執行計算並更新結果顯示。"""
        try:
            freq_value = float(self.freq_entry.get())
        except ValueError:
            messagebox.showerror("輸入錯誤", "請輸入有效的數字作為頻率值。")
            return
        
        if freq_value <= 0:
            messagebox.showerror("輸入錯誤", "頻率必須大於零。")
            return

        freq_unit = self.freq_unit.get()
        wave_unit = self.wave_unit.get()

        # 1. 計算波長 (公尺) 並獲取頻帶名稱
        wavelength_m, band_name = calculate_wavelength(freq_value, freq_unit)
        
        # 2. 轉換波長單位
        converted_wavelength = convert_wavelength(wavelength_m, wave_unit)

        # 3. 更新結果顯示
        # 根據單位調整小數位數顯示
        if wave_unit == "公里":
            format_str = ",.6f" # 公里通常需要更多小數位
        elif wave_unit == "公釐":
            format_str = ",.2f"
        else:
            format_str = ",.4f"

        self.wave_result_label.config(
            text=f"波長: {converted_wavelength:{format_str}} {wave_unit}"
        )
        self.band_result_label.config(
            text=f"頻帶命名: {band_name}"
        )


if __name__ == "__main__":
    app = WavelengthCalculator()
    app.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...