python 第 2 週 進度(2024/03/12 ~ 2024/03/18)
盤點過去編寫的幾個程式存在一個缺失,
當要移到其他電腦上執行,常遇到
1. 連接埠 (COM 和LPT) 編號
2. 鏡頭編號
3. 連接WIFI 名稱
4. IP 位置
與程式已寫死的資料不同,因此需要修改上述設定
本週嘗試以ChapGPT 協作完成以上工作
一、 連接埠 (COM 和LPT)設定
使用USB HUB, 連接如下圖 3 種 UART TOOL 與真正需要連接的 Arduino NANO 模板
3 種 UART TOOL 左至右, 分別是
Arduino NANO 模板,USB to UART,USB to RS485,USB to UART

以裝置管理員檢查連接埠 (COM 和LPT) 連接設備情況,
COM10 是 Arduino NANO,
COM12 是 USB to UART
其餘 2 個 PL2303HAX 因為未安裝 Driver 所以未顯示

**以 ChapGPT 協作, 產生程式 uart_setcom.py如下**
```
# uart_setcom.py
# 2024/03/15
# 我要用python 做 uart 應用程式, 首先偵測目前 pc 連接了幾個 COM Port,
# 在視窗上列出目前有那幾個COM Port的編號與名稱,再由使用者選擇
#
import serial.tools.list_ports
def list_available_ports():
ports = serial.tools.list_ports.comports()
if ports:
print("Available COM Ports:")
for idx, port in enumerate(ports):
print(f"{idx}: {port.device} - {port.description}")
else:
print("No COM Ports available.")
def select_port():
selected_index = input("Enter the index of the port you want to use: ")
try:
selected_index = int(selected_index)
ports = serial.tools.list_ports.comports()
if 0 <= selected_index < len(ports):
selected_port = ports[selected_index].device
print(f"You selected port: {selected_port}")
return selected_port
else:
print("Invalid index.")
return None
except ValueError:
print("Please enter a valid integer.")
return None
def main():
list_available_ports()
selected_port = select_port()
while selected_port is None:
selected_port = select_port()
# 在这里可以将选定的端口传递给你的UART应用程序
if __name__ == "__main__":
main()
```
執行 uart_setcom.py , 搜尋結果如下

使用 python IDEL 測試
```
>>> import serial.tools.list_ports
>>> ports = serial.tools.list_ports.comports()
>>> print(len(ports))
4
>>> print(ports[0])
COM9 - PL2303HXA PHASED OUT SINCE 2012. PLEASE CONTACT YOUR SUPPLIER.
>>> print(ports[1])
COM10 - USB-SERIAL CH340 (COM10)
>>> print(ports[2])
COM11 - PL2303HXA PHASED OUT SINCE 2012. PLEASE CONTACT YOUR SUPPLIER.
```
再次要求ChapGPT 改用 tkinter 的 Radiobutton 方式選擇 COM Port

```
# uart_setcom_2.py
# 以上程式請改用 tkinter 的 Radiobutton 方式選擇 COM Port,
# 請保留列印 COM Port的編號與名稱的功能
import serial.tools.list_ports
import tkinter as tk
from tkinter import ttk
# 定义一个全局变量来存储用户选择的COM端口
selected_var = None # 将selected_var定义在函数之外
def list_available_ports(): # 列出所有可用的COM端口
ports = serial.tools.list_ports.comports()
if ports:
print("Available COM Ports:")
for idx, port in enumerate(ports):
# print(f"{idx}: {port.device} - {port.description}")
print(f"{idx}: {port.device}- {port.product}")
else:
print("No COM Ports available.")
def select_port(): # 获取用户选择的COM端口
selected_port = selected_var.get()
if selected_port:
print(f"You selected port: {selected_port}")
return selected_port
else:
print("Please select a port.")
return None
def main():
global selected_var # 声明selected_var为全局变量
list_available_ports()
root = tk.Tk() # 创建Tkinter应用程序窗口
root.title("Select COM Port")
root.geometry('800x400')
# root.configure(bg='green')
frame = ttk.Frame(root, padding="10") # 创建一个框架用于放置组件
frame.grid(row=0, column=0, sticky="nsew")
available_ports = serial.tools.list_ports.comports()
selected_var = tk.StringVar() # 定义选中的端口
for idx, port in enumerate(available_ports):
ttk.Radiobutton(
frame,
text=f"{idx}: {port.device} - {port.description}",
variable=selected_var,
value=port.device
).grid(row=idx, column=0, sticky="w")
ttk.Button(
frame,
text="Select Port",
command=lambda: root.quit()
).grid(row=len(available_ports), column=0, sticky="w")
root.mainloop()
selected_port = select_port()
while selected_port is None:
selected_port = select_port()
# 在这里可以将选定的端口传递给你的UART应用程序
if __name__ == "__main__":
main()
```
**二、鏡頭設定**
以裝置管理員檢查相機連接設備情況,發現連接 2 個鏡頭,一個是筆電機上鏡頭,另一是 USB CAM

請求 ChapGPT 協作
延續上面的工作, 現在要用程式偵測 pc 連接幾個鏡頭,並且列出 再由使用者選擇鏡頭 函式庫是使用 cv2
執行結果


隨後再請求ChapGPT列出 Camer 名稱

```
import cv2
import tkinter as tk
from tkinter import ttk
def list_available_cameras():
# 检测可用的摄像头并获取名称
camera_list = []
for i in range(10): # 假设最多检测10个摄像头
cap = cv2.VideoCapture(i)
if cap.isOpened():
ret, frame = cap.read()
if ret:
camera_name = f"Camera {i}: {frame.shape[1]}x{frame.shape[0]}"
camera_list.append((i, camera_name))
cap.release()
return camera_list
def select_camera():
# 获取用户选择的摄像头
selected_camera = selected_var.get()
if selected_camera is not None:
print(f"You selected camera: {selected_camera}")
return selected_camera
else:
print("Please select a camera.")
return None
def main():
global selected_var
cameras = list_available_cameras()
root = tk.Tk()
root.title("Select Camera")
frame = ttk.Frame(root, padding="10")
frame.grid(row=0, column=0, sticky="nsew")
selected_var = tk.StringVar(value=None)
for idx, (camera_index, camera_name) in enumerate(cameras):
ttk.Radiobutton(
frame,
text=camera_name,
variable=selected_var,
value=camera_index
).grid(row=idx, column=0, sticky="w")
ttk.Button(
frame,
text="Select Camera",
command=lambda: root.quit()
).grid(row=len(cameras), column=0, sticky="w")
root.mainloop()
selected_camera = select_camera()
while selected_camera is None:
selected_camera = select_camera()
# 在这里可以将选定的摄像头传递给你的应用程序
if __name__ == "__main__":
main()
```