기본 콘텐츠로 건너뛰기

NodeMCU에서 I2C 통신을 이용하여 OLED 디스플레이에 표시하기


준비물:

NodeMCU 개발보드 1개, OLED SSD1306 디스플레이 1개, micro-USB 케이블 1개, 브레스보드
그림 1. 준비물

개발환경

아두이노 스케치 1.8.9
ESP8266 OLED SSD1306 라이브러리   https://github.com/ThingPulse/esp8266-oled-ssd1306

I2C란

I2C 버스는 80년대 초반에 저속의 부품들을 연결하기 위한 목적으로 필립스에서 개발한 직렬버스이다. "Inter IC"라고도 하며, IIC, I2C 버스라고도 한다. I2C 통신은 다음과 같은 특징들을 갖는다.
  • SDA, SCL 등 2개의 통신선만 사용하므로 구성이 간단하다.
  • 마스터-슬레이브 관계로 연결하여 1:n 연결이 가능하다. 슬레이브는 고유의 주소로 구분한다.
  • 통신 최대속도는 100Kbit/s이며, Fast mode(400Kbit/s), High speed mode(3.4Mbit/s)도 지원한다.

실습내용

아두이노의 경우 디폴트로 SDA와 SCL을 위해 GPIO4 핀과 GPIO5 핀이 지정되어 있지만, ESP8266의 경우 소프트웨어적인 방식으로 구현되어 있기 때문에 임의의 핀을 이용할 수 있다. 여기서는 D1(GPIO5), D2(GPIO4)핀을 SCL과 SDA로 지정했다. ESP8266은 마스터로 동작하며 OLED 디스플레이는 슬레이브로 동작한다.

Wire 라이브러리

ESP8266(마스터)에서 OLED 디스플레이(슬레이브)로의 데이터 전송은 먼저 버퍼를 준비하고, 버퍼에 데이터를 기록한 후 버퍼의 내용을 전달하는 3단계로 진행된다.

멤버 함수들을 사용하기 위해 우선 헤더 파일을 추가한다.

#include <Wire.h>
초기화
void begin(int sda, int scl)
  • sda: SDA(Serial data) 핀 번호
  • scl: SCL(Serial clock) 핀 번호

데이터 전송
슬레이브로의 데이터 전송은 beginTransmission 함수를 사용하여 전송을 위해 버퍼를 초기화하고, write 함수로 버퍼에 데이터를 기록한 후, endTransmission 함수로 버퍼에 기록된 데이터를 전송.

void beginTransmission(uint8_t address)
void beginTransmission(int address)
  • address: 슬레이브 주소

size_t write(uint8_t data)
size_t write(const unint_8 *date, size_t quantity)
  • data: 전송할 단일 바이트 또는 바이트 배열에 대한 포인터
  • quantity: 전송할 바이트 수
  • RETURN: 전송된 바이트 수

uint8_t endTransmission(void)
uint8_t endTransmission(uint8_t sendStop)
  • sendStop: 요청 완료 후 정지 메시지 전송 여부 (false: 전송 완료 후 연결 유지. 다른 마스터 장치가 데이터 전송 불가능. 디폴트 true.)
  • RETURN: 전송 상태 메시지 (성공시 0 리턴. 오류 값 리턴)

마스터(ESP8266)가 requsestFrom 함수를 이용하여 특정 주소의 슬레이브에게 지정된 바이트 수만큼 데이터를 요청한 뒤 데이터 수신을 대기한다. 수신 여부는 available 함수를 통해 확인한다.

데이터 수신
uint8_t requestFrom(uint8_t address, uint8_t quantity)
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
  • address: 슬레이브 주소
  • quantity: 요청 바이트 수
  • sendStop: 요청 완료 후 정지 메시지 전송(true, false 전송 유지)
  • RETURN: 슬레이브 장치로부터 전송된 바이트 수

int available(void)
  • RETURN: 버퍼 내 수신된 데이터 바이트 수

int read(void)
  • RETURN: 수신 버퍼의 한 바이틀 읽어서 반환

ESP8266 OLED SSD1306 라이브러리

헤더 파일 추가 및 초기화
#include "SSD1306Wire.h"

SSD1306Wire DISPLAY(0x3c, D3, D5);        // NodeMCU D3 핀과 D5핀을 SDA와 SCL로 설정
// SSD1306Wire DISPLAY(0x3c, SDA, SCL);    // ADDRESS, SDA, SCL

디스플레이 제어
// 디스플레이 초기화
void init();

// 디스플레이가 사용하는 메모리를 비움
void end();

// 초기화 반복
void resetDisplay(void);

// I2C를 이용하여 디스플레이에 다시 연결
void reconnect(void);

// 디스플레이 켜기
void displayOn(void);

// 디스플레이 끄기
void displayOff(void);

// 버퍼를 디스플레이 메모리에 기록 (디스플레이에 출력됨)
void display(void);

// 디스플레이 반전 시킴
void invertDisplay(void);

// 디스플레이 반전 해제
void normalDisplay(void);

// 디스플레이 콘트라스트 조정
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint_8_t comdetect = 64);

// 디스플레이 상하 뒤집기
void flipScreenVertically();

픽셀 그리기
// 색상 지정 (컬러 지원 OLED의 경우)
void setColor(OLEDDISPLAY_COLOR color);

// 좌표 값에 픽셀 그리기
void setPixel(int16_t x, int16_t y);

// 두 좌표 값으로 선 그리기
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);

// 좌표를 기준으로 사각형 그리기
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);

// 좌표를 기준으로 채워진 사각형 그리기
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);

// 원그리기
void drawCircle(int16_t x, int16_t y, int16_t radius);

// 채워진 원그리기
void fillCircle(int16_t x, int16_t y, int16_t radius);

// 가로선 그리기
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);

// 세로선 그리기
void drawVerticalLine(int16_t x, int16_t y, int16_t length);

// 진행바 그리기 (progress 값 0 ~ 100)
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint_t progress);

// 이미지 비트맵 그리기
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);

// XBM 그리기
void drawXBM(int16_t x, int16_t y, int16_t width, int16_t height, const char *xbm);

텍스트 명령
void drawString(int16_t x, int16_t y, String text);

// 정해진 폭 범위 내에 최대한 표시. 주어진 폭 길이보다 넓게 글을 표시할 경우 공백이나 '-' 표시후 개행
void drawStringMaxWidth(int16_t x, int16_t y, int16_t maxLineWidth, String text);

uint16_t getStringWidth(const char* text, uint16_t length);

uint16_t getStringWidth(String text);

// 정렬
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);

// 폰트 설정
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
void setFont(const uint8_t* fontData);

UI 라이브러리 (OLEDDisplayUi)
Ui 라이브러리는 Frame과 Overay라고 하는 기본적인 UI 요소들의 집합으로 구성되어 있다. Frame은 움직이는 화면을 Overay는 정지된 화면을 제어한다.
// 초기화
void init();

// 초당 프레임 수 지정
void setTargetFPS(uint_t fps);

// 프레임 자동 전환
void enableAutoTransition();
void disableAutoTransition();

// 자동 전환 설정시 전환 방향 지정
void setAutoTransitionForwards();
void setAutoTransitionBackwards();

// 시간당 표시 프레임
void setTimePerFrame(uint16_t time);

// 전환 시간
void setTimePerTransition(uint16_t time);

void enalbeIndicator();
void disableIndicator();

void enableAllIndicators();
void disableAllIndicators();

void setIndicatorPosition(IndicatorPosition pos);

void setIndicatorDirection(IndicatorDirection dir);

void setActiveSymbol(const char* symbol);
void setInactiveSymbol(const char* symbol);

void setFrameAnimation(AnimationDirection dir);

void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);

void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);

void setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);

void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);

void nextFrame();
void previousFrame();

void switchToFrame(uint8_t frame);

void transitionToFrame(uint8_t frame);

OLEDDisplayUiState* getUiState();

int8_t update();

댓글

이 블로그의 인기 게시물

아두이노 미세먼지 센서 PM2008

온습도계를 달아봤으니 이참에 미세먼지까지 한꺼번에 표시되도록 기능을 추가해보기로 했다. 마침 아두이노 전용 쉴드까지 제공하는 미세먼지 센서가 눈에 띄길래 일단 구매를 해봤다. 배송받은 센서는 거의 완제품에 가깝게 제작되었다. 다만 아쉬운 점은 아두이노 전용 쉴드의 마감이 좀 지분하다는 느낌을 받았는데, 후처리에 신경을 더 써주는 센스가 부족한 듯. PC2008 미세먼지 센서 아두이노 우노 전용 PM2008 쉴드  부착한 상태는 핀 위치도 잘 맞고 비교적 깔끔한 느낌이다. 쉴드 덕분에 지저분한 배선이 줄어들어 다른 센서들을 붙이기에도 좋을 것 같다. 쉴드와 일체형으로 제작하지 않은 건 라즈베리 파이와 같은 다른 마이크로칩 보드용의 쉴드 제작을 염두에 둔 듯하다. Arduino UNO에 장착한 모습 센서의 작동 테스트를 위해 PM2008 I2C 라이브러리를 추가하여 샘플코드를 실행시켜봤다. 성공적을 테스트를 완료. 이제 공부가 남았을 뿐. Arduino library PM2008 I2C 설치

Adafuit HUZZAH ESP8266 보드를 이용한 Arduino IDE 환경설정하기

 Espressif社의 ESP8266 마이크로컨트롤러는 Arduino 보드에 사용된 AVR 마이크로컨트롤러와 같은 종류이다. 가장 큰 장점은 WiFi 통신이 가능하며, 별도의 추가적인 하드웨어 없이 펌웨어만으로 WiFi 클라이언트와 Access Point 기능을 제공한다는 점이다. 최근 중요한 이슈로 자리잡은 사물인터넷(IoT)을 구현하는데 더없이 좋은 마이크로컨트롤러라 할 수 있다. 게다가 저렴한 가격은 덤! (8,000 ~ 10,000원 정도이니 Arduino UNO 호환보드 가격이다.)  HUZZAH 보드의 특징을 간단히 살펴보면 다음과 같다. Adafruit HUZZAH ESP8266 ESP8266 칩(64KB RAM, 96KB data RAM, 4MB QIO FLASH) 리셋 버튼 프로그램을 업로드하는데 필요한 부트로딩 모드로 전환하기 위한 버튼 프로그래밍 가능한 RED UART 통신 기능 Analog 입력 1개 (최대 1V) GPIO 핀 9개 (3.3V), I2C와 SPI 이용 가능  프로그래밍을 위해 FTDI 연결이 필요하다. 프로그래밍은 Arduino IDE를 사용할 수 있으며, Arduino와 같이 C/C++ 코드를 이용하여 개발이 가능하다. 참고로 Epressif社의 ESP8266 개발보드인 NodeMCU는 루아(LUA)라는 프로그래밍언어를 기본 제공한다. Adafruit社의 HUZZAH 보드는 기본적으로 핀헤더 없이 반제품으로 판매되며 필요에 따라 핀헤더를 직접 납땜해서 부착해야한다. 핀헤더 및 USB 포트를 기본제공하는 개발보드 형태의 제품을 별도로 판매하고 있다. Arduino IDE를 이용하여 프로그래밍을 하기 위해서는 우선 라이브러리에 ESP8266 보드를 추가해야 한다. Arduino IDE에 ESP8266 애드온 설치하기 1. 환경설정에서 "추가적인 보드 매니저 URLs"에 다음 URL을 입력한다. http://arduino.esp8266.com/sta...

Eclipse + JBoss + jBPM 개발환경 설정

상용 개발환경인 JBoss Development Studio 9.0.0 GA 개발환경과 동일한 오픈소스 환경 구성을 목표 Windows 10 64bit JDK 1.8 64bit Eclipse Mars.1 64bit Wildfly 10 (JBoss Application Server) - JDK 1.8 지원 jBPM 6 1. JDK를 내려받아 설치한다. JDK 1.8 - Windows x64  http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2. Eclipse을 내려받아 설치한다. 1) Eclipse IDE for Java EE Developers Windows 64bit 배포판을 내려받는다. http://www.eclipse.org/downloads/ 2) 적당한 디렉터리에 압축을 푼다. Ex) d:\eclipse 3) 압축을 풀어낸 디렉터리에서 eclipse.ini를 찾아 jdk bin 디렉터리의 javaw.exe를 설정한다. [eclipse.ini] -vm C:/Program Files/Java/jdk1.8.0_65/bin/javaw.exe 3. Wildfly를 내려받아 설치한다. 1) Wildfly 10.0.0 최신버전을 내려받는다. http://wildfly.org/downloads/ 2) 적당한 디렉터리에 압축을 푼다. Ex) d:\wildfly 4. Eclipse에 JBoss Tools 4.3.0.Final 플러그인을 설치한다. Help > Install New Software... http://download.jboss.org/jbosstools/mars/stable/updates/  주소를 추가한 후 다음 소프트웨어를 설치한다. JBoss Applicastion Server Adaper JBoss Maven Int...