반응형
목차
아두이노 온도, 습도 값 파이썬으로 그래프 출력하기
앞 포스트에서 제작한 프로젝트와 동일하게 센서 없이 아두이노에서 랜덤으로 온도와 습도를 만들어서 시리얼 통신으로 보냅니다. 아두이노 코드는 아래와 같습니다.
아두이노 코드>>
void setup() {
// 시리얼 통신을 시작합니다. 보드에 맞는 속도로 설정하세요.
Serial.begin(9600);
}
void loop() {
// 가상의 온도와 습도 값을 생성합니다.
// 예를 들어, 온도는 20~30도 사이, 습도는 40~60% 사이의 값으로 설정할 수 있습니다.
float temperature = 20 + random(100) / 10.0; // 20.0 ~ 29.9 사이의 값
float humidity = 40 + random(200) / 10.0; // 40.0 ~ 59.9 사이의 값
// 시리얼 통신을 통해 온도와 습도 값을 전송합니다.
// Serial.print("온도: ");
// Serial.print(temperature);
// Serial.print(" °C, 습도: ");
// Serial.print(humidity);
// Serial.println(" %");
Serial.println(String(temperature) + "," + String(humidity));
// 0.5초 동안 대기합니다.
delay(500);
}
특정 범위의 온도와 습도를 랜덤하게 생성하고 serial 통신을 통해 , 컴마 기호로 분리해서 println으로 "\n"과 함께 전송합니다.
파이썬으로 일정 개수만 출력, 버튼으로 그래프 만들기
이번에는 Python으로 별도의 버튼을 만들고 버튼을 클릭하면 그래프가 실행되게 하겠습니다. 그리고 이전에는 그래프에 포인트들이 계속 추가되어 정보가 쌓였는데 이번에는 default로 60개의 포인트에 대한 값만 그래프로 출력하고 사용자가 text box에 숫자를 입력하면 그 숫자만큼 출력되게 만들겠습니다.
파이썬 전체 코드>>
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial
import threading
# 시리얼 포트 설정
ser = serial.Serial('COM15', 9600)
# 그래프 창 및 스레드 관리를 위한 변수
graph_window = None
thread = None
continue_reading = False
max_data_points = 60 # 초기 데이터 포인트 개수
def start_graph():
global graph_window, thread, continue_reading
if graph_window is not None:
return # 이미 그래프 창이 열려 있으면 아무것도 하지 않음
graph_window = tk.Toplevel()
graph_window.title("Arduino Temperature and Humidity Graph")
# 그래프 설정
fig, (ax1, ax2) = plt.subplots(2, 1) # 두 개의 subplot 생성
temp_line, = ax1.plot([], [], label='Temperature', color='blue')
humi_line, = ax2.plot([], [], label='Humidity', color='orange')
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
canvas = FigureCanvasTkAgg(fig, master=graph_window)
widget = canvas.get_tk_widget()
widget.pack(fill=tk.BOTH, expand=True)
continue_reading = True
# 아두이노에서 데이터 읽는 스레드 시작
def read_from_arduino():
x, y_temp, y_humi = [0], [0], [0]
while continue_reading:
try:
line = ser.readline().decode('utf-8').strip()
temperature, humidity = map(float, line.split(','))
x.append(x[-1] + 1)
y_temp.append(temperature)
y_humi.append(humidity)
# 설정된 데이터 포인트 수만큼 유지
if len(x) > max_data_points:
x = x[-max_data_points:]
y_temp = y_temp[-max_data_points:]
y_humi = y_humi[-max_data_points:]
temp_line.set_xdata(x)
temp_line.set_ydata(y_temp)
humi_line.set_xdata(x)
humi_line.set_ydata(y_humi)
ax1.relim()
ax1.autoscale_view()
ax2.relim()
ax2.autoscale_view()
canvas.draw()
except ValueError:
pass
thread = threading.Thread(target=read_from_arduino)
thread.daemon = True
thread.start()
def close_graph():
global graph_window, continue_reading
continue_reading = False
if graph_window is not None:
graph_window.destroy()
graph_window = None
def update_data_points():
global max_data_points
try:
max_data_points = int(data_points_entry.get())
except ValueError:
print("Please enter a valid integer for data points.")
# 메인 윈도우 설정
root = tk.Tk()
root.title("Arduino Data Viewer")
# 시작 버튼
start_button = tk.Button(root, text="Start Graph", command=start_graph)
start_button.pack()
# 종료 버튼
close_button = tk.Button(root, text="Close Graph", command=close_graph)
close_button.pack()
# 데이터 포인트 설정
data_points_label = tk.Label(root, text="Set Data Points:")
data_points_label.pack()
data_points_entry = tk.Entry(root)
data_points_entry.pack()
data_points_button = tk.Button(root, text="Set", command=update_data_points)
data_points_button.pack()
root.mainloop()
주석>>
def read_from_arduino():
지속적으로 아두이노에서 값을 읽어와야 하기 때문에 threading으로 동작합니다.
global graph_window, thread, continue_reading
함수 외부에서 영향을 주는 변수 들로 global로 관리 합니다.
결과>>
코드 다운로드
파이썬 코드 다운로드>>
반응형
'아두이노 Arduino > 파이썬(Python)' 카테고리의 다른 글
아두이노 온도, 습도 값 파이썬으로 그래프 출력 - 커서 값 출력하기(Arduino, Cursor, Python, Cordination, graph) (0) | 2024.01.25 |
---|---|
아두이노 온도, 습도 값 파이썬으로 그래프 출력하기(Arduino, Python, Serial, Graph) (1) | 2024.01.14 |
Ping이란? CMD, 파이썬으로 예제 실습하기(Window OS) (2) | 2023.12.20 |
[Python] 파이썬 실행파일(exe) 만들기(Pyinstaller, Batch file) (0) | 2022.11.14 |
[아두이노] 파이썬 threading timer 로 주기적으로 LED 켜고 끄기(타이머, 인터럽트, Interrupt) (0) | 2022.05.18 |