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()



댓글(0) 먼댓글(0) 좋아요(0)
좋아요
공유하기 북마크하기찜하기