목차(클릭하세요)
파이파이키트 자체가 센서, 엑츄에이터가 이미 연결되어 있으므로 핀맵 정보 필요
실시간 정보를 받아 시간대별 센서 정보를 저장하는 작업은 상당한 난이도 필요
실시간 정보를 받아 시간대별 센서 정보를 저장하는 작업은 상당한 난이도 필요1. 센서(Sensor) 핀 연결 정보(4개)
1-1. 터치 센서, 컬러인식 센서, 온습도 센서, 조도센서
센서명 | 센서 종류 | 통신 방식 | GPIO 핀 | 기능 설명 |
터치 센서 1번 | 디지털 입력 | GPIO | D33 (S핀) | 터치 버튼 감지 |
터치 센서 2번 | 디지털 입력 | GPIO | D32 (S핀) | 터치 버튼 감지 |
터치 센서 3번 | 디지털 입력 | GPIO | D35 (S핀) | 터치 버튼 감지 |
터치 센서 4번 | 디지털 입력 | GPIO | D34 (S핀) | 터치 버튼 감지 |
컬러 인식 센서 | TCS34725 | I2C | SDA: D21, SCL: D22 | RGB 색상 측정 |
온습도 센서 | DHT11 | 디지털 | D27 (S핀) | 온도/습도 측정 |
조도센서 | Cds | 아날로그 입력 (ADC) | D4 (S핀) | 빛 밝기 측정
0~4095 (연속값) |
1-2.특이점
•
컬러인식 센서는 I2C통신 방식 사용
I2C통신 방식•
2개 핀(SDA, SCL)으로 여러 센서 제어 가능
•
SDA (Serial Data): D21
•
SCL (Serial Clock): D22
•
여러 센서를 체인 형태로 연결 가능 (주소 다름)
2. 액추에이터(Actuator) 핀 연결 정보(3개)
액추에이터명 | 액추에이터 종류 | 통신 방식 | GPIO 핀 | 기능 설명 |
네오픽셀 LED 링 | WS2812B | 1-Wire (단일선) | D14 (S핀) | RGB LED 제어 |
OLED 디스플레이 | SSD1306 | I2C | SDA: D21, SCL: D22 | 화면 출력 |
내장ED | 디지털 출력 | GPIO | D2: 2번핀 | 보드 상태 표시 (ON/OFF 제어)로 주로 활용 |
3. 센서&엑추에이터 기본 연결 코드
3-1. 목적
•
터치 센서, 컬러인식 센서, 온습도 센서, 조도센서와 액추에이터(Actuator) 핀이 모두 잘 연결되어 작동하는지 체크하는 일종의 체크코드
"""
파이파이 IoT 보드 - 하드웨어 핀 연결 순차 체크 코드
각 센서와 액추에이터를 단계별로 확인
"""
from machine import Pin, ADC, SoftI2C
from neopixel import NeoPixel
import time
def print_step(step_num, title):
"""단계 제목 출력"""
print("\n" + "=" * 50)
print(f"STEP {step_num}: {title}")
print("=" * 50)
def print_result(name, status, message=""):
"""결과 출력"""
emoji = "✅" if status else "❌"
print(f"{emoji} {name}: {message}")
# ============================================
# STEP 1️⃣: 터치센서 확인 (사용자 입력 대기)
# ============================================
print_step(1, "터치센서 확인")
print("터치센서(1번~4번) 중 하나를 터치하면 다음 단계로 이동합니다.")
print("(최대 10초 대기)")
touch_pins = {
"터치1": Pin(33, Pin.IN),
"터치2": Pin(32, Pin.IN),
"터치3": Pin(35, Pin.IN),
"터치4": Pin(34, Pin.IN),
}
# 터치센서 상태 확인
touch_detected = False
start_time = time.time()
timeout = 10 # 10초 타임아웃
while not touch_detected and (time.time() - start_time) < timeout:
for name, pin in touch_pins.items():
if pin.value() == 1:
print_result(name, True, "터치 감지됨!")
touch_detected = True
break
time.sleep(0.1)
if not touch_detected:
print_result("터치센서", False, "10초 이상 반응 없음 (타임아웃)")
print("⚠️ 터치센서 연결을 확인하고 다시 시도하세요.")
else:
print_result("터치센서", True, "정상 작동")
time.sleep(1)
# ============================================
# STEP 2️⃣: 조도센서 확인
# ============================================
print_step(2, "조도센서 확인")
try:
light_sensor = ADC(Pin(4))
light_sensor.atten(ADC.ATTN_11DB)
# 5번 측정하여 평균값 출력
light_values = []
print("조도값 측정 중... (5회)")
for i in range(5):
value = light_sensor.read()
light_values.append(value)
print(f" 측정 {i+1}: {value}/4095", end="")
# 밝기 상태 표시
if value > 3500:
print(" (매우 밝음 ☀️)")
elif value > 2000:
print(" (밝음 💡)")
elif value > 1000:
print(" (어두움 🌙)")
else:
print(" (매우 어두움 🌑)")
time.sleep(0.3)
avg_light = sum(light_values) // len(light_values)
print_result("조도센서", True, f"평균값: {avg_light}/4095")
time.sleep(1)
except Exception as e:
print_result("조도센서", False, f"오류 - {e}")
# ============================================
# STEP 3️⃣: 컬러인식센서 확인
# ============================================
print_step(3, "컬러인식센서 확인")
try:
# I2C 통신 확인
i2c = SoftI2C(sda=Pin(21), scl=Pin(22))
devices = i2c.scan()
if devices:
print_result("I2C 통신", True, "정상")
# 발견된 디바이스 주소 출력
for device in devices:
device_name = f"TCS34725 (컬러센서)" if device == 0x29 else "기타 I2C 디바이스"
print(f" └─ 발견: 0x{device:02x} ({device_name})")
# TCS34725 라이브러리가 있으면 색상값 출력 시도
try:
from tcs34725 import TCS34725
tcs = TCS34725(i2c)
print("\n컬러값 측정 중... (3회)")
for i in range(3):
rgb = tcs.read('rgb')
r, g, b = rgb[0], rgb[1], rgb[2]
print(f" 측정 {i+1}: R={r}, G={g}, B={b}")
time.sleep(0.5)
print_result("컬러센서", True, "정상 작동 (RGB값 측정 완료)")
except ImportError:
print("⚠️ tcs34725 라이브러리가 없어 상세 측정 불가")
print(" (하지만 I2C 통신은 정상입니다)")
print_result("컬러센서", True, "I2C 연결됨 (라이브러리 필요)")
else:
print_result("컬러센서", False, "I2C에서 디바이스 미발견")
print("⚠️ 케이블 연결을 확인하세요.")
time.sleep(1)
except Exception as e:
print_result("컬러센서", False, f"오류 - {e}")
# ============================================
# STEP 4️⃣: 온습도센서 확인
# ============================================
print_step(4, "온습도센서 I2C 확인")
try:
dht_pin = Pin(27, Pin.IN)
dht_value = dht_pin.value()
if dht_value in [0, 1]:
print_result("온습도센서", True, f"GPIO 응답 정상 (현재값: {dht_value})")
print(" └─ 정확한 온습도 값은 DHT11 라이브러리로 측정 가능")
else:
print_result("온습도센서", False, "GPIO 응답 이상")
time.sleep(1)
except Exception as e:
print_result("온습도센서", False, f"오류 - {e}")
# ============================================
# STEP 5️⃣: 네오픽셀 LED 확인
# ============================================
print_step(5, "네오픽셀 LED 확인")
try:
np = NeoPixel(Pin(14), 12)
# 빨강
print("네오픽셀 색상 변화 중...")
for i in range(12):
np[i] = (255, 0, 0) # 빨강
np.write()
print(" 1️⃣ 빨강 점등 (1초)")
time.sleep(1)
# 초록
for i in range(12):
np[i] = (0, 255, 0) # 초록
np.write()
print(" 2️⃣ 초록 점등 (1초)")
time.sleep(1)
# 파랑
for i in range(12):
np[i] = (0, 0, 255) # 파랑
np.write()
print(" 3️⃣ 파랑 점등 (1초)")
time.sleep(1)
# OFF
for i in range(12):
np[i] = (0, 0, 0) # 검정(OFF)
np.write()
print(" 4️⃣ OFF 상태 (소등)")
print_result("네오픽셀 LED", True, "정상 작동 (RGB 모두 정상)")
time.sleep(1)
except Exception as e:
print_result("네오픽셀 LED", False, f"오류 - {e}")
# ============================================
# STEP 6️⃣: OLED 디스플레이 I2C 확인
# ============================================
print_step(6, "OLED 디스플레이 I2C 확인")
try:
# I2C 재스캔
i2c = SoftI2C(sda=Pin(21), scl=Pin(22))
devices = i2c.scan()
oled_found = False
for device in devices:
# OLED는 일반적으로 0x3c 또는 0x3d 주소
if device in [0x3c, 0x3d]:
print_result("OLED", True, f"I2C 주소 0x{device:02x}에서 발견됨")
oled_found = True
break
if not oled_found:
if devices:
print("⚠️ OLED 미발견 (예상 주소: 0x3c 또는 0x3d)")
print(f" 발견된 I2C 디바이스: {[hex(d) for d in devices]}")
print_result("OLED", False, "예상 주소에서 미발견")
else:
print_result("OLED", False, "I2C 통신 불가")
except Exception as e:
print_result("OLED", False, f"오류 - {e}")
# ============================================
# 🎯 최종 체크 완료
# ============================================
print("\n" + "=" * 50)
print("🎯 모든 단계 완료!")
print("=" * 50)
print("""
✅ 라이브러리 설치가 필요한 센서, 엑츄에이터는 라이브러리를 설치
""")
Python
복사
3-2.조도센서 실습
•
현재 조도센서 값 측정하기
[주의] 파이파이 키트의 조도 센서는 4번 핀에 연결되어 있으며, 아날로그 신호를 읽어오기 위해 ADC 클래스를 사용
ESP32는 기본적으로 1.0V~1.1V까지만 측정할 수 있으므로, 3.3V 전압을 사용하는 센서 값을 제대로 읽으려면 감쇠(Attenuation) 설정을 반드시 해야 함
from machine import Pin, ADC
import time
# 1. 조도 센서 객체 생성 (4번 핀)
# 파이파이 키트의 조도 센서는 GPIO 4번에 연결됨
cds = ADC(Pin(4))
# 2. 감쇠(Attenuation) 설정: 11dB
# ESP32는 기본적으로 0~1.1V까지만 측정 가능
# 3.3V 범위까지 읽기 위해 ATTN_11DB 설정을 사용
cds.atten(ADC.ATTN_11DB)
print(">>> 조도 센서 측정 시작 (Ctrl+C로 종료)")
while True:
# 3. 아날로그 값 읽기 (0 ~ 4095)
# 0에 가까울수록 어둡고, 4095에 가까울수록 밝은 상태(회로 구성에 따라 반대일 수 있음).
val = cds.read()
print(f"현재 밝기 값: {val}")
time.sleep(0.5) # 0.5초 대기
Python
복사
감쇠란?
전압을 깎아서(감쇠시켜서) ADC가 읽을 수 있는 범위로 맞추는 설정
감쇠가 클수록 더 높은 전압을 측정할 수 있지만, 정밀도는 조금 떨어질 수 있음
전압을 깎아서(감쇠시켜서) ADC가 읽을 수 있는 범위로 맞추는 설정
감쇠가 클수록 더 높은 전압을 측정할 수 있지만, 정밀도는 조금 떨어질 수 있음•
ESP32의 ADC 감쇠 기능은 입력 전압의 측정 범위를 결정
•
왜 필요한가? ESP32의 ADC는 기본적으로 약 1.1V가 넘어가면 최대값(4095)으로 포화(Saturated)되어 측정이 불가능
•
결국 3.3V 센서를 쓰려면 범위를 늘려야 함!
설정값 (상수) | 감쇠율 | 측정 가능 전압 범위 (약) | 용도 |
ADC.ATTN_0DB | 0dB | 0V ~ 1.1V | 매우 낮은 전압의 정밀 측정 |
ADC.ATTN_2_5DB | 2.5dB | 0V ~ 1.5V | 1.5V 이하 센서 |
ADC.ATTN_6DB | 6dB | 0V ~ 2.0V | 2.0V 이하 센서 |
ADC.ATTN_11DB | 11dB | 0V ~ 3.3V (3.6V Max) | 대부분의 3.3V 센서 (조도 등) |
ATTN_0DB (기본값)
├─ 장점: 정확도가 가장 높음
├─ 단점: 0~1.1V 범위만 측정 가능
└─ 용도: 정확한 저전압 센서 측정 (온도센서, 압력센서 등)
ATTN_2_5DB
├─ 장점: 정확도 유지, 약간 더 넓은 범위
├─ 단점: 0~1.5V 범위 제한
└─ 용도: 중간 전압 센서
ATTN_6DB
├─ 장점: 더 넓은 범위 (0~2.2V)
├─ 단점: 정확도 약간 감소
└─ 용도: 0~2.2V 범위의 센서
ATTN_11DB (권장) 

├─ 장점: ESP32의 최대 범위(3.3V) 전체 사용 가능
├─ 단점: 정확도가 조금 떨어짐 (±12bit 해상도)
└─ 용도: 다양한 센서 (조도센서, 가변저항, 배터리 전압 등)
3-3.조도센서 실습 with 감쇠
•
같은 밝기(전압)라도 감쇠 설정에 따라 읽히는 숫자가 달라지거나 최대값(4095)에 막히는 현상을 확인할 수 있음
from machine import Pin, ADC
import time
# 조도 센서 핀 설정
sensor_pin = Pin(4)
adc = ADC(sensor_pin)
# 테스트할 감쇠 설정 리스트
atten_modes = [
(ADC.ATTN_0DB, "0dB (0~1.1V)"),
(ADC.ATTN_2_5DB, "2.5dB (0~1.5V)"),
(ADC.ATTN_6DB, "6dB (0~2.0V)"),
(ADC.ATTN_11DB, "11dB (0~3.3V)")
]
print(">>> ADC 감쇠 설정별 값 비교 테스트 <<<")
while True:
print("-" * 40)
for mode, desc in atten_modes:
# 감쇠 설정 변경
adc.atten(mode)
time.sleep(0.1) # 설정 적용 대기
# 값 읽기
val = adc.read()
# 결과 출력 (4095가 나오면 측정 범위를 초과한 것임)
status = " (최대값 포화!)" if val >= 4095 else ""
print(f"설정: {desc:<15} | 측정값: {val}{status}")
print("-" * 40)
print("센서 밝기를 변화시켜 보기, 탈출은 ctrl+c")
time.sleep(2)
Python
복사
3-4.조도센서 측정값을 시각화 하기
•
Thonny 개발 환경에서 ESP32 자체적으로 matplotlib 라이브러리를 직접 import하여 사용하는 것은 불가능
◦
matplotlib은 컴퓨터(PC)의 운영체제 위에서 돌아가는 무거운 라이브러리이며, 마이크로컨트롤러인 ESP32의 메모리와 연산 능력으로는 구동할 수 없기 때문
[해결책] Thonny의 내장 'Plotter' 기능
•
이를 위해 코드 일부를 수정
[핵심]
•
출력하고 싶은 값들을 튜플 (값1, 값2) 형태로 print() 하면 자동으로 그래프가 그려짐
•
감쇠(Attenuation) 설정에 따른 차이를 한 눈에 보기 위해 4가지 감쇠 설정 값을 한방에 출력
from machine import Pin, ADC
import time
# 조도 센서 (4번 핀)
cds = ADC(Pin(4))
# 감쇠 설정 상수 리스트
attens = [ADC.ATTN_0DB, ADC.ATTN_2_5DB, ADC.ATTN_6DB, ADC.ATTN_11DB]
print("Plotter 시작: 4가지 감쇠 모드 값을 동시에 출력합니다.")
while True:
# values라는 빈 리스트 설정
values = []
# 4가지 감쇠 설정을 순서대로 빠르게 변경하며 측정
for atten_mode in attens:
cds.atten(atten_mode)
time.sleep_ms(20) # 설정 변경 후 안정화 대기
# 측정된 값을 리스트에 추가
values.append(cds.read())
# 튜플 형태로 묶어서 출력 -> Thonny 플로터가 이를 인식해 4개의 선으로 그림
# 출력 형식 예: (150, 400, 1200, 3500)
print(tuple(values))
time.sleep(0.1)
Python
복사
•
시각화 확인하기: 상단 메뉴에서 [보기(View)] -> **[플로터(Plotter)]**를 선택
4.측정된 값 저장하기
4-1. [간편]엑셀 시트에 저장하기
•
가장 간편한 방법
1.
장점: 초간편, 이보다 더 간편한 코드는 없을 듯
from machine import Pin, ADC
import time
# 1. 조도 센서 설정 (4번 핀) [4]
cds = ADC(Pin(4))
cds.atten(ADC.ATTN_11DB) # 3.3V 범위까지 측정
# 2. CSV 파일 저장 함수 정의 [2], [3]
def save_to_csv(filename, data):
print("파일 저장 중...")
# 'w' 모드는 쓰기 전용으로 파일을 엽니다. [5]
with open(filename, 'w') as csvfile:
# 엑셀 헤더(제목) 작성
csvfile.write("Time(s),Light_Value\n")
# 데이터 한 줄씩 작성
for row in data:
# 콤마(,)로 값을 구분하여 저장합니다. [6]
csvfile.write("{},{}\n".format(row, row))
print(f"{filename} 저장 완료!")
# 3. 데이터 수집 시작
data_list = []
print(">>> 측정 시작 (10회 측정)")
for i in range(1, 11): # 10번만 측정 예시
val = cds.read()
print(f"측정 {i}: {val}")
# (시간, 조도값) 형태로 리스트에 추가
data_list.append((i, val))
time.sleep(1)
# 4. 파일로 내보내기
save_to_csv("light_data.csv", data_list)
Python
복사
2.
파일 확인 방법
•
코드가 실행되고 "저장 완료" 메시지가 뜨면,
•
Thonny IDE 왼쪽 파일 탐색기에서 MicroPython 장치 를 새로 고침한 다음 **light_data.csv**를 찾아 다운로드
[csv 결과물 확인]
3.
단점
•
메모리 부족 (Memory Error) 위험: 현재 코드는 측정된 모든 데이터를 data_list라는 리스트 변수에 계속 쌓아두었다가, 마지막에 한 번에 파일로 저장
•
ESP32와 같은 마이크로컨트롤러는 RAM(메모리) 용량이 매우 제한
•
만약 측정 횟수가 10회가 아니라 1,000회, 10,000회로 늘어나면 data_list의 크기가 메모리 한계를 초과하여 MemoryError가 발생하고 보드가 멈출 수 있음
•
문제점: 실제 루프의 실행 시간은 **센서 읽는 시간 + 출력하는 시간 + 리스트에 추가하는 시간 + 1초 대기**가 됨
◦
따라서 실제로는 1.01초, 1.05초 처럼 조금씩 밀리게 되며, 시간이 지날수록 오차(Drift)가 누적되어 정확한 시계열 데이터를 얻기 불가능해짐
◦
해결: time.ticks_ms() 등을 활용하여 경과 시간을 계산해 보정하거나 타이머 인터럽트를 사용
•
실제 시간(Real Time) 기록 불가: 현재 코드는 단순히 i (횟수)를 시간으로 기록
◦
문제점: 데이터가 "언제" 측정되었는지(예: 2023-10-27 14:30:00) 알 수 없음
◦
해결: ESP32는 전원이 꺼지면 시간이 초기화되므로, 정확한 기록을 위해서는 Wi-Fi로 NTP 서버에서 시간을 받아오거나 RTC(Real Time Clock) 모듈을 설정해야 함!
4.
개선된 코드
[주의] 즉시실행방식이 아닌 Main.py형태로 저장하여 실행해야 함!
이경우 main.py파일을 저장한 뒤 ESP32본체의 리셋버튼을 한번 꼭 눌러주어야 실행 됨을 잊지말자!from machine import Pin, ADC, RTC
import network
import ntptime
import time
# ===== [설정 영역] =====
FILENAME = "smart_log.csv"
SSID = "???"
PASSWORD = " ??? "
MEASUREMENT_TIME = 30 # 측정 시간 (초)
INTERVAL = 1000 # 측정 간격 (밀리초)
FLUSH_RATE = 10 # 10회마다 저장소에 완전 기록
# ===== [WiFi 연결 + NTP 시간 동기화] =====
def setup_time():
"""WiFi 연결 및 NTP 시간 동기화 (UTC+9)"""
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print("[WiFi] 연결 중...")
wlan.connect(SSID, PASSWORD)
timeout = 10
while not wlan.isconnected() and timeout > 0:
time.sleep(0.5)
timeout -= 1
if wlan.isconnected():
print(f"[WiFi] 연결 성공")
try:
# NTP로 UTC 시간 동기화
ntptime.settime()
print("[NTP] UTC 시간 동기화 완료")
# UTC → 한국시간 변환 (UTC+9)
rtc = RTC()
t = rtc.datetime()
# t: (년, 월, 일, 요일, 시, 분, 초, 마이크로초)
year, month, day, weekday, hour, minute, second = t[0], t[1], t[2], t[3], t[4], t[5], t[6]
# 시간에 9시간 추가
hour = (hour + 9) % 24
# 시간이 넘어갔으면 다음날로
if hour < t[4]: # 24시간 초과해서 넘어간 경우
day += 1
# 간단히: 월마다 최대 31일로 가정 (대부분의 경우 충분)
if day > 31:
day = 1
month += 1
if month > 12:
month = 1
year += 1
# RTC에 한국시간 설정
rtc.datetime((year, month, day, weekday, hour, minute, second, 0))
# 확인용 출력
t_korea = rtc.datetime()
print(f"[RTC] 한국시간 설정: {t_korea[0]:04d}-{t_korea[1]:02d}-{t_korea[2]:02d} {t_korea[4]:02d}:{t_korea[5]:02d}:{t_korea[6]:02d}")
return True
except Exception as e:
print(f"[NTP] 동기화 실패: {e}")
return False
else:
print("[WiFi] 연결 실패")
return False
# ===== [CDS 센서 초기화] =====
def init_cds():
"""CDS 센서 초기화"""
print("[센서] CDS 초기화 중...")
# WiFi 연결 해제 (간섭 방지)
wlan = network.WLAN(network.STA_IF)
wlan.active(False)
time.sleep(0.5) # 안정화 대기
# GPIO4를 ADC로 설정
cds = ADC(Pin(4))
cds.atten(ADC.ATTN_11DB) # 3.3V 범위
# 첫 몇 개 읽음 (워밍업)
for _ in range(5):
val = cds.read()
time.sleep(0.1)
print(f"[센서] CDS 초기화 완료 (현재값: {cds.read()})")
return cds
# ===== [메인 측정 루프] =====
def measure_and_log(cds):
"""30초 동안 센서 측정 및 기록"""
rtc = RTC()
# CSV 파일 헤더 확인
try:
with open(FILENAME, 'r') as f:
pass
except OSError:
with open(FILENAME, 'w') as f:
f.write("Date,Time,Light_Value\n")
print(f"\n[측정 시작] {MEASUREMENT_TIME}초간 {INTERVAL}ms 간격으로 센서 측정\n")
# 파일을 append 모드로 열어둠
f = open(FILENAME, 'a')
next_tick = time.ticks_ms()
measurement_count = 0
end_time = time.ticks_add(time.ticks_ms(), MEASUREMENT_TIME * 1000)
try:
while time.ticks_diff(end_time, time.ticks_ms()) > 0:
# 설정 시간이 되었는지 확인 (논블로킹)
if time.ticks_diff(time.ticks_ms(), next_tick) >= 0:
next_tick = time.ticks_add(next_tick, INTERVAL)
# 센서값 읽음
val = cds.read()
# RTC에서 현재 시간 가져옴
t = rtc.datetime()
# t[0]:년, t[1]:월, t[2]:일, t[3]:요일, t[4]:시, t[5]:분, t[6]:초
# 날짜: YYYY-MM-DD
date_str = "{:04d}-{:02d}-{:02d}".format(t[0], t[1], t[2])
# 시간: HHMMSS (숫자 형식, 6자리)
time_num = int("{:02d}{:02d}{:02d}".format(t[4], t[5], t[6]))
# 파일에 기록
f.write(f"{date_str},{time_num},{val}\n")
measurement_count += 1
print(f" [{measurement_count:3d}] {date_str} {time_num:06d} | CDS값: {val}")
# FLUSH_RATE마다 저장
if measurement_count % FLUSH_RATE == 0:
f.flush()
print(f" ↳ {measurement_count}개 데이터 저장 완료")
# 마지막 저장
f.flush()
finally:
f.close()
print(f"\n[완료] 총 {measurement_count}개 데이터 기록\n")
# ===== [메인 실행] =====
if __name__ == "__main__":
if setup_time():
cds = init_cds()
measure_and_log(cds)
print("[프로그램 종료]")
else:
print("[오류] WiFi 연결 실패")
Python
복사
•
코드 포인트3가지
1. time.sleep()을 쓰지 않음: "잠들지 않고 시계만 보면서 기다리기 때문에, 기다리는 동안 버튼을 누르는 것도 다 알 수 있음."
2. f.flush() 사용: "글을 쓰다가 저장을 안 하고 끄면 날아가지만, 이 코드는 10번 쓸 때마다 '저장 버튼'을 눌러주는 것과 같음."
3. f.write() 바로 사용: "머릿속(리스트)에 다 외우고 있다가 한 번에 쓰려면 머리가 아프지만(메모리 부족), 이 코드는 한 줄씩 바로 공책에 적는 방식임."
[값 확인방법] 위와 동일하게 Thonny IDE 왼쪽 파일 탐색기에서 MicroPython 장치 를 새로 고침한 다음 **smart_log.csv**를 찾아 다운로드
이 코드까지 오는데 반나절이상 걸림.. AI가 코드를 아무리 잘 짜도 결국은 디버깅 포인트를 사람이 제대로 설명해주어야 주도적 프로그래밍 가능
4-2. [복잡]구글 시트에 저장하기
•
상당한 준비과정이 필요하므로 다음 장에서 새로 시작하기!












