IBM Developer Day 2018์—์„œ ๋ฐฐํฌํ•œ IoT ๋ฑƒ์ง€๋Š” ESP32 Devkit์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ ๋‹น์‹œ ์„ค์น˜๋œ ํ–‰์‚ฌ์šฉ ์†Œํ”„ํŠธ์›จ์–ด ๋Œ€์‹  ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์ด ํฌํŒ…๋œ ํŽŒ์›จ์–ด๋ฅผ ์„ค์น˜ํ•˜๋ฉด IoT ๋ฑƒ์ง€๋ฅผ ๊ฐœ๋ฐœ ๋ณด๋“œ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” IoT Badge์— ํ”ผ์—์กฐ ๋ถ€์ €๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์—์„œ PWM(Pulse Width Modulation)์œผ๋กœ ๊ฐ„๋‹จํ•œ ์Œ์•…์„ ์—ฐ์ฃผํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค.

ํ•™์Šต ๋ชฉํ‘œ

์ด ํŠœํ† ๋ฆฌ์–ผ์„ ๋งˆ์น˜๊ฒŒ ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • REPL์„ ์ด์šฉํ•˜์—ฌ IoT Badge์— ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ ์‹คํ–‰
  • ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ GPIO ํฌํŠธ๋กœ PWM ์ถœ๋ ฅ

์‚ฌ์ „ ์ค€๋น„ ์‚ฌํ•ญ

  1. Developer Day 2018 IoT Badge ํŽŒ์›จ์–ด ์„ค์น˜ํ•˜๊ธฐ
  2. Developer Day 2018 IoT Badge์— ๋‚˜๋งŒ์˜ ํŒŒ์ด์ฌ ์ฝ”๋“œ ์‹คํ–‰ํ•˜๊ธฐ
  3. IBM Developer Day 2018 IoT Badge
  4. ๋ฐ์ดํ„ฐ ํ†ต์‹ ์šฉ USB 2.0 Micro B Type ์ผ€์ด๋ธ” (๋งˆ์ดํฌ๋กœ 5ํ•€)
  5. J8๋ฒˆ 6ํ•€ 2.54mm Female ์†Œ์ผ“ ํ—ค๋” ์—ฐ๊ฒฐ
  6. ํ”ผ์—์กฐ ๋ถ€์ €

์†Œ์š” ์‹œ๊ฐ„

์ด ํŠœํ† ๋ฆฌ์–ผ์„ ์™„๋ฃŒํ•˜๊ธฐ๊นŒ์ง€ ๋Œ€๋žต 15๋ถ„ ์ •๋„๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค.

๋‹จ๊ณ„

ํ”ผ์—์กฐ๋ถ€์ € ์—ฐ๊ฒฐํ•˜๊ธฐ

ํ”ผ์—์กฐ ๋ถ€์ €๋Š” ๋‹ค์–‘ํ•˜๊ฒŒ ์žˆ์œผ๋‚˜ Developer Day 2018 ํ–‰์‚ฌ๋ฅผ ํ†ตํ•ด ์ œ๊ณตํ•œ ๋ถ€์ €๋Š” 6.5mm ์ •๋„๋ผ 2.54mm ๊ฐ„๊ฒฉ์˜ ์†Œ์ผ“์— ๋”ฑ๋งž๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ 4ํ•€ ์†Œ์ผ“์— ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋„๋ก ์•ฝ๊ฐ„ ๋‹ค๋ฆฌ ๊ฐ„๊ฒฉ์„ ๋„“ํ˜€์„œ J8๋ฒˆ ์†Œ์ผ“์— ๊ฝ‚์Šต๋‹ˆ๋‹ค.

J8๋ฒˆ์˜ ์ œ์ผ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ฒซ ๋ฒˆ์งธ๋Š” GPIO27๋ฒˆ์ด๊ณ , ๋„ค ๋ฒˆ์งธ๋Š” GND์ž…๋‹ˆ๋‹ค. ๋ถ€์ €์˜ + ๊ธฐํ˜ธ์ชฝ์„ GPIO27๋ฒˆ, – ๊ธฐํ˜ธ์ชฝ์„ GND์— ๋งž์ถฐ์„œ ๋ผ์›Œ๋„ฃ์Šต๋‹ˆ๋‹ค.

๋”ฑ ๋งž์ง€๋Š” ์•Š์ง€๋งŒ ๋น ์ง€์ง€ ์•Š์„ ์ •๋„์˜ ์•ˆ์ •๊ฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ชจ์–‘์ด ๋ฉ๋‹ˆ๋‹ค.

๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

ํ”ผ์—์กฐ ๋ถ€์ €๋Š” PWM ๋ฐฉ์‹์œผ๋กœ ์†Œ๋ฆฌ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์—์„œ๋Š” machine.PWM ๋ชจ๋“ˆ์„ ์ด์šฉํ•˜์—ฌ GPIO ํฌํŠธ์— PWM ์ œ์–ด ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ESP32๊ฐ€ PWM์ด๋ผ๋Š” ๊ฒƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  Timer๋ฅผ ์ด์šฉํ•˜์—ฌ PWM์„ ๊ตฌํ˜„ํ•œ ๋ชจ๋“ˆ์ด๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ Timer ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ฃผํŒŒ์ˆ˜๊ฐ€ 1Hz๋ถ€ํ„ฐ 40MHz๊นŒ์ง€ ์„ค์ • ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ฃผํŒŒ์ˆ˜๊ฐ’์ด ๋†’์•„์ง์— ๋”ฐ๋ผ duty ํ•ด์ƒ๋„๋Š” ๊ฐ์†Œ๋˜๋Š” ํ˜„์ƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 40MHz์ธ ๊ฒฝ์šฐ ํ•ด์ƒ๋„๋Š” 1bit๊ฐ€ ๋˜๋ฉฐ duty๋Š” ๋ฌด์กฐ๊ฑด 50%๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ด€๋ จํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ESP IDF-Supported Range of Frequency and Duty Resolution๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ  ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์šฐ์„ ์€ ํ•„์š”ํ•œ ํŒŒ์ด์ฌ ๋ชจ๋“ˆ์„ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

from machine import Pin
from machine import PWM
import time

๊ทธ๋ฆฌ๊ณ  J8์˜ GPIO27๋ฒˆ ํ•€์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  Pin์— ๋Œ€ํ•œ ๊ฐ์ฒด๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

p = Pin(27, Pin.OUT)

์ด์ œ machine.PWM ๋ชจ๋“ˆ์— 27๋ฒˆ Pin์— ๋Œ€ํ•œ ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ PWM ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  duty ๊ฐ’์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.

pwm = PWM(p)
pwm.duty(0)

๊ทธ๋ฆฌ๊ณ , A4 (๋ผ)์Œ๊ณ„์ธ 440Hz ์ฃผํŒŒ์ˆ˜๋ฅผ ์„ค์ • ํ›„ duty ๊ฐ’์„ 50%๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

pwm.freq(440)
pwm.duty(50)

๋ผ์Œ์— ๋Œ€ํ•ธ ์†Œ๋ฆฌ๋ฅผ ๋“ค์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ๋ฐ”๋กœ ์œ—์Œ์ธ B4(์‹œ) 494 ๊ทธ๋ฆฌ๊ณ , C5(๋„) 523๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

pwm.freq(494)
pwm.freq(523)

๊ทธ๋Ÿฐ๋ฐ PWM์€ ์ผ์ •ํ•œ ์ฃผํŒŒ์ˆ˜๋ฅผ ์ง€์†์ ์œผ๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ์†Œ๋ฆฌ๊ฐ€ ๊ณ„์† ๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ํŠน์ •ํ•œ ์†Œ๋ฆฌ๋ฅผ ํŠน์ •ํ•œ ์‹œ๊ฐ„๋™์•ˆ ๋‚ด๋ ค๋ฉด duty ๊ฐ’์ด 0%์ธ ์ƒํƒœ์—์„œ ์†Œ๋ฆฌ๋ฅผ ๋‚ด๊ณ ์ž ํ•  ๋•Œ 50%๋กœ ์„ค์ •ํ•˜๊ณ  ๋˜ ์†Œ๋ฆฌ๋ฅผ ๋„๋ ค๋ฉด ๋‹ค์‹œ 0%์œผ๋กœ ์„ค์ •ํ•˜๊ฒŒ ํ•˜๋ถ€์ €๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ beeper๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „๋‹ฌ ์ธ์ž ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ C5์Œ์„ 1์ดˆ ๋™์•ˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

def beeper(freq=523, duration=1000):
    pwm.freq(freq)
    pwm.duty(50)
    time.sleep_ms(duration)
    pwm.duty(0)

๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์œผ๋กœ Tone Play ํ•ด๋ณด๊ธฐ

๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์œ„ํ‚ค์—๋Š” pyboard์˜ Timer๋กœ Tone Play๋ฅผ ํ•˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ์—๋Š” ๊ฐ ์Œํ‘œ์— ๋Œ€์‘ํ•˜๋Š” ๋ณ€์ˆ˜์— ์ฃผํŒŒ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ์ž…๋ ฅํ•˜๊ณ , ์ด ์Œํ‘œ๋ฅผ ๋ฐฐ์—ด์— ๋„ฃ๊ณ  ์ˆœ์„œ๋Œ€๋กœ ์žฌ์ƒํ•˜์—ฌ ๊ฐ„๋‹จํ•œ Tone Play๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ IoT Badge์šฉ์œผ๋กœ ํฌํŒ…ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

from machine import Pin
from machine import PWM
import time

# define frequency for each tone
B0  = 31
C1  = 33
CS1 = 35
D1  = 37
DS1 = 39
E1  = 41
F1  = 44
FS1 = 46
G1  = 49
GS1 = 52
A1  = 55
AS1 = 58
B1  = 62
C2  = 65
CS2 = 69
D2  = 73
DS2 = 78
E2  = 82
F2  = 87
FS2 = 93
G2  = 98
GS2 = 104
A2  = 110
AS2 = 117
B2  = 123
C3  = 131
CS3 = 139
D3  = 147
DS3 = 156
E3  = 165
F3  = 175
FS3 = 185
G3  = 196
GS3 = 208
A3  = 220
AS3 = 233
B3  = 247
C4  = 262
CS4 = 277
D4  = 294
DS4 = 311
E4  = 330
F4  = 349
FS4 = 370
G4  = 392
GS4 = 415
A4  = 440
AS4 = 466
B4  = 494
C5  = 523
CS5 = 554
D5  = 587
DS5 = 622
E5  = 659
F5  = 698
FS5 = 740
G5  = 784
GS5 = 831
A5  = 880
AS5 = 932
B5  = 988
C6  = 1047
CS6 = 1109
D6  = 1175
DS6 = 1245
E6  = 1319
F6  = 1397
FS6 = 1480
G6  = 1568
GS6 = 1661
A6  = 1760
AS6 = 1865
B6  = 1976
C7  = 2093
CS7 = 2217
D7  = 2349
DS7 = 2489
E7  = 2637
F7  = 2794
FS7 = 2960
G7  = 3136
GS7 = 3322
A7  = 3520
AS7 = 3729
B7  = 3951
C8  = 4186
CS8 = 4435
D8  = 4699
DS8 = 4978

# set up pin PWM timer for output to buzzer or speaker
p = Pin(27, Pin.OUT)
pwm = PWM(p)
pwm.duty(0)

# play all tone
note = [B0, C1, CS1, D1, DS1, E1, F1, FS1, G1, GS1, A1, AS1, B1, C2, CS2, D2, DS2, E2, F2, FS2, G2, GS2, A2, AS2, B2, C3, CS3, D3, DS3, E3, F3, FS3, G3, GS3, A3, AS3, B3, C4, CS4, D4, DS4, E4, F4, FS4, G4, GS4, A4, AS4, B4, C5, CS5, D5, DS5, E5, F5, FS5, G5, GS5, A5, AS5, B5, C6, CS6, D6, DS6, E6, F6, FS6, G6, GS6, A6, AS6, B6, C7, CS7, D7, DS7, E7, F7, FS7, G7, GS7, A7, AS7, B7, C8, CS8, D8, DS8]

for i in note:
    pwm.freq(i)
    print(i)
    pwm.duty(30)
    time.sleep_ms(300)

mario = [E7, E7, 0, E7, 0, C7, E7, 0, G7, 0, 0, 0, G6, 0, 0, 0, C7, 0, 0, G6, 0, 0, E6, 0, 0, A6, 0, B6, 0, AS6, A6, 0, G6, E7, 0, G7, A7, 0, F7, G7, 0, E7, 0,C7, D7, B6, 0, 0, C7, 0, 0, G6, 0, 0, E6, 0, 0, A6, 0, B6, 0, AS6, A6, 0, G6, E7, 0, G7, A7, 0, F7, G7, 0, E7, 0,C7, D7, B6, 0, 0]

# play Mario Bros tone example
# source from here http://www.linuxcircle.com/2013/03/31/playing-mario-bros-tune-with-arduino-and-piezo-buzzer/
for i in mario:
    if i == 0:
        pwm.duty(0)
    else:
        pwm.freq(i) # change frequency for change tone
        pwm.duty(30)

    time.sleep_ms(150)

pwm.deinit()

๋งบ์Œ๋ง

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Develper Day 2018 IoT ๋ฑƒ์ง€์™€ ํ”ผ์—์กฐ ๋ถ€์ €๋ฅผ ์ด์šฉํ•˜์—ฌ ์–ด๋–ป๊ฒŒ ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์œผ๋กœ PWM ์ œ์–ด๋ฅผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.