파이톤을 사용하여 온도 데이터 수집


내가 업무 중에 클라우드를 더욱 쉽게 사용할 수 있고 강하게 만들 수 있는 방법을 생각할 때, 나는 하드웨어 공학 학위를 공부하기 시작했다.나는 대학에서 대부분의 시간을 자석과 전장 사이의 갈등을 해결하고 물리를 이해하기 위해 VHDL을 썼다.즉, 대학에 입학한 이래로 나의 하드웨어 기능이 크게 떨어졌다.내가 증명할 수 있는 것은 단지 아무도 살 수 없는 책들뿐이다.그러니 RC 회로에 대해 묻지 마세요.
그래도 나는 세계 사이에 다리를 놓는 것을 좋아한다.최근에 이것은 보통 마이크로파이톤이나 CircuitPython (하드웨어에 따라) 를 통해 이루어진다.이것은 쉽게 접근할 수 있는 방법으로 내가 당시에 겪었을 수 있는 어떤 문제를 해결하는 데 있어서도 매우 낮은 문턱이다.나는 이 널빤지를 책상 위에 놓고 나를 비웃는 것을 좋아한다. "야, 무슨 일이 있어?"
나의 최근 실험은 온도에 관한 것이다.비록 나는 시애틀에 살고 있지만, 그곳의 온도는 보통 비교적 안정적이지만, 겨울에는 확실히 차가워진다.내 지하실에는 에어컨이 있지만, 나는 통풍구를 닫았다. 왜냐하면 그것은 주로 저장실과 세탁실이기 때문이다.나도 적당한 포도주를 소장하고 있는데, 포도주는 시원한 온도를 더욱 좋아한다.근데 멋있어요?너무 춥지 않아요?온도 변화가 얼마나 됩니까?내가 수중에 가지고 있는 몇 가지 물건으로 이 문제를 해결할 수 있습니까?
내 주위의 회로판에는 온도 센서가 포함되어 있기 때문에 Circuit Playground Express가 좋은 선택인 것 같다.
Circuit Playerd Express를 사용하면 온도 센서를 쉽게 읽을 수 있습니다.
import time
from adafruit_circuitplayground.express import cpx
while True:
    temperature = cpx.temperature * 1.8 + 32
    print("Temperature F: {}".format(temperature))
    time.sleep(1)

그렇습니다.연속 순환 중 cpx.temperature 읽히고 섭씨도에서 (미국 때문) 전환한 다음 컨트롤러로 출력됩니다.Serial 모니터에 연결하면 결과를 볼 수 있습니다.만약 당신이 이것에 익숙하지 않다면, 내장된 직렬 디버깅은 설정하기 쉽기 때문에 Mu Code을 보시기를 권장합니다.
그래서 나는 회로판으로 실온 데이터를 얻을 수 있다는 개념이 증명되었다.비록 나의 특정한 용례에 대해서 나는 좀 더 진일보한 일을 하고 싶다.
  • 며칠 동안 온도를 추적하고 싶습니다.그래서 1초에 한 번씩 너무 잦아요.반대로 나는 매 분마다 업데이트를 받는다.
  • 이사회에서 자신의 상태를 조금 전달할 수 있었으면 좋겠다.예를 들어 오류가 발생하거나 센서가 보고한 온도입니다.그래서 나는 NeoPixel LED를 설정해서 서로 다른 모드를 표시해서 서로 다른 상태를 표시하고 싶다.
  • 회로판을 컴퓨터에 꽂고 싶지 않아요.나는 그것이 전기가 통할 때 조용히 하고 잠시 후에 데이터를 수집할 수 있기를 바란다.
  • 보고된 온도는 합리적이지만 내 항온기보다 조금 높다.나는 실제 실온을 반영하기 위해 결과를 약간 조정해야 한다고 예상한다.
  • LED를 통해 보드 상태 보고



    마이크로 컨트롤러를 사용하는 어려움 중 하나는 컨트롤러나 모니터가 부족한 것일 수도 있다.다만, 서킷 플레이어드 익스프레스에는 네오픽스(Neopix·상태 LED 1개)가 10개 있어 소량의 정보를 전달할 수 있는 방법이 있다.이 항목에 대해 문제(이상)가 생겼는지, 읽는 온도가 얼마나 되는지 아는 것이 좋다.
    이것은 실내에서 사용하기 때문에, 나는 내가 50화씨보다 낮거나 95화씨도를 넘는 온도를 읽을 것이라고 생각하지 않는다.따라서 5F가 증가할 때마다 회로판에 별도의 LED가 빛을 발한다.

    def color_temperature(temp):
        # Use Neopixels to show temperature,
        # incrementally lighting up another NeoPixel
        # add a light for each extra 5 degrees
        # 50 (0), 55 (1), 60 (2), 65 (4), 70 (5),
        # 75 (6), 80 (7), 85 (8), 90 (9), 95 (10)
    
        # turn all off first
        cpx.pixels.fill((0,0,0))
    
        temp = int(temp) - 50
        leds_on = min(temp / 5, 10)
        print(leds_on)
        for i in range(leds_on):
            print(i)
            cpx.pixels[i] = color.HEAT_COLORS[i]
        cpx.pixels.show()
    
    

    데이터를 저장할 수 있도록 Circuit Playery Express를 구성합니다.


    직렬 모니터가 없는 상태에서 장치를 사용하기 위해서는 소량의 데이터를 장치에 저장할 수 있어야 한다.Adafruit에서 회로 놀이터가 있는 메모리를 어떻게 사용하는지에 대한 완전한 지침이 있지만, 높은 단계에서 내장된 다이얼 스위치는 USB(개발용)인지 code.py의 코드(데이터 포획용)를 통해 쓰는지 확인하는 데 사용될 수 있다.boot.py에 포함된 코드를 실행하기 전에 code.py에 메모리 상태를 초기화하기 위해 코드를 한 소절 써야 한다
    # Contents of boot.py
    import board
    import digitalio
    import storage
    
    switch = digitalio.DigitalInOut(board.D7)
    switch.direction = digitalio.Direction.INPUT
    switch.pull = digitalio.Pull.UP
    
    # If the D7 is switched on (towards B button),
    # CircuitPython can write to storage
    storage.remount("/", switch.value)
    
    
    boot.py를 보드에 저장한 후 회로를 재설정합니다.현재 code.py 는 cpx에 기록할 수 있습니다.스위치가 False로 설정됩니다.그렇지 않으면 프로그램이 데이터를 저장하지 않았음을 표시하기 위해 LED를 깜박이는 코드가 있습니다.
    # If Switch is to left, we aren't in write mode, flash yellow LEDs to warn
    if cpx.switch:
        cpx.pixels.fill(color.YELLOW)
        cpx.pixels.show()
    else:
        with open("/temperatures.txt", "a") as f:
            f.write("{}, {}\n".format(temperature, time_from_start))
    
    
    모든 섹션을 함께 배치하여 얻은 code.py 파일은 다음과 같습니다.
    import time
    
    from adafruit_circuitplayground.express import cpx
    
    # Turn down LED brightness as 1 is *very* bright
    cpx.pixels.brightness = 0.02
    
    # Configure NeoPixel state to update on show()
    cpx.pixels.auto_write = False
    
    class color:
        RED = (255,0,0)
        YELLOW = (255,255,0)
        HEAT_COLORS = [
            (255, 255, 0),
            (255, 255, 0), # YELLOW
            (255, 150, 0),
            (255, 150, 0), # YELLOWORANGE)
            (255, 100, 0),
            (255, 100, 0), # ORANGE
            (255, 50, 0),
            (255, 50, 0), # REDORANGE
            (255, 0, 0),
            (255, 0, 0), # RED
        ]
    
    def color_temperature(temp):
        # Use Neopixels to show temperature,
        # incrementally lighting up another NeoPixel
        # add a light for each extra 5 degrees
        # 50 (0), 55 (1), 60 (2), 65 (4), 70 (5),
        # 75 (6), 80 (7), 85 (8), 90 (9), 95 (10)
    
        # turn all off first
        cpx.pixels.fill((0,0,0))
    
        temp = int(temp) - 50
        leds_on = min(temp / 5, 10)
        print(leds_on)
        for i in range(leds_on):
            print(i)
            cpx.pixels[i] = color.HEAT_COLORS[i]
        cpx.pixels.show()
    
    # time.monotonic() allows for non-blocking LED animations!
    time_from_start = 0
    start = time.monotonic()
    while True:
        now = time.monotonic()
    
        # Display a red led when switch is to the left.
        cpx.red_led = cpx.switch
    
        temperature = cpx.temperature * 1.8 + 32
        print("Temperature F: {} t: {}".format(temperature, time_from_start))
    
        # If Switch is to left, we aren't in write mode, flash yellow LEDs to warn
        if cpx.switch:
            cpx.pixels.fill(color.YELLOW)
            cpx.pixels.show()
    
            color_temperature(temperature)
    
            # Blink yellow lights every second.
            time_from_start += 1
            time.sleep(1)
        else:
            try:
                with open("/temperatures.txt", "a") as f:
                    f.write("{}, {}\n".format(temperature, time_from_start))
                color_temperature(temperature)
                cpx.pixels.show()
            except OSError as ex:
                print("Cannot write while connected to pc: {}".format(ex))
                cpx.pixels.fill(color.RED)
                cpx.pixels.show()
    
            # Wait 60 seconds before recording the next temperature update.
            time_from_start += 60
            time.sleep(60)
    
    
    위 코드를 실행하면 온도 및 시간 오프셋의 CSV가 표시됩니다.
    74.5162, 0
    73.3791, 60
    72.8705, 120
    72.4798, 180
    72.3626, 240
    
    

    온도를 조정하다.



    앞에서 말한 바와 같이 회로판의 온도 센서와 실제 온도는 약간 차이가 있다.다행히도, 나는 양호한 온도계를 가지고 있다.비록 편차가 선형이라는 것은 보장할 수 없지만, 나는 그것이 선형이라고 가정할 것이다. 왜냐하면 초보적인 데이터로 볼 때 온도의 변화가 현저하지 않기 때문이다.데이터 수집을 멈추기 전에, 나는 우주에 물을 담을 용기를 남겨 놓고 그것을 측정했다.내가 이 사진을 찍었을 때, 온도 센서가 71.97화씨도를 나타냈고, 내가 교정한 온도계는 64.8화씨도를 나타냈다.회로판의 온도는 약 7.2화씨도이다.

    데이터를 보다


    수집된 데이터를 처리하는 것은 매우 간단합니다. 주로 Python 라이브러리와 matplotlib을 내장하여 완성할 수 있습니다.데이터가 CSV로 저장되므로 CSV 리더를 사용할 수 있습니다.줄마다 소량의 처리를 하고 교준 후 온도치를 이동하며 시간 증가량을 날짜 시간으로 전환해야 한다. 채집부터 계산하기 때문에 초보다 추리하기 쉽기 때문이다.

    from datetime import datetime, timedelta
    import csv
    
    import matplotlib.pyplot as plt
    import datetime
    
    start_time = datetime.datetime(2020, 11, 12, 17, 32)
    
    times = []
    temperatures = []
    
    with open("temperatures.txt") as f:
        reader = csv.reader(f, delimiter=',')
        for temperature, time_offset in reader:
            # Reported temperature of 71.9724 recorded as 64.8F
            # Offset temperatures by 7.2F
            temperature_adjusted = float(temperature) - 7.2
            temperatures.append(float(temperature_adjusted))
            t = start_time + timedelta(seconds=int(time_offset))
            times.append(t)
    
    plt.plot(times, temperatures)
    plt.ylabel('Temperature')
    plt.xlabel('Time')
    plt.grid(True)
    
    plt.savefig("temperatures.png")
    
    

    요약


    그럼, 내가 뭘 발견했지?비록 나의 지하실은 본관보다 시원하지만, 그것은 술 저장소에서 매우 멀다.그러나 얼어 죽을 위험은 없다.나는 이와 같은 문제에 기술적 함량이 비교적 낮은 해결 방안이 있다는 것을 인정해야 한다.나는 온도계를 이 방에 한동안 두고 정기적으로 검사할 수 있었지만, 이것은 나로 하여금 Circuit Python과 Circuit Playerd Express를 사용하여 메모리에 데이터를 쓰는 것을 탐색할 기회를 주지 못했다.때때로 이것이 이런 마이크로 컨트롤러의 즐거움이다.이것이 바로 내가 그것들을 책상 위에 놓은 이유이다.나를 어리석은 짓을 하도록 유혹하다.
    최초 2020년 11월 17일 발표https://chriswilcox.dev

    좋은 웹페이지 즐겨찾기