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

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

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

  • REPL์„ ์ด์šฉํ•˜์—ฌ IoT Badge์— ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ ์‹คํ–‰
  • ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ I2C ํ†ต์‹ 
  • ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ์™€ BH1750๋กœ ์กฐ๋„ ์ธก์ •

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

  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. J7๋ฒˆ 6ํ•€ 2.54mm Female ์†Œ์ผ“ ํ—ค๋” ์—ฐ๊ฒฐ
  6. GY-302 (BH1750FVI Breakout ๋ณด๋“œ)

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

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

๋‹จ๊ณ„

BH1750FVI ์„ผ์„œ ์ •๋ณด

GY-302 ๋ณด๋“œ๋Š” BH1750FVI ์„ผ์„œ๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ์ ์ธ ํšŒ๋กœ๊ฐ€ ํฌํ•จ๋œ Breakout Board ์ž…๋‹ˆ๋‹ค. BH1750์˜ I2C ํ†ต์‹ ์„ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋„๋ก VCC, GND, SCL, SDA, ADDR 5ํ•€์œผ๋กœ ๋…ธ์ถœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

BH1750FVI ์„ผ์„œ์—์„œ ์ธก์ • ๊ฐ€๋Šฅํ•œ ๋ฒ”์œ„๋Š” 1~65535 lx. ์ด๋ฉฐ ๋ชจ๋“œ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ธก์ • ๋ชจ๋“œ ์ธก์ • ์‹œ๊ฐ„ ์ธก์ • ํ•ด์ƒ๋„
H-Resolution Mode Typ. 120ms. 1 lx.
H-Resolution Mode2 Typ. 120ms. 0.5 lx.
L-Resolution Mode Typ. 16ms. 4 lx.

์œ„์˜ ์ธก์ • ๋ชจ๋“œ์— 1ํšŒ ์ธก์ •๊ณผ ์—ฐ์† ์ธก์ • ๋ฐฉ์‹ ๋‘ ๊ฐ€์ง€๋ฅผ ๋” ์ง€์›ํ•˜์—ฌ 3 x 2 = 6 ์ด 6๊ฐœ์˜ ๋ชจ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ œ์กฐ์‚ฌ์—์„œ๋Š” H-Resolution Mode ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜๋Š”๋ฐ, ์ธก์ • ์‹œ๊ฐ„์ด ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— 50~60Hz์™€ ๊ฐ™์€ ์ผ์ • ์˜์—ญ์˜ ๋…ธ์ด์ฆˆ๊ฐ€ ๊ฑธ๋Ÿฌ์ง€๋ฉฐ, 1 lx. ํ•ด์ƒ๋„๋ผ ์–ด๋‘์šด ๊ณณ(10 lx.์ดํ•˜)์— ์ ํ•ฉํ•œ ๋ชจ๋“œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์ด ๋ชจ๋“œ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ธก์ • ํ•ด์ƒ๋„๋Š” ์ธก์ • ๊ฐ’์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋‹จ์œ„๋กœ H-Res. L-Res์˜ ์ฐจ์ด๋ฅผ ๋‹ค์Œ ๊ทธ๋ž˜ํ”„์—์„œ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Lux ๊ฐ’ ๋ณ€ํ™˜

BH1750์„ผ์„œ๋Š” ์ฃผ๋ณ€ ์กฐ๋„๋ฅผ 2 bytes ๊ฐ’์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. unsigned 16bits ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜๋˜๋Š”๋ฐ ์ด ๊ฐ’์„ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Measurement Accuracy ๊ฐ’ 1.2๋กœ ๋‚˜๋ˆˆ ๊ฐ’์„ ์ตœ์ข… lux ๊ฐ’์œผ๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ˆ˜์‹ ๋œ ๊ฐ’์ด ์ƒ์œ„ ๋ฐ”์ดํŠธ 0x83, ํ•˜์œ„ ๋ฐ”์ดํŠธ 0x90 ์ธ ๊ฒฝ์šฐ 8390h (33680)์ด ๋˜๊ณ , ์ด ๊ฐ’์€ 33680/1.2 = 28066.7777777… ์ด ๋˜๋ฏ€๋กœ ๋ฐ˜์˜ฌ๋ฆผํ•˜์—ฌ 28067 lux๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

BH1750 ์„ผ์„œ๋Š” ์ธก์ • ์‹œ๊ฐ„์„ ์กฐ์ •ํ•˜์—ฌ ์ธก์ • ์„ผ์„œ ๋ฏผ๊ฐ๋„๋ฅผ ์กฐ์ ˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จํ•˜์—ฌ ์ž์„ธํ•œ ๋‚ด์šฉ์€ BH1750FVI Data sheet๋ฅผ ์ฐธ๊ณ  ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

BH1750 ์„ผ์„œ ์—ฐ๊ฒฐ ๋ฐ I2C ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ

BH1750์€ ์ „์› ์ž…๋ ฅ ํ›„ DVI๋ผ๋Š” Pin์ด LOW์—์„œ HIGH๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์œผ๋กœ ์ดˆ๊ธฐํ™” ๋ฉ๋‹ˆ๋‹ค. ๋ณธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์‚ฌ์šฉํ•˜๋Š” GY-302 ๋ณด๋“œ๋Š” ์ €ํ•ญ๊ณผ ์ฝ˜๋ด์„œ๋ฅผ ์ด์šฉํ•˜์—ฌ LPF (Low-pass Filter)๋ฅผ ์ ์šฉํ•œ ๋ฆฌ์…‹ ํšŒ๋กœ๋กœ ์ „์›์ด ๋ถ€์—ฌ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋ฆฌ์…‹๋ฉ๋‹ˆ๋‹ค.

I2C ํ†ต์‹ ์„ ์œ„ํ•œ Pin์€ SCL๊ณผ SDA์ด๋ฉฐ iot badge์˜ J7์— ์—ฐ๊ฒฐ๋˜์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ ํ•ฉ๋‹ˆ๋‹ค.

ESP32 BH1750 Description
VCC VDD v3.3
GND GND Ground
GPIO26 SCL Serial Clock
GPIO25 SDA Serial Data
GPIO33 ADDR Select Slave Address

๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์˜ machine.I2C ๋ชจ๋“ˆ์„ ์ด์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋กœ I2C ํ†ต์‹ ์„ ์œ„ํ•œ ์ค€๋น„๊ฐ€ ์™„๋ฃŒ ๋ฉ๋‹ˆ๋‹ค.

from machine import I2C, Pin
import time

SCL = Pin(26) # SCL
SDA  = Pin(25) # SDA
i2c = I2C(scl=SCL, sda=SDA)

์ด์ œ BH1750์—์„œ ์‚ฌ์šฉํ•˜๋Š” Instruction์„ ํ™•์ธํ•ด ๋ด…๋‹ˆ๋‹ค.

Instruction Opecode Hex
Power Down 0000_0000 0x00
Power On 0000_0001 0x01
Reset 0000_0111 0x07
Continously H-Resolution Mode 0001_0000 0x10
Continously H-Resolution Mode2 0001_0001 0x11
Continously L-Resolution Mode 0001_0111 0x17
One Time H-Resolution Mode 0010_0000 0x20
One Time H-Resolution Mode2 0010_0001 0x21
One Time L-Resolution Mode 0010_0111 0x27
Change Measurement Time (High bit) 01000_MT[7, 6, 5] 0x40~0x47
Change Measurement Time (Low bit) 011_MT[4, 3, 2, 1, 0] 0x60~0x7f

์ด๋ฅผ ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒ์ˆ˜๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

BH1750_POWER_DOWN  = 0x00
BH1750_POWER_ON    = 0x01
BH1750_POWER_RESET = 0x07
BH1750_CONT_H_RES_MODE  = 0x10
BH1750_CONT_H_RES_MODE2 = 0x11
BH1750_CONT_L_RES_MODE  = 0x17
BH1750_ONCE_H_RES_MODE  = 0x20
BH1750_ONCE_H_RES_MODE2 = 0x21
BH1750_ONCE_L_RES_MODE  = 0x27
BH1750_MTREG_HIGH_BASE  = 0x40
BH1750_MTREG_LOW_BASE   = 0x60

I2C ๋ฐ์ดํ„ฐ ํ†ต์‹ 

BH1750์„ผ์„œ์™€ ํ†ต์‹ ์€ I2C ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. I2C๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ์ž…์žฅ์—์„œ Master์™€ Slave๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. iot badge๊ฐ€ ์„ผ์„œ๋ฅผ ์ œ์–ดํ•˜๋ฏ€๋กœ Master, BH1750 ์„ผ์„œ๊ฐ€ Slave๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

I2C ํ†ต์‹ ์„ ์œ„ํ•ด์„œ๋Š” Slave์— ๋Œ€ํ•œ ์ฃผ์†Œ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ๋ฐ, BH1750 ์„ผ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •ํ•ด์ ธ ์žˆ์œผ๋ฉฐ ADDR Pin์˜ ์ƒํƒœ ๊ฐ’์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

ADDR Slave Address Hex
HIGH 1011100 0x5c
LOW 0100011 0x23

๊ธฐ๋ณธ์ ์œผ๋กœ GY-302 ๋ณด๋“œ์—์„œ๋Š” ADDR Pin์„ 1K ์ €ํ•ญ์œผ๋กœ Pull-down ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ Slave ์ฃผ์†Œ ๊ฐ’์€ 0x23์ด ๋ฉ๋‹ˆ๋‹ค. iot badge์˜ J7์— ์—ฐ๊ฒฐ๋œ GPIO33์ด ADDR Pin์— ๋Œ€์‘๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ADDR Pin์„ ๊ฐ’์„ HIGH๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด Slave Address๋ฅผ 0x5c๋กœ ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ๊ณ„๋กœ BH1750๊ณผ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.

  • Master์—์„œ Slave๋กœ mode ์„ค์ • Instruction์„ ์ „๋‹ฌ
  • mode์— ๋”ฐ๋ผ ์ธก์ • ์‹œ๊ฐ„์„ ๋Œ€๊ธฐ
  • Master์—์„œ Slave์— ์ธก์ • ๊ฐ’์„ ์š”์ฒญํ•˜๋Š” Instruction ์ „๋‹ฌํ•˜์—ฌ ์ •๋ณด ์ˆ˜์‹ 

๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์—์„œ๋Š” I2C ํ†ต์‹  ์ดˆ๊ธฐํ™”๋กœ ์–ป์€ instance์˜ writeto() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด Slave์— ๋ช…๋ น๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  readfrom() ํ•จ์ˆ˜๋กœ Slave๋กœ ๋ถ€ํ„ฐ ์ •๋ณด๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ช…๋ น ์‹œํ€€์Šค์„ ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ ๊ตฌ์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

sl_addr = 0x23 # slave address
current_mode = BH1750_ONCE_H_RES_MODE
i2c.writeto(sl_addr, bytearray([current_mode]))
time.sleep_ms(120) # 120ms for H-Res Mode
data = i2c.readfrom(sl_addr, 2)

i2c.readfrom์œผ๋กœ ์ฝ์€ ๊ฐ’์€ binary ๋ฐ์ดํ„ฐ์ด๋ฏ€๋กœ ์ด๋ฅผ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ustruct ๋ชจ๋“ˆ์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ustruct.unpack() ํ•จ์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜ธ์ถœํ•˜์—ฌ 2 ๋ฐ”์ดํŠธ ์ด์ง„ ๊ฐ’์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

import ustruct
data = i2c.readfrom(sl_addr, 2)
raw = ustruct.unpack('>H', data)[0]

BH1750์˜ ๋ชจ๋“œ ์ค‘ Continuously Mode ๋Š” ์ดˆ๊ธฐํ™”๋ฅผ ํ•œ ๋ฒˆ๋งŒ ํ•ด ์ฃผ๋ฉด ์ดํ›„ ์ง€์†์ ์œผ๋กœ ์ธก์ • ๊ฐ’์„ ์ฝ์–ด์˜ค๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ชจ๋“œ๋กœ ์ดˆ๊ธฐํ™” ๋˜์—ˆ๋‹ค๋ฉด ๋‹ค์‹œ ์ดˆ๊ธฐํ™” ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ด์— ๋Œ€ํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, H-Resolution Mode2์ธ ๊ฒฝ์šฐ๋Š” ์ธก์ •๋œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ 1bit shift right๋ฅผ ํ•ด ์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ ์ด์— ๋Œ€ํ•œ ๋ถ€๋ถ„๋„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.

current_mode = BH1750_ONCE_H_RES_MODE
def measure(inst=None):
    global current_mode
    if inst == None:
        inst = current_mode
    if inst < 0x10 or inst > 0x27:
        raise Error('This (%) is not kind of mode inst.'.format(inst))

    is_once_mode = (inst & 0x20 == 0x20)
    is_high_res_mode = not(inst & 0x07 == 0x07)

    # initialize
    if is_once_mode or not (inst == current_mode):
        i2c.writeto(sl_addr, bytearray([inst]))
        current_mode = inst

    # Measuring time
    time.sleep_ms(120 if is_high_res_mode else 16)
    data = i2c.readfrom(sl_addr, 2)
    raw = ustruct.unpack('>H', data)[0]

    # Measurement Accuracy
    m_acc = 1.2

    # Check H-Resolution mode2
    if is_high_res_mode and inst & 0x01 == 0x01:
        raw >>= 1
    
    return int(round(raw/m_acc))

์„ผ์„œ ์ •๋ณด ํ‘œ์‹œ

๋‹ค์Œ๊ณผ ๊ฐ™์ด measure() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์กฐ๋„ ์ •๋ณด๋ฅผ ์ฝ๊ณ  uGFX๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™”๋ฉด์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

ugfx.init()
ugfx.set_default_font('IBMPlexMono_Bold24')
ugfx.clear()
ugfx.Label(40, 0, 240, 60, text='BH1750 I2C Demo')

ugfx.set_default_font('IBMPlexMono_Regular24')
l = ugfx.Label(40, 60, 240, 120, text='')

while True:
    lux = measure(BH1750_CONT_H_RES_MODE)
    l.text('Measured: {} lux'.format(lux))
    time.sleep(1)

iot badge์—์„œ ์‹คํ–‰ ์ค‘์ธ ๋ชจ์Šต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋งบ์Œ๋ง

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” IBM Developer Day 2018 IoT ๋ฑƒ์ง€์™€ BH1750 ์„ผ์„œ๋ฅผ ํ™œ์šฉํ•œ ๋งˆ์ดํฌ๋กœ ํŒŒ์ด์ฌ์˜ I2C(Inter-Integrated Circuit) ํ†ต์‹  ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.