ESP8266 개요

하드웨어/ESP8266 2016. 10. 13. 13:00

1.1 ESP8266 개요 c{mpy0101}


ESP8266은 Espressif Systems 라는 상하이 소재 중국 회사에서 2014년도에 출시한 마이크로 컨트롤러이다.


[그림] ESP8266


ESP8266은 다음과 같은 물리적인 스펙을 가지고 있다.


  • Voltage : 3.3V

  • Current consumption : 10uA – 170mA

  • Flash memory attachable : 16MB max (512K normal)

  • Processor : Tensilica L106 32 bit

  • Processor speed : 80-160MHz

  • RAM : 32K + 80K

  • GPIOs : 17 (multiplexed with other functions)

  • ADC(Analog to Digital) : 1 input with 1024 step resolution

  • 802.11 support : b/g/n/d/e/i/k/r

  • Maximum concurrent TCP connections : 5


스펙을 보면 알겠지만 이 칩만으로도 독립된 프로세서 보드를 구성할 수 있는 충분한 기능이 내장되어 있다. Wi-Fi 기능을 내장하고 있으면서도 저렴한 가격 때문에 무선인터넷 기반의 제품을 만드는 경우 무선모듈로 널리 사용되고 있으며 아두이노(arduino)와 같은 보드와 시리얼통신으로 연결하여 무선인터넷 기능을 구현할 수 있다.


[그림] ESP-01모듈(좌)과 ESP-12모듈(우)


특히 주목할만한 것은 Lua(eLua) 나 python(MicroPython) 혹은 javascript 같은 스크립트 언어로 제어할 수 있게끔 해주는 펌웨어도 존재한다는 점이다. 이는 c++ 기반으로 개발하는 것 보터 훨씬 더 편리한 환경에서 개발을 진행할 수 있다는 것을 의미하며  ESP-12 모듈 기반의 NodeMCU, WeMos 등등 다양하고 저렴한 응용 보드가 제작되어 널리 사용되고 있다.


NodeMCU보드

WeMos d1 mini 보드


이러한 보드에 eLua나 MicroPython 과 같은 펌웨어를 올려서 Lua 혹은 python으로 보드와 주변 기기들을 제어할 수 있다.


Posted by 살레시오

댓글을 달아 주세요


1.2 WeMos D1 mini 보드                       c{mpy0102}


전절에서 소개한 ESP8266 모듈을 사용한 WeMos D1 mini 라는 보드가 있다. 작은 크기의 PCB에 ESP8266모듈과 전력변환 회로 그리고 Serial-to-USB 칩과 micro-usb포트를 갖추고 있어서 PC와 연결하여 바로 사용할 수 있도록 compact하게 만들어 놓은 것이다.


윗면

밑면

실제 외관


이 모듈은 통신칩으로 CH340이라는 IC를 사용하는데 WeMos 다운로드 페이지에서 전용 드라이버를 받아 설치해야 한다.



핀맵은 위 그림과 같다. ESP8266의 GPIO와 WeMos의 Data핀과의 번호가 다르므로 유의해야 한다.


Posted by 살레시오

댓글을 달아 주세요


2.7 아날로그 입력             c{mpy0207}


ESP8266은 아날로그 입력핀 하나를 가지고 있다. 이 핀을 이용하면 0V~1.0V사이의 전압을 읽어서 숫자 0~1023 사이의 값으로 변환할 수 있다.


MicroPython에서는 다음과 같이 machine모듈의 ADC클래스를 이용하여 객체를 생성하면 된다.


from machine import ADC
a0 = ADC(0)
print(a0.read())

read()메서드의 값은 0과 1023사이의 정수이며 1023일때 핀의 전압이 1.0V라는 의미이다.

A0핀에 1.0V 이상의 전압이 가해지면 안되므로 적절한 전압분배회로를 이용해야 한다.


Posted by 살레시오

댓글을 달아 주세요

2.6 pwm 기능으로 서보모터 제어하기     c{mpy0206}


서보모터는 R/C카의 조향장치나 마이크로로봇의 구동장치로 쓰이는 모터로서 신호선 한 가닥으로 0도~180도의 각도를 조절할 수 있는 것이다.


[그림] 서보 모터의 외형


위 그림에서 보듯이 전원선인 Vcc/GND와 신호선 세 가닥이 인터페이스의 전부이다. 모터축의 각도는 신호선으로 인가되는 펄스폭으로 조정된다.


[그림] 서보 모터의 신호선으로 인가되는 펄스(pulse)


위 그림에 서보모터의 신호선으로 인가되는 펄스를 도시하였다. 주기 B는 3ms~20ms 의 범위를 가지며 주기가 짧을 수록 모터축의 회전 속도가 빨라진다. 펄스의 폭 A는 1.5ms 일때 중심각도인 0도를 가리키게 되고 1ms(최소값 0.7ms)일때 –90도, 2ms(최대값 2.3ms)일 때 +90도를 갖는다. 즉, 이 펄스폭을 조절하여 –90도에서 90도 사이의 원하는 각도를 가지도록 제어할 수 있다.

이것을 pwm기능으로 구현하려면 다음과 같이 하면 된다. 일단 주기는 50 Hz~330Hz 정도의 범위를 가지며 주파수가 높을 수록 회전속도는 빨라진다. 만약 50Hz를 사용한다면 펄스폭이 20ms이므로 1.5ms를 만드려면 듀티를 77(정확한 값은 76.8)로 설정하면 되며 40~115의 값을 주면 정해진 각도로 회전하게 된다.



[표] freq=50일경우 duty에 따른 회전각

duty

회전각

40

-90도

77

0도

115

+90도




만약 gpio12에 서보모터의 신호선이 연결되어 있다면 다음과 같이 PWM객체인 servo를 생성하여 제어할 수 있다.


from machine import Pin, PWM
servo=PWM(Pin(12), freq=50)

만약 0도로 맞출려면 다음과 같이 하면 된다.


servo.duty(77)

단 주파수가 바뀌면 각도를 제어하기 위한 duty값도 다시 계산하여 사용해야 한다.

Posted by 살레시오

댓글을 달아 주세요


2.5 LED의 fading 예제   c{mpy0206}


여기에서는 math 모듈의 sin 함수를 이용하여 LED의 밝기를 조절하는 예제를 작성해 보도록 하겠다. LED는 gpio5 핀에 연결되어 있다고 가정한다.


from machine import Pin, PWM
import time, math

led = PWM(Pin(5), freq=1000)

def pulse(tm):
   for x in range(628):
       led.duty( int(511-math.cos(x/100)*511) )
       time.sleep_ms(tm)

for i in range(10):
   pulse(1)

위에서 pulse()함수를 보면 내부에서 math.sin()함수의 한 주기를 628등분하여 돌아가며


int(511-math.cos(x/100)*511)

는 0부터 1022 범위의 정수를 계산해냄을 알 수 있다. pulse()함수의 인수로 시간(ms)값을 받아서 628등분 각 사이의 지연 시간을 지정할 수 있다. 위 예제와 같이 pulse(1)과 같이 호출하면 한 주기에 약 0.628초가 걸린다.


이 프로그램을 실행하면 led가 10번 밝아졌다 어두워졌다를 반복하게 된다.


Posted by 살레시오

댓글을 달아 주세요



 ESP8266의 0,2,4,5,12,13,14,15 번 핀 모두 PWM 파형을 만들 수 있다. 단, 모두 같은 주파수를 가지며 주파수의 범위는 1~1000Hz 이다. 즉, 각각의 PWM파형이 서로 다른 주파수를 가질 수 없다.


 PWM파형을 만들기 위해서는 먼저 Pin객체를 생성해야 한다.


import machine
p5 = machine.Pin(5)

이것을 이용해서 PWM객체를 만들 수 있다.


pwm5=machine.PWM(p5)

이제 이 객체의 freq()메서드와 duty()메서드를 이용하여 주파수와 듀티비를 설정할 수 있다. 듀티비는 0~1023의 범위를 가진다.


pwm5.freq(500) #500Hz
pwm5.duty(512)

위와 같이 하면 주파수는 500Hz에 듀티비는 50%이다. 만약 freq()함수와 duty()함수를 인수 없이 호출하면 현재 설정값을 반환한다.


메서드

기능

비고

PWM(PinObj, freq=500, duty=0)

PWM클래스의 생성.


pwm.freq(n)

pwm.freq()

주파수를 n으로 설정

주파수값 반환

n은 [1,1000]범위의 정수

pwm.duty(m)

pwm.duty()

듀티비를 m으로 설정

현재 듀티비를 반환

m은 [0,1023]범위의 정수

pwm.deinit()

PWM 중단



좀 더 간략하게 작성된 프로그램은 다음과 같다.


from machine import Pin, PWM
pwm5 = PWM(Pin(5), freq=500, duty=512) #PWM객체 생성, 주파수는 500Hz

서로 다른 핀에서 발생하는 PWM파형일지라도 모두 같은 주파수로 동작한다는 사실에 유의해야 한다.


Posted by 살레시오

댓글을 달아 주세요


2.3 외부 인터럽트

c{mpy02p03}

 NodeMCU모듈의 16번 핀을 제외한 GPIO핀들에 외부 인터럽트 핸들러를 붙여줄 수 있다. 예를 들어서 GPIO4 핀에 택스위치를 GND와 직결한 다음 풀업레지스터를 연결하여 FALLING EDGE를 검출하는 예제는 다음과 같다.


from machine import Pin
p4 = Pin(4, Pin.IN, Pin.PULL_UP)

# 인터럽트핸들러
# 인터럽트가 발생한 Pin 객체가 넘어온다.
def callback(pin):
   print('falling ',pin)

p4.irq(trigger=Pin.IRQ_FALLING,handler=callback)

먼저 Pin 객체를 입력+풀업저항으로 설정한 후 그 객체의 irq 메서드를 이용하여 인터럽트의 종류와 핸들러를 설정할 수 있다. 그리고 irq()  함수의 trigger 인수는 다음과 같이 세 가지로 설정할 수 있다.


trigger 인수

동작

Pin.IRQ_FALLING

핀이 1에서 0올 떨어질때 handler 호출

Pin.IRQ_RISING

핀이 0에서 1로 올라갈때 handler 호출

Pin.IRQ_RISING | Pin.IRQ_FALLING

두 경우 모두 handler 호출


이렇게 지정하면 해당하는 경우에 handler 인수로 지정해둔 함수가 호출된다. hadler의 인수로는 Pin 객체가 넘어온다.


 주의할 점은 동일한 핀에 IRQ_RISING과 IRQ_FALLING에 각각 다른 handler를 붙여줄 수 없다는 점이다. 하지만 위 표에서와 같이 두 경우 중 하나가 발생했을 때 모두 동일한 handler를 붙여줄 수 있으므로 그 함수 안에서 pin.value() 함수값을 읽으면 어떤 인터럽트가 발생했는지 확인할 수 있으므로 각각을 다르게 처리할 수는 있을 것이다.


 만약 기계식 접점에서 발생하는 인터럽트라면 채터링(chattering)현상으로 인해서 누를 때마다 여러 번의 인터럽트가 발생할기 쉽다. 이러한 채터링 현상을 제거하는 것을 디바운싱(debouncing)이라고 하는데 다음과 같이 간단히 프로그램으로 해결할 수 있다.


from machine import Pin
import time
p4 = Pin(4, Pin.IN, Pin.PULL_UP)

def callback(pin):
   time.sleep_ms(150)
   if pin.value()==0:
       #아래에 실제 처리할 코드를 넣는다.
       print('falling ',pin)

p4.irq(trigger=Pin.IRQ_FALLING,handler=callback)

여기에서 사용하는 방법은 채터링이 사라질 때까지 기다린 다음 핀의 값을 읽어서 여전히 0이라면 FALLING 인터럽트가 실제로 일어났다고 판단하는 것이다. 만약 RISING 인터럽트의 경우는 기다린 후 pin.value()가 아직도 1인지를 검사하면 될 것이다. 채터링이 사라지는  시간은 대락 100~200ms 정도로 알려져 있으므로 기다리는 시간은 적당히 설정하면 된다.


 외부 인터럽트는 실행하고 있는 모든 일을 중단시키고 즉시 handler 함수를 호출하며 메모리 할당 등은 할 수 없다. 또한 handler 함수는 되도록 짧고 간결하게 작성하여야 한다.

(현 시점에서 RISING 인터럽트 동작은 문제가 있는 것 같다.)



Posted by 살레시오

댓글을 달아 주세요


2.2 GPIO핀 제어

c{mpy0202}

 MicroPython 에서는 핀번호를 ESP8266모듈의 GPIO 번호를 사용한다. 아래 그림에서 보면 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16 번이다.



이들을 제어하기 위해서는 machine 모듈의 Pin 객체를 이용해야 한다.


from machine import Pin

p0 = Pin(0, Pin.OUT)    # GPIO0 출력핀 객체 생성
p0.high()               # set pin to high
p0.low()                # set pin to low
p0.value(1)             # set pin to high

p2 = Pin(2, Pin.IN)     # GPIO2 입력핀 생성
print(p2.value())       # get value, 0 or 1

p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation

위와 같이 Pin 객체의 생성자에 입력/출력 그리고 초기값 등등을 지정해 줄 수 있으며 멤버함수 high(), low() 로 출력값을 지정하거나 value()함수로 핀의 입력값을 받을 수 있다.


출력

입력

p = Pin(n, Pin.OUT)
p = Pin(n, Pin.IN)
p = Pin(n, Pin.IN, Pin.PULL_UP)
p.high() 혹은 p.value(1)
p.low() 혹은 p.value(0)
p.value()

여기서 n은 0,1,2,3,4,5,12,13,14,15,16 중 하나이다.


이와 같이 value() 멤버함수는 출력값을 지정해 줄 때도 쓰이고 입력인수가 없을 경우에는 핀의 입력값을 읽을 때도 사용된다.


단, 1번과 3번 핀은 시리얼 통신에 사용되며 16번 핀은 wakeup 기능(deepsleep 모드에서)에 사용되므로 가급적 사용하지 말아야 한다.



Posted by 살레시오

댓글을 달아 주세요


1.3 MicroPython 설치

c{mpy0103}

 nodeMcu에 microPython을 설치할 수 있다. 이런 저가의 모듈을 python으로 제어할 수 있다니 무척 놀랬다. 설치하는 과정도 무척 간단한데 윈도우 기준으로 설명한다면 다음과 같다.

1.3.1 python 2.7 과 pip 설치하기

만약 윈도우 PC에 python 2.7이 설치되어 있지 않다면 설치해야 하는데 이 과정은 무척 간단하다. 윈도우 인스톨러를 다운받은 후 설치하면 된다.기본 설정을 변경하지 않았다면 c:/python27 폴더가 생성되어 있을 것이다. 그 다음 pip 라는 파이썬 모듈을 설치해야 하는데 여기에서 get-pip.py 를 다운받아 c:/python27 폴더에 옮긴 후 다음과 같이 실행하면 설치된다.


python get-pip.py

1.3.2 nodeMCU에 펌웨어 설치

먼저 nodeMCU를 PC와 연결한 후 시리얼 포트 번호를 알아두어야 한다. 그리고 MicroPython downloads 페이지에서 ESP8266 용의 최신 펌웨어를 다운받아 c:/python27 폴더에 복사해 넣는다.


[그림] ESP8266 용의 MicroPython 펌웨어


nodeMCU에 펌웨어를 설치하기 전에 esptool 파이썬 모듈을 설치해야 한다.


python -m pip install esptool

그 다음에 설치된 esptool 을 이용하여 반드시 esp8266의 내부 플래시메모리 내용을 삭제하여야 한다.


python -m esptool --port COM4 erase_flash

위에서 COM4는 자신의 포트 번호를 사용해야 한다. 이제 펌웨어를 저장한다.


python -m esptool --port COM4 --baud 460800 write_flash --flash_size=8m 0 esp8266-2016-05-03-v1.8.bin


파일명은 자신이 다운로드받은 것으로 대체해야 한다. 만약 기록 후 원본과 대조를 하고자 하면 --verify 옵션을 추가로 붙여주면 된다.


1.3.3 PC와의 연결

putty를 이용하여 serial로 연결하면 된다. 속도(baud rate)는 115200 으로 설정한다.



이제 다음과 같이 접속되면 성공한 것이다.



NodeMCU 같은 와이파이가 포함된 저가의 프로세서를 파이썬으로 제어한다는 것은 무척 매력적이다. 파이썬을 잘 알지 못한다면 이 기회에 배워두는 것도 나쁘지 않을 것이다.



Posted by 살레시오

댓글을 달아 주세요