import serial
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# USB 시리얼 포트 설정
usb_port = 'COM5' # 사용할 USB 포트 번호
baud_rate = 9600 # 통신 속도 (bps)
# 시리얼 포트 열기
ser = serial.Serial(usb_port, baud_rate)
# PID 제어 알고리즘 파라미터 설정
Kp = 0.5 # 비례 제어 게인
Ki = 0.2 # 적분 제어 게인
Kd = 0.1 # 미분 제어 게인
dt = 0.1 # 샘플링 간격
#Kp = [float(Kp)] # 형변환 후 리스트로 정의
#Ki = [float(Ki)]
#Kd = [float(Kd)]
#dt = 0.1
#Kp = [0.1] # 비례 제어 게인
#Ki = [0.2] # 적분 제어 게인
#Kd = [0.3] # 미분 제어 게인
#dt = 0.1 # 샘플링 간격
# 목표 피드백 값 설정
target_feedback = 1
# 초기 PID 제어 변수 설정
integral = 0.1
prev_error = 1
derivative = 0.1
# 그래프 초기 설정
fig, ax = plt.subplots()
line_feedback, = ax.plot([], [], 'r-', label='Feedback') # 피드백 데이터를 나타내는 선
line_control_signal, = ax.plot([], [], 'b-', label='Control Signal') # 제어 신호 데이터를 나타내는 선
ax.set_ylim(0, 15) # Y 축 범위 설정 (시리얼 데이터 범위에 따라 조정)
ax.set_xlim(0, 50) # X 축 범위 설정
x_data = np.arange(0, 50) # X 축 데이터 초기값 (0에서 100까지)
y_feedback = np.zeros(50) # 피드백 데이터 초기값 (0으로 초기화)
y_control_signal = np.zeros(50) # 제어 신호 데이터 초기값 (0으로 초기화)
# 그래프 초기 설정 적용
plt.xlabel('Time')
plt.ylabel('Value')
plt.title('Feedback Control with PID')
plt.legend()
plt.grid(True)
# 애니메이션 생성
def update(frame):
global integral, prev_error
# 시리얼 포트로부터 데이터 읽기
received_data = ser.readline().decode().strip()
# 데이터 출력 및 처리
print("수신된 데이터:", received_data)
if received_data:
# 주어진 데이터 형식에 따라 데이터 처리 및 업데이트
if 'Time' in received_data and 'Feedback' in received_data:
# 주파수, 피드백 값 추출
parts = received_data.split(', ')
time = float(parts[0].split(': ')[1])
feedback = float(parts[1].split(': ')[1])
control_signal = float(parts[2].split(': ')[1]) # 제어 신호를 추출
# 최근 100개 데이터 유지를 위해 데이터 이동
y_feedback[:-1] = y_feedback[1:]
y_control_signal[:-1] = y_control_signal[1:]
# PID 제어 알고리즘 계산
error = target_feedback - feedback
integral += error * dt
derivative = (error - prev_error) / dt
control_signal = Kp * error + Ki * integral + Kd * derivative
control_signal = max(control_signal, 0)
# 최신 데이터 추가
y_feedback[-1] = feedback
y_control_signal[-1] = control_signal
# 이전 오차 값 업데이트
prev_error = error
# 그래프 업데이트
line_feedback.set_data(x_data, y_feedback)
line_control_signal.set_data(x_data, y_control_signal)
return line_feedback, line_control_signal
ani = FuncAnimation(fig, update, frames=50, interval=50, blit=True)
# 그래프 표시
plt.show()
# 프로그램 종료 시 시리얼 포트 닫기
ser.close()