Chapter 11: WiFi 연결 - 인터넷 세계로¶
🎯 이 장에서 배우는 것¶
- [ ] 피코 W의 무선 기능이 무엇인지 설명할 수 있다
- [ ] network 라이브러리로 WiFi에 연결할 수 있다
- [ ] 연결 상태를 확인하고 IP 주소의 의미를 이해할 수 있다
- [ ] WiFi 연결 상태를 OLED 화면에 표시할 수 있다
💡 왜 이걸 배우나요?¶
지금까지 피코로 만든 건 모두 혼자 작동하는 장치였어. LED 켜고, 센서 읽고, OLED에 표시하고... 근데 생각해봐. 진짜 스마트 기기들은 뭐가 다를까?
인터넷에 연결되어 있다는 거야!
- 🌡️ 스마트 온도계: 방 온도를 앱으로 확인
- ⏰ 스마트 시계: 인터넷에서 정확한 시간 받아옴
- 🌤️ 날씨 표시기: 실시간 날씨 정보 표시
피코 2W의 'W'는 Wireless(무선)를 의미해. WiFi가 내장되어 있다는 뜻이지! 이번 장에서 피코를 인터넷에 연결하면, 다음 장부터 진짜 IoT(사물인터넷) 프로젝트를 만들 수 있어.
📚 핵심 개념¶
개념 1: WiFi와 무선 네트워크¶
-
비유로 시작: "WiFi는 마치 보이지 않는 케이블과 같아요. 공기 중으로 데이터가 오가는 거죠."
-
정확한 정의: "WiFi는 무선 주파수(2.4GHz 또는 5GHz)를 사용해 기기들이 인터넷 공유기(라우터)와 통신하는 기술이에요."
-
예시로 확인: "스마트폰으로 유튜브 볼 때, 영상 데이터가 공유기 → 스마트폰으로 WiFi를 통해 전달돼요."
쉽게 말하면: WiFi = 선 없이 인터넷 연결하는 기술 📶
개념 2: SSID와 비밀번호¶
-
비유로 시작: "SSID는 WiFi의 이름표예요. 카페 가면 'CafeWiFi' 같은 이름 보이잖아? 그게 SSID야."
-
정확한 정의: "SSID(Service Set Identifier)는 무선 네트워크를 구분하는 고유한 이름이에요. 최대 32글자까지 가능해요."
-
예시로 확인:
- 학교:
School_WiFi_5G - 집:
iptime_2F - 카페:
Starbucks_Guest
쉽게 말하면: SSID = WiFi 이름, Password = WiFi 비밀번호 🔐
개념 3: IP 주소 - 인터넷 세계의 주소¶
-
비유로 시작: "IP 주소는 인터넷 세계의 집 주소야. 택배 받으려면 주소가 필요하듯, 데이터 받으려면 IP 주소가 필요해."
-
정확한 정의: "IP(Internet Protocol) 주소는 네트워크에 연결된 각 기기를 식별하는 고유한 숫자예요. IPv4는
192.168.0.10같은 형태야." -
예시로 확인:
- 공유기:
192.168.0.1 - 내 노트북:
192.168.0.15 - 피코 W:
192.168.0.23
쉽게 말하면: IP 주소 = 네트워크에서 나를 찾는 주소 🏠
개념 4: 피코 W의 무선 칩¶
피코 2W에는 CYW43439 무선 칩이 내장되어 있어:
| 기능 | 설명 |
|---|---|
| WiFi | 2.4GHz, 802.11n |
| Bluetooth | BLE 5.2 지원 |
| 안테나 | 보드에 내장 (PCB 안테나) |
쉽게 말하면: 피코 W = 일반 피코 + WiFi/Bluetooth 칩 🎁
🔨 따라하기¶
Step 1: WiFi 연결 기본 코드¶
목표: 피코를 학교/집 WiFi에 연결하기
준비물: - 피코 2W - WiFi 이름(SSID)과 비밀번호 - Thonny IDE
코드:
# === WHAT: WiFi에 연결하는 기본 코드 ===
# 피코 W를 무선 네트워크에 연결합니다
# --- WHY: 왜 필요한지 ---
# 인터넷에 연결해야 시간 동기화, 날씨 정보 등을 받을 수 있어요
# HOW: 어떻게 동작하는지
import network # WiFi 기능을 제공하는 라이브러리
import time # 대기 시간에 사용
# ⚠️ 여기에 실제 WiFi 정보를 입력하세요!
SSID = "여기에_WiFi_이름" # WiFi 이름
PASSWORD = "여기에_비밀번호" # WiFi 비밀번호
# WiFi 객체 생성 (STA = Station 모드 = 클라이언트)
wlan = network.WLAN(network.STA_IF)
# WiFi 기능 켜기
wlan.active(True)
print("WiFi 연결 시도 중...")
print(f"SSID: {SSID}")
# WiFi 연결 시도
wlan.connect(SSID, PASSWORD)
# 연결될 때까지 대기 (최대 10초)
max_wait = 10
while max_wait > 0:
if wlan.isconnected(): # 연결됐는지 확인
break
max_wait -= 1
print(".", end="") # 진행 표시
time.sleep(1)
print() # 줄바꿈
# 결과 확인
if wlan.isconnected():
print("✅ WiFi 연결 성공!")
print(f"IP 주소: {wlan.ifconfig()[0]}")
else:
print("❌ WiFi 연결 실패")
실행 결과 (성공 시):
WiFi 연결 시도 중...
SSID: School_WiFi
..
✅ WiFi 연결 성공!
IP 주소: 192.168.0.105
실행 결과 (실패 시):
WiFi 연결 시도 중...
SSID: School_WiFi
..........
❌ WiFi 연결 실패
여기서 잠깐! 🤔
STA_IF vs AP_IF -
STA_IF(Station): 피코가 공유기에 접속하는 모드 (우리가 사용) -AP_IF(Access Point): 피코가 직접 공유기 역할하는 모드
Step 2: 연결 상태 상세 확인¶
목표: 연결 상태와 네트워크 정보를 자세히 확인하기
코드:
# === WHAT: WiFi 연결 상태를 상세히 확인하는 코드 ===
# 연결 상태, IP, 신호 강도 등을 확인합니다
# --- WHY: 왜 필요한지 ---
# 연결이 안 될 때 원인을 찾으려면 상세 정보가 필요해요
import network
import time
SSID = "여기에_WiFi_이름"
PASSWORD = "여기에_비밀번호"
def connect_wifi():
"""WiFi에 연결하고 상태를 반환하는 함수"""
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# 이미 연결되어 있으면 스킵
if wlan.isconnected():
print("이미 WiFi에 연결되어 있어요!")
return wlan
print(f"'{SSID}'에 연결 중...")
wlan.connect(SSID, PASSWORD)
# 연결 대기 (최대 15초)
for i in range(15):
status = wlan.status() # 현재 상태 코드
# 상태 코드 해석
status_msg = {
0: "🔴 IDLE (대기)",
1: "🟡 CONNECTING (연결 중)",
2: "🟡 WRONG_PASSWORD (비밀번호 오류)",
3: "🟡 NO_AP (AP를 찾을 수 없음)",
-1: "🔴 FAIL (연결 실패)",
-2: "🔴 FAIL (연결 실패)",
3: "🟢 GOT_IP (연결 성공!)"
}
print(f" 상태: {status_msg.get(status, f'알 수 없음({status})')}")
if wlan.isconnected():
break
time.sleep(1)
return wlan
def show_network_info(wlan):
"""네트워크 정보를 보여주는 함수"""
if wlan.isconnected():
# ifconfig()는 (IP, 서브넷마스크, 게이트웨이, DNS) 반환
config = wlan.ifconfig()
print("\n" + "="*40)
print("📡 네트워크 정보")
print("="*40)
print(f" IP 주소: {config[0]}")
print(f" 서브넷마스크: {config[1]}")
print(f" 게이트웨이: {config[2]}")
print(f" DNS 서버: {config[3]}")
print("="*40)
else:
print("❌ WiFi에 연결되어 있지 않아요")
# 실행
wlan = connect_wifi()
show_network_info(wlan)
실행 결과:
'School_WiFi'에 연결 중...
상태: 🟡 CONNECTING (연결 중)
상태: 🟡 CONNECTING (연결 중)
상태: 🟢 GOT_IP (연결 성공!)
========================================
📡 네트워크 정보
========================================
IP 주소: 192.168.0.105
서브넷마스크: 255.255.255.0
게이트웨이: 192.168.0.1
DNS 서버: 192.168.0.1
========================================
여기서 잠깐! 🤔
네트워크 정보 해석하기 - IP 주소: 피코의 주소 (데이터 받을 곳) - 서브넷마스크: 같은 네트워크 범위를 정의 - 게이트웨이: 외부 인터넷으로 나가는 문 (보통 공유기) - DNS: 도메인(google.com)을 IP로 바꿔주는 서버
Step 3: OLED에 연결 상태 표시하기¶
목표: WiFi 연결 상태와 IP 주소를 OLED에 표시하기
회로 연결:
📌 Grove OLED를 피코의 I2C 포트에 연결하세요!
코드:
# === WHAT: WiFi 상태를 OLED에 표시하는 코드 ===
# 연결 과정과 결과를 시각적으로 보여줍니다
# --- WHY: 왜 필요한지 ---
# 터미널 없이도 연결 상태를 바로 확인할 수 있어요
import network
import time
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
# OLED 설정
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
oled = SSD1306_I2C(128, 64, i2c)
# WiFi 설정
SSID = "여기에_WiFi_이름"
PASSWORD = "여기에_비밀번호"
def oled_print(lines):
"""OLED에 여러 줄 텍스트 표시"""
oled.fill(0) # 화면 지우기
for i, line in enumerate(lines):
oled.text(line, 0, i * 10)
oled.show()
def connect_wifi_with_display():
"""WiFi 연결하면서 OLED에 상태 표시"""
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# 시작 화면
oled_print([
"== WiFi ==",
"",
"Connecting to:",
SSID[:16], # 긴 이름은 자르기
"",
"Please wait..."
])
wlan.connect(SSID, PASSWORD)
# 연결 대기 (애니메이션 효과)
dots = ""
for i in range(15):
if wlan.isconnected():
break
dots = "." * ((i % 3) + 1)
oled_print([
"== WiFi ==",
"",
"Connecting" + dots,
"",
f"Time: {i+1}s"
])
time.sleep(1)
# 결과 표시
if wlan.isconnected():
ip = wlan.ifconfig()[0]
oled_print([
"== WiFi ==",
"",
"Connected!",
"",
"IP Address:",
ip
])
return wlan, ip
else:
oled_print([
"== WiFi ==",
"",
"FAILED!",
"",
"Check SSID",
"& Password"
])
return wlan, None
# 실행
wlan, ip = connect_wifi_with_display()
if ip:
print(f"연결 성공! IP: {ip}")
else:
print("연결 실패!")
OLED 화면 변화:
[연결 중] [성공] [실패]
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│== WiFi == │ │== WiFi == │ │== WiFi == │
│ │ │ │ │ │
│Connecting... │ → │Connected! │ or │FAILED! │
│ │ │ │ │ │
│Time: 3s │ │IP Address: │ │Check SSID │
│ │ │192.168.0.105 │ │& Password │
└──────────────┘ └──────────────┘ └──────────────┘
여기서 잠깐! 🤔
SSID 이름이 길면? OLED는 한 줄에 약 16글자만 표시 가능해요.
SSID[:16]으로 잘라서 표시하거나, 스크롤 기능을 만들 수 있어요.
📝 전체 코드¶
아래는 WiFi 연결 + OLED 표시가 통합된 완성 코드야. 복사해서 바로 사용해봐!
# === WiFi 연결 + OLED 상태 표시 완성 코드 ===
# 파일명: wifi_oled_complete.py
#
# 기능:
# 1. WiFi에 자동 연결
# 2. 연결 과정을 OLED에 실시간 표시
# 3. 성공 시 IP 주소 표시
# 4. 실패 시 오류 원인 표시
import network
import time
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
# ============================================
# 🔧 설정 (여기만 수정하세요!)
# ============================================
SSID = "여기에_WiFi_이름" # WiFi 이름
PASSWORD = "여기에_비밀번호" # WiFi 비밀번호
TIMEOUT = 15 # 최대 대기 시간(초)
# ============================================
# OLED 초기화
# ============================================
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
oled = SSD1306_I2C(128, 64, i2c)
# ============================================
# 함수 정의
# ============================================
def clear_oled():
"""OLED 화면 지우기"""
oled.fill(0)
oled.show()
def show_text(lines, title=""):
"""OLED에 텍스트 표시
Args:
lines: 표시할 문자열 리스트
title: 상단에 표시할 제목 (선택)
"""
oled.fill(0)
y = 0
if title:
oled.text(title, 0, 0)
oled.hline(0, 10, 128, 1) # 구분선
y = 14
for line in lines:
if y > 54: # 화면 넘침 방지
break
oled.text(str(line)[:16], 0, y) # 16자 제한
y += 10
oled.show()
def get_status_message(status):
"""WiFi 상태 코드를 메시지로 변환"""
messages = {
0: "Idle",
1: "Connecting...",
2: "Wrong password!",
3: "No AP found",
-1: "Connection fail",
-2: "Connection fail"
}
return messages.get(status, f"Unknown({status})")
def connect_wifi():
"""WiFi에 연결하고 결과 반환
Returns:
tuple: (wlan 객체, IP 주소 또는 None)
"""
# WiFi 인터페이스 생성
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# 이미 연결됨?
if wlan.isconnected():
ip = wlan.ifconfig()[0]
show_text([
"",
"Already",
"connected!",
"",
f"IP: {ip}"
], "== WiFi ==")
return wlan, ip
# 연결 시작
show_text([
"",
"Connecting to:",
SSID[:16],
"",
"Please wait..."
], "== WiFi ==")
wlan.connect(SSID, PASSWORD)
# 연결 대기
start_time = time.time()
while time.time() - start_time < TIMEOUT:
if wlan.isconnected():
break
# 상태 표시 (애니메이션)
elapsed = int(time.time() - start_time)
dots = "." * ((elapsed % 3) + 1)
status = wlan.status()
show_text([
"",
f"Connecting{dots}",
"",
get_status_message(status),
"",
f"Time: {elapsed}s"
], "== WiFi ==")
time.sleep(0.5)
# 결과 확인
if wlan.isconnected():
ip = wlan.ifconfig()[0]
show_text([
"",
"SUCCESS!",
"",
"IP Address:",
ip
], "== WiFi ==")
return wlan, ip
else:
# 실패 원인 분석
status = wlan.status()
show_text([
"",
"FAILED!",
"",
get_status_message(status),
"",
"Check settings"
], "== WiFi ==")
return wlan, None
def disconnect_wifi(wlan):
"""WiFi 연결 해제"""
wlan.disconnect()
wlan.active(False)
show_text([
"",
"Disconnected",
"",
"WiFi OFF"
], "== WiFi ==")
# ============================================
# 메인 실행
# ============================================
if __name__ == "__main__":
print("=" * 40)
print("WiFi 연결 시작")
print("=" * 40)
wlan, ip = connect_wifi()
if ip:
print(f"\n✅ 연결 성공!")
print(f" IP 주소: {ip}")
# 네트워크 상세 정보
config = wlan.ifconfig()
print(f"\n📡 네트워크 정보:")
print(f" 서브넷마스크: {config[1]}")
print(f" 게이트웨이: {config[2]}")
print(f" DNS 서버: {config[3]}")
else:
print("\n❌ 연결 실패!")
print(" SSID와 비밀번호를 확인하세요.")
print("\n" + "=" * 40)
⚠️ 자주 하는 실수¶
실수 1: SSID나 비밀번호 오타¶
증상:
상태: 🟡 WRONG_PASSWORD (비밀번호 오류)
상태: 🟡 NO_AP (AP를 찾을 수 없음)
원인: WiFi 이름이나 비밀번호를 잘못 입력했어.
해결:
# 잘못된 코드
SSID = "School WiFi" # 공백이 다름!
PASSWORD = "password123" # 대소문자 확인!
# 올바른 코드 (정확히 확인해서 입력)
SSID = "School_WiFi" # 실제 WiFi 이름과 정확히 일치
PASSWORD = "Password123" # 대소문자 구분!
💡 팁: 스마트폰에서 WiFi 이름을 복사해오면 확실해!
실수 2: WiFi가 2.4GHz가 아닌 경우¶
증상:
상태: 🟡 NO_AP (AP를 찾을 수 없음)
원인: 피코 W는 2.4GHz만 지원해. 5GHz WiFi에는 연결 못 해.
해결:
# 5GHz WiFi 이름 (연결 안 됨!)
SSID = "Home_WiFi_5G"
# 2.4GHz WiFi 이름 (연결 가능!)
SSID = "Home_WiFi" # 또는 "Home_WiFi_2.4G"
💡 확인 방법: 공유기 설정에서 2.4GHz 네트워크 이름 확인
실수 3: 연결 대기 시간 부족¶
증상:
❌ WiFi 연결 실패
원인: 연결에 시간이 좀 걸리는데, 너무 빨리 포기함.
해결:
# 잘못된 코드 - 5초만 기다림
max_wait = 5
while max_wait > 0:
if wlan.isconnected():
break
max_wait -= 1
time.sleep(1)
# 올바른 코드 - 충분히 기다림 (15-20초)
max_wait = 15 # 또는 20
while max_wait > 0:
if wlan.isconnected():
break
max_wait -= 1
time.sleep(1)
실수 4: wlan.active(True) 빠뜨림¶
증상:
OSError: Wifi Internal Error
원인: WiFi 기능을 켜지 않고 연결 시도함.
해결:
# 잘못된 코드
wlan = network.WLAN(network.STA_IF)
wlan.connect(SSID, PASSWORD) # 에러!
# 올바른 코드
wlan = network.WLAN(network.STA_IF)
wlan.active(True) # 이거 꼭 필요!
wlan.connect(SSID, PASSWORD)
실수 5: 학교/공공 WiFi 인증 문제¶
증상: 연결은 되는데 인터넷이 안 됨
원인: 학교나 공공 WiFi는 웹 로그인이 필요할 수 있어.
해결: - 방법 1: 핫스팟 사용 (스마트폰 테더링) - 방법 2: 선생님께 WiFi 정보 확인 - 방법 3: 인증이 필요 없는 네트워크 사용
# 핫스팟 사용 시 예시
SSID = "내폰핫스팟"
PASSWORD = "핫스팟비밀번호"
✅ 스스로 점검하기¶
1. 피코 W에서 WiFi에 연결하려면 어떤 라이브러리를 사용하나요?¶
정답 확인
`network` 라이브러리를 사용해요.import network
wlan = network.WLAN(network.STA_IF)
2. STA_IF와 AP_IF의 차이점은 무엇인가요?¶
정답 확인
- **STA_IF (Station)**: 피코가 **다른 공유기에 접속**하는 모드 - **AP_IF (Access Point)**: 피코가 **직접 공유기 역할**을 하는 모드 우리는 인터넷에 연결하려고 하니까 STA_IF를 사용해요!3. 연결 성공 후 IP 주소를 얻으려면 어떻게 하나요?¶
정답 확인
`wlan.ifconfig()[0]`을 사용해요.config = wlan.ifconfig() # (IP, 서브넷, 게이트웨이, DNS) 튜플 반환
ip_address = config[0] # 첫 번째가 IP 주소
4. 피코 W가 5GHz WiFi에 연결 안 되는 이유는?¶
정답 확인
피코 W의 무선 칩(CYW43439)이 **2.4GHz만 지원**하기 때문이에요. 5GHz는 더 빠르지만, 피코 W에서는 사용할 수 없어요. 해결: 2.4GHz 네트워크에 연결하거나, 공유기에서 2.4GHz를 활성화하세요.5. 연결 상태를 확인하는 두 가지 방법은?¶
정답 확인
1. **`wlan.isconnected()`**: True/False 반환 (연결됨/안됨) 2. **`wlan.status()`**: 상태 코드 반환 (0, 1, 2, 3, -1 등)if wlan.isconnected():
print("연결됨!")
status = wlan.status() # 3이면 연결 성공
🚀 더 해보기¶
도전 1: 연결 재시도 기능 추가 (쉬움)¶
연결 실패 시 자동으로 3번까지 재시도하는 기능을 추가해봐!
힌트:
for attempt in range(3):
print(f"시도 {attempt + 1}/3")
# 연결 코드
if wlan.isconnected():
break
time.sleep(2)
도전 2: 신호 강도 표시 (중간)¶
WiFi 신호 강도(RSSI)를 막대그래프로 OLED에 표시해봐!
힌트:
# RSSI 값 얻기 (연결 후)
rssi = wlan.status('rssi') # -30(강함) ~ -90(약함)
# 막대 길이 계산 (-90~-30을 0~100%로 변환)
strength = min(100, max(0, (rssi + 90) * 100 // 60))
bar_width = strength * 100 // 100 # 픽셀로 변환
도전 3: WiFi 스캐너 만들기 (어려움) ⭐¶
주변의 모든 WiFi 목록을 스캔해서 OLED에 표시해봐!
힌트:
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# 주변 WiFi 스캔
networks = wlan.scan()
for net in networks:
ssid = net[0].decode() # 네트워크 이름
rssi = net[3] # 신호 강도
print(f"{ssid}: {rssi}dBm")
🔗 다음 장으로¶
이번 장에서 배운 것:
- ✅ 피코 W의 무선 기능 이해
- ✅ network 라이브러리로 WiFi 연결
- ✅ IP 주소의 의미와 확인 방법
- ✅ OLED에 연결 상태 표시
다음 장 "시간 동기화 - 정확한 시계"에서는: - 인터넷에서 정확한 시간 받아오기 (NTP) - 한국 시간대 설정하기 - OLED에 실시간 시계 표시하기
드디어 인터넷 연결에 성공했어! 🎉 다음 장에서는 이 연결을 활용해서 전 세계 어디서나 정확한 시간을 받아올 거야. 피코가 진짜 스마트 기기가 되는 거지!