아두이노 Arduino/파이썬(Python)

아두이노 온도, 습도 값 파이썬으로 그래프 출력하기(Arduino, Python, Serial, Graph)

끄적끄적아무거나 2024. 1. 14. 21:29
반응형

 

목차

     

     

     

     

    아두이노 온도, 습도 값 파이썬으로 그래프 출력하기#1

    우선 제가 가지고 있는 것이 아두이노 보드 밖에 없기 때문에 센서 없이 임의로 데이터를 만들어서 온도와 습도 값을 생성하겠습니다.

     

    아두이노 코드>>

    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 통신을 통해 , (컴마) 기호로 구분되어 전송됩니다.

     

      Serial.print("온도: ");
      Serial.print(temperature);
      Serial.print(" °C, 습도: ");
      Serial.print(humidity);
      Serial.println(" %");

     

    위 부분은 주석 처리했는데 아두이노 serial monitor로 직접 확인하고 싶으시면 사용하시면 됩니다.

     

     

     

     

     

     

    아두이노 온도, 습도 값 파이썬으로 그래프 출력하기#2

     

    다음으로 파이썬 코드를 사용해서 시리얼 통신으로 입력 받은 값을 그래프로 출력 해보겠습니다.

     

    코드>>

    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) 
    
    # 데이터를 읽어서 그래프에 추가하는 함수
    def read_from_arduino():
        while True:
            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)
                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
    
    # GUI 설정
    root = tk.Tk()
    root.title("Arduino Temperature and Humidity")
    
    # 그래프 설정
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    x, y_temp, y_humi = [0], [0], [0]  # 초기값 설정
    
    temp_line, = ax1.plot(x, y_temp, label='Temperature', color='blue')
    humi_line, = ax2.plot(x, y_humi, label='Humidity', color='orange')
    ax1.legend(loc='upper left')
    ax2.legend(loc='upper right')
    
    canvas = FigureCanvasTkAgg(fig, master=root)
    widget = canvas.get_tk_widget()
    widget.pack(fill=tk.BOTH, expand=True)
    
    # 아두이노에서 데이터 읽는 스레드 시작
    thread = threading.Thread(target=read_from_arduino)
    thread.daemon = True
    thread.start()
    
    root.mainloop()

     

     

    주석>>

     

    혹시 처음 serial을 실행하면서 아래와 같은 에러 메세지가 발생했다면

    AttributeError: module 'serial' has no attribute 'Serial'

     

    아래와 같이 설치를 진행해주세요.

    pip install pyserial

     

     

    ser = serial.Serial('COM15', 9600)

     

    시리얼 포트 번호를 통해 아두이노에 연결된 포트 번호를 입력합니다. 저는 COM15에 연결되어 있어서 COM15로 설정하였습니다. 

     

    line = ser.readline().decode('utf-8').strip()

     

    들어온 byte 값을 utf-8 인코딩 방식으로 문자열로 바꿔 줍니다. strip으로 공백 등을 제거 해줍니다. 

     

                temp_line.set_xdata(x)
                temp_line.set_ydata(y_temp)
                humi_line.set_xdata(x)
                humi_line.set_ydata(y_humi)

     

    set_xdata, ydata를 통해서 값을 지속적으로 업데이트 합니다.

     

     

                ax1.relim()
                ax1.autoscale_view()
                ax2.relim()
                ax2.autoscale_view()

     

    들어온 값에 맞춰서 축의 범위를 autoscale 해줍니다.

     

     

     

     

    결과>>

     

     

     

    코드 다운로드>>

    rnd_temp_humid.ino
    0.00MB
    test01.py
    0.00MB

     

     

     

     

    반응형