u8glib 라이브러리 사용하기

    

`U8glib` 라이브러리를 사용하는 기본적인 방법은 다음과 같습니다. 이 예시는 아두이노에서 U8glib를 사용하여 OLED 디스플레이에 그래픽과 텍스트를 표시하는 간단한 과정을 보여줍니다.


### 1. 라이브러리 설치

- 아두이노 IDE에서 "도구" > "라이브러리 관리"로 가서 `U8glib`를 검색하고 설치합니다.


### 2. 라이브러리 포함

- 아두이노 스케치의 시작 부분에 `U8glib` 라이브러리를 포함시킵니다.

  ```cpp

  #include <U8glib.h>

  ```


### 3. 디스플레이 객체 생성

- 사용 중인 OLED 디스플레이에 맞는 객체를 생성합니다. 객체 생성 시 사용하는 생성자는 디스플레이 및 사용 중인 통신 프로토콜(I2C 또는 SPI)에 따라 달라집니다.

  ```cpp

  U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // 예시로 SH1106 128x64 디스플레이 사용

  ```


### 4. 기본 스케치 코드

- `setup()` 함수와 `loop()` 함수 안에 코드를 작성합니다.

  ```cpp

  void setup() {

    // 초기화, 필요한 경우 여기에 코드 추가

  }


  void loop() {

    // 디스플레이 버퍼 지우기

    u8g.firstPage();

    do {

      draw(); // 그리기 함수 호출

    } while (u8g.nextPage());

    

    // 필요한 경우 여기에 추가 코드 추가

    delay(1000); // 1초 대기

  }


  void draw() {

    // 여기에 디스플레이에 그릴 내용을 작성

    u8g.setFont(u8g_font_unifont); // 폰트 설정

    u8g.drawStr(0, 22, "Hello World!"); // 텍스트 그리기

  }

  ```


### 주의 사항

- 디스플레이 모델과 사양에 따라 생성자를 올바르게 선택해야 합니다.

- `draw()` 함수 내에서 텍스트, 그래픽 등을 그립니다. U8glib는 페이지 버퍼 방식을 사용하므로 `u8g.firstPage()`와 `u8g.nextPage()`를 사용하여 전체 화면을 갱신합니다.

- U8glib는 다양한 그래픽 함수를 제공합니다. 예를 들어, 선, 원, 사각형을 그릴 수 있고, 다양한 폰트를 사용할 수 있습니다.


`U8glib` 라이브러리 몇 가지 주요 함수:


### 1. 초기화 및 설정 관련 함수

- `U8GLIB`: 디스플레이 객체를 생성하는 생성자 함수.

- `setFont`: 사용할 폰트를 설정합니다.

- `setColorIndex`: 그리기에 사용할 색상의 인덱스를 설정합니다.


### 2. 텍스트 관련 함수

- `drawStr`: 지정된 위치에 문자열을 그립니다.

- `setPrintPos`: 텍스트를 출력할 위치를 설정합니다.


### 3. 그래픽 관련 함수

- `drawBox`: 지정된 위치에 박스(사각형)을 그립니다.

- `drawFrame`: 지정된 위치에 빈 사각형(테두리만 있는)을 그립니다.

- `drawCircle`: 지정된 위치에 원을 그립니다.

- `drawDisc`: 지정된 위치에 채워진 원을 그립니다.

- `drawEllipse`: 타원을 그립니다.

- `drawLine`: 두 점을 잇는 선을 그립니다.

- `drawPixel`: 지정된 위치에 픽셀(점)을 그립니다.

- `drawTriangle`: 세 점을 연결하는 삼각형을 그립니다.


### 4. 이미지 관련 함수

- `drawBitmap`: 비트맵 이미지를 그립니다.

- `drawXBM`: XBM 형식의 비트맵 이미지를 그립니다.


### 5. 페이지 버퍼 관련 함수

- `firstPage`: 디스플레이의 첫 페이지를 준비합니다.

- `nextPage`: 다음 페이지를 준비하고, 모든 페이지가 렌더링될 때까지 반복합니다.


### 예시 코드

```cpp

void draw() {

  u8g.setFont(u8g_font_unifont); // 폰트 설정

  u8g.drawStr(0, 20, "Hello World!"); // 텍스트 출력


  u8g.drawBox(10, 30, 20, 10); // 박스 그리기

  u8g.drawFrame(40, 30, 20, 10); // 빈 사각형 그리기


  u8g.drawCircle(30, 50, 10); // 원 그리기

  u8g.drawLine(0, 0, 40, 40); // 선 그리기

}

```


`U8glib`가 페이지 버퍼 방식을 사용한다는 것은 이 라이브러리가 디스플레이의 내용을 업데이트할 때 전체 화면을 한 번에 그리지 않고, 화면을 여러 "페이지"로 나누어 각 페이지를 차례대로 그린다는 의미입니다. 이 방식의 주요 특징과 이점은 다음과 같습니다:


### 페이지 버퍼 방식의 특징

- **부분적 업데이트**: 화면은 여러 페이지로 나뉘며, 각 페이지는 화면의 일부 영역에 해당합니다. 이러한 방식은 디스플레이의 전체 화면을 한 번에 메모리에 저장할 필요가 없게 해줍니다.

- **메모리 절약**: 페이지 버퍼 방식은 전체 프레임 버퍼 방식에 비해 적은 양의 RAM을 사용합니다. 이는 특히 메모리가 제한적인 마이크로컨트롤러 환경에서 유리합니다.


### 작동 방식

- `firstPage()` 함수를 호출하여 첫 번째 페이지의 그리기를 시작합니다.

- `draw()` 함수 내에서 디스플레이에 그릴 내용을 정의합니다.

- `nextPage()` 함수를 호출하여 다음 페이지로 이동하고, 화면의 다음 부분을 그립니다.

- 이 과정을 화면의 모든 부분이 그려질 때까지 반복합니다.


### 예시

```cpp

void loop() {

  u8g.firstPage();  

  do {

    draw();  // 디스플레이에 그릴 내용을 정의하는 함수

  } while ( u8g.nextPage() );  // 모든 페이지를 그릴 때까지 반복

}

```


### 이점

- **메모리 효율성**: 마이크로컨트롤러의 제한된 RAM에서도 대형 디스플레이를 사용할 수 있습니다.

- **유연성**: 화면의 일부만 업데이트할 수 있어서, 전체 화면을 갱신하는 것보다 더 빠를 수 있습니다.


단, 페이지 버퍼 방식은 전체 화면을 한 번에 업데이트하는 방식보다 구현이 조금 더 복잡할 수 있으며, 화면 전체를 갱신하는 데 시간이 조금 더 걸릴 수 있습니다. 그러나 메모리 사용 측면에서의 이점이 크기 때문에, 특히 아두이노와 같은 메모리 제한이 있는 환경에서 매우 유용합니다.


`U8glib`에서 "다음 페이지"가 어떻게 저장되는지 이해하기 위해서는 먼저 라이브러리가 어떻게 페이지 버퍼를 관리하는지 알아야 합니다. `U8glib`는 디스플레이의 내용을 RAM에 임시로 저장하는데, 이 때 전체 화면을 한 번에 저장하지 않고, 화면을 여러 '페이지'로 나누어 각 페이지를 순차적으로 처리합니다. 이 방식의 주요 특징은 다음과 같습니다:


### 페이지 버퍼의 관리

- **분할된 저장 공간**: 전체 화면을 한 번에 RAM에 저장하는 대신, `U8glib`는 화면을 여러 '페이지'로 나누어 각 페이지를 별도로 저장합니다. 이는 디스플레이의 일부분만을 한 번에 메모리에 저장하는 방식으로, 메모리 사용을 최소화합니다.

- **순차적 처리**: `U8glib`는 설정된 페이지 버퍼 크기에 따라 디스플레이의 일부분(한 페이지)을 메모리에 저장하고, 그 페이지를 디스플레이에 그린 후, 다음 페이지로 넘어갑니다.


### `nextPage()` 함수의 역할

- `nextPage()` 함수는 현재 페이지의 그리기 작업이 완료되면 다음 페이지로 넘어가는 역할을 합니다.

- 이 함수는 내부적으로 '현재 페이지'의 정보를 관리하며, 다음 페이지로 넘어갈 때 마다 이 정보를 업데이트합니다.

- 또한, 현재 처리 중인 페이지의 정보를 바탕으로 RAM에 저장된 페이지 데이터를 디스플레이 하드웨어로 전송합니다.


### 메모리 저장 방식

- **임시 저장**: 각 페이지의 데이터는 임시로 RAM에 저장됩니다. 이 데이터는 그 페이지에 그릴 내용(텍스트, 그래픽 등)을 나타냅니다.

- **하드웨어 전송**: 각 페이지가 RAM에 저장된 후, 그 데이터는 디스플레이 하드웨어로 전송되어 화면에 표시됩니다.


### 작업 흐름

1. `firstPage()`를 호출하여 첫 페이지로 시작합니다.

2. `draw()` 함수에서 해당 페이지를 그립니다.

3. `nextPage()`가 호출되면, 현재 페이지의 내용을 디스플레이에 전송하고, 다음 페이지로 넘어갑니다.

4. 이 과정이 모든 페이지에 대해 반복되며, 전체 화면이 그려집니다.


`U8glib`의 이런 방식은 특히 메모리가 제한된 시스템에서 전체 화면을 효과적으로 관리할 수 있게 해주며, 디스플레이의 전체 내용을 갱신하는데 필요한 메모리 요구량을 최소화합니다. 


`U8glib`에서 "다음 페이지가 있다"는 것은 페이지 버퍼 방식을 사용하여 디스플레이의 내용을 업데이트할 때, 전체 화면을 여러 부분(페이지)으로 나누어 순차적으로 처리해야 한다는 의미입니다. 각 "페이지"는 디스플레이의 일부 영역을 나타내며, 이러한 페이지들을 차례대로 처리함으로써 전체 화면이 구성됩니다. "다음 페이지가 있다"는 말은 아직 그려야 할 페이지가 더 남아있다는 것을 의미합니다.


### 페이지 버퍼 방식의 작동 원리

- **화면 분할**: 디스플레이 화면은 여러 개의 수평 또는 수직 "페이지"로 나뉩니다. 각 페이지는 화면의 한 부분을 차지합니다.

- **순차적 업데이트**: 프로그램은 첫 번째 페이지부터 시작하여 각 페이지를 순차적으로 그립니다. 각 페이지가 그려진 후에는 다음 페이지로 넘어갑니다.


### `nextPage()` 함수의 역할

- **페이지 전환**: `nextPage()` 함수는 현재 페이지가 완전히 그려진 후 다음 페이지로 넘어가도록 합니다. 이 함수는 더 이상 그려야 할 페이지가 있으면 `true`를 반환하고, 모든 페이지가 그려졌다면 `false`를 반환합니다.

- **루프 제어**: 이 함수는 `do-while` 루프 내에서 사용되어, 더 이상 그려야 할 페이지가 없을 때까지 루프를 계속합니다.


### 예시

```cpp

do {

    draw(); // 현재 페이지 그리기

} while ( u8g.nextPage() ); // 다음 페이지로 넘어가기

```

- 위 코드에서 `draw()` 함수는 현재 페이지에 그릴 내용을 정의합니다.

- `nextPage()`는 다음 페이지로 넘어갈 준비를 하고, 더 이상 페이지가 없으면 루프를 종료합니다.


이 방식은 특히 메모리가 제한된 마이크로컨트롤러 환경에서 유용하며, 전체 화면을 메모리에 한 번에 저장하지 않고도 디스플레이 내용을 효과적으로 업데이트할 수 있게 해줍니다.


`U8glib`를 사용하는 경우 `draw()` 함수로 한 번에 전체 화면을 그리지 않습니다. 대신, 이 라이브러리는 페이지 버퍼 방식을 사용하여 화면을 여러 개의 "페이지"로 나누고, 각 페이지를 차례대로 그립니다. 이는 디스플레이의 각 부분(페이지)을 순차적으로 처리하여 전체 화면을 구성하는 방식입니다.


### 페이지 버퍼 방식의 작동 원리

- **분할된 화면**: 디스플레이는 여러 페이지로 나뉘어 있으며, 각 페이지는 화면의 일부분을 차지합니다.

- **순차적 그리기**: `draw()` 함수는 현재 활성화된 페이지에 내용을 그립니다. 이 함수는 `u8g.firstPage()`를 호출한 후 `u8g.nextPage()`가 `false`를 반환할 때까지, 즉 모든 페이지가 그려질 때까지 반복적으로 호출됩니다.


### 예시

```cpp

void loop() {

  u8g.firstPage();

  do {

    draw(); // 현재 페이지를 그림

  } while ( u8g.nextPage() ); // 다음 페이지가 있으면 계속 반복

}

```

- 여기서 `draw()` 함수는 각 페이지에 대해 한 번씩 호출됩니다.

- 각 호출에서 `draw()`는 현재 페이지의 일부분만 그립니다.

- `nextPage()`는 다음 페이지로 넘어가는데, 이는 다음 `draw()` 호출이 다음 페이지의 일부분을 그리게 합니다.

- 이렇게 모든 페이지가 그려질 때까지 반복됩니다.


### 그리기 방식의 장점

- **메모리 효율**: 전체 화면을 메모리에 저장할 필요가 없어, 메모리 사용량이 줄어듭니다. 이는 특히 메모리가 제한된 마이크로컨트롤러에서 중요합니다.

- **유연성**: 페이지 단위로 화면을 업데이트할 수 있어, 복잡한 그래픽이나 텍스트를 메모리 제한 내에서 효과적으로 표현할 수 있습니다.


따라서 `U8glib`의 `draw()` 함수는 전체 화면을 한 번에 그리지 않고, 페이지 단위로 화면을 나누어 순차적으로 그리는 방식을 사용합니다. 이는 더 적은 메모리로 더 큰 디스플레이를 관리할 수 있게 해줍니다.



`U8glib` 라이브러리에서 `draw()` 함수 내에서 그래픽이나 텍스트를 그릴 때, 사용자는 버퍼 설정과 같은 저수준의 세부 사항을 신경 쓰지 않아도 됩니다. 이는 `U8glib`의 내부 구현 덕분에 가능한데, 라이브러리가 자동으로 페이지 버퍼를 관리하고, 사용자가 `draw()` 함수에 작성한 그래픽 명령들을 이 버퍼에 적절하게 배치합니다. 


### `U8glib`의 내부 작동 방식


1. **자동 버퍼 관리**: `U8glib`는 현재 활성화된 페이지에 대한 버퍼를 내부적으로 관리합니다. 이 버퍼는 디스플레이의 해당 페이지 부분에 해당하는 메모리 영역을 나타냅니다.


2. **그래픽 명령의 처리**: `draw()` 함수에서 사용자가 그래픽 명령(예: 텍스트 그리기, 도형 그리기)을 호출할 때, 이 명령들은 현재 활성화된 페이지의 버퍼에 적용됩니다. 


3. **페이지 순회**: `do-while` 루프와 `nextPage()` 함수를 사용함으로써, `U8glib`는 각 페이지를 차례대로 활성화하고, 각 페이지에 대해 `draw()` 함수를 호출하여 그래픽 명령들을 해당 페이지 버퍼에 적용합니다.


4. **디스플레이 업데이트**: 각 페이지의 그래픽 명령이 버퍼에 적용된 후, `U8glib`는 이 버퍼의 내용을 디스플레이 하드웨어로 전송합니다. 이 과정은 모든 페이지에 대해 반복됩니다.


### 사용자 경험

- 사용자는 `draw()` 함수 내에서 그리고자 하는 내용을 정의하기만 하면 됩니다. 예를 들어, 텍스트를 출력하거나 도형을 그리는 명령을 포함시킵니다.

- `U8glib`의 내부 로직이 페이지 버퍼를 관리하고, 사용자의 그래픽 명령을 적절한 페이지에 배치하며, 이를 디스플레이에 순차적으로 표시합니다.


이런 방식으로 `U8glib`는 사용자에게 간결하고 직관적인 프로그래밍 인터페이스를 제공하면서도, 메모리 효율적인 디스플레이 업데이트를 구현합니다. 사용자는 복잡한 버퍼 관리나 페이지 관리에 대해 걱정할 필요 없이, 원하는 그래픽 출력을 쉽게 구현할 수 있습니다.




---

페이지 버퍼 방식으로 업데이트 되므로

무조건

u8g.firstPage();  

  do {

//그리는 함수

  } while ( u8g.nextPage() ); 

이런 형태가 필요하다.

화면은 여러 페이지로 쪼개서 램에 순차적으로 올려서 순차적으로 그리는 건데

do while 동안 다음페이지 있나 보고 그리는 거다


Adafruit_SSD1306은 회전 기능 지원했는데

u8glib 여긴 없...는줄 알았는데 있다. 챗지피티가 잘못알려줬네

위키는 이쪽

https://github.com/olikraus/u8glib/wiki/userreference


색깔 바꾸기

setDefaultBackgroundColor

setDefaultForegroundColor

u8g.setColorIndex(0);




drawBitmap

drawBitmapP

progmem 저장이면 drawBitmapP이거 써야한다

drawBitmap 쓰면 쓰레기값 출력한거처럼 나옴.


u8g.drawBitmapP((display_width - 64) / 2, (display_height - 96+2) , 8, 96, character_bitmap);

세번째 변수가 바이트로 적어야해서(비트/8) 좀 독특하다.

x, y, 너비(바이트=비트수/8), 높이(그냥 바이트로), 비트맵

순으로 적어야해서 이상하다.


페이지 버퍼 방식때문에 너무 느린 것이 문제가 된다

화면 넘어가는 부분이 그냥 보인다..

화면이 순차적으로 그려지는게 그냥 보여서 아무래도 좀 별로였다



-> u8g2로 옮겨보기로 결정




댓글

이 블로그의 인기 게시물

js 스트링에서 요소 갯수 세기

STUDY

javascript cheatsheet