일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 아두이노 비접촉 온도계
- 온습도 센서
- LGP33
- DHT22
- 0.96 OLED
- 아두이노 나노 호환보드
- 노트북 SSD교체
- AM2302
- 온습도계 만들기
- 비접촉 온도계 만들기
- 노트북 써멀그리스
- 아두이노 OLED
- DS3231 RTC
- 0.96 OLED I2C
- 선반 만들기
- 0.91 OLED
- LGP33 LG노트북
- Windows 10 설치 USB
- MLX90614
- 128x64 OLED
- 아두이노
- 아두이노 시계
- P330-KE1WK
- OLED 시계
- HDD를 SSD로
- 아두이노 온습도계
- 노트북 쿨러(팬) 청소
- MLX90614 온도센서
- Adafruit SSD1306 u8glib
- 비접촉 적외선 온도계
- Today
- Total
K씨의 별별제작소
아두이노로 온습도계만들기 (DHT22 온습도센서, 0.96 OLED) - 2 본문
DHT22온습도센서와 0.96인치 OLED디스플레이를 사용하여
아두이노로 온습도계 만들기를 진행중이다.
이전 글에서 DHT22로 온습도를 측정하고
Adafruit SSD1306 라이브러리를 사용하여 OLED에 온습도를 출력해보았다.
0.96 OLED 디스플레이를 사용하기 위한 라이브러리로 가장 많이 사용되는 것이
Adafruit SSD1306 라이브러리와 U8glib 라이브러리인데
디스플레이에 영문자와 숫자만 표현한다면
Adafruit SSD1306 라이브러리도 괜찮지만
나는 한글을 표현하기 위해
U8glib 라이브러리도 사용해보았다.
이전 글에 이어서 설명함~
( Adafruit SSD1306 라이브러리 대신 U8glib 라이브러리를 사용하고자 한다면
이전 글의 '3. 0.96 OLED 디스플레이에 온습도 출력하기 → 1> 0.96 OLED 연결하기'
이후 '방법1' 대신 아래의 '방법2'를 사용하면 됨. )
"방법2. U8glib 라이브러리 사용"
2-1> U8glib 라이브러리 설치하기
▲ https://code.google.com/archive/p/u8glib/
사이트로 들어가 라이브러리를 다운로드 한다.
▲ 다운받은 라이브러리를 아두이노IDE → 라이브러리 추가한다.
2-2> 예제 실행하기
▲ 파일 → 예제 → U8glib → HelloWorld 를 연다.
▲ 내가 사용하는 디스플레이 부분을 찾아 주석을 지운다.
여기를 지우지 않으면 에러가 발생한다.
▲ 컴파일하고 보드에 업로드하면 Hello World! 글씨가 나타난다.
Adafruit 라이브러리를 사용하는 것에 비해 컴파일 시간이 꽤 오래걸린다.
업로드 도중 오류가 떴는데 보드 연결을 끊었다 다시 연결하고 업로드 하니 해결!
▲ 파일 → 예제 → U8glib → GraphicsTest 예제도 실행해 보았다.
역시 해당 OLED에 해당하는 부분 주석을 지우고 실행해야 한다.
▲ 컴파일에 시간이 오래 걸리지만, 그래픽이 잘 표현된다.
테스트 완료!
2-3> 온도 습도 출력하기
출처: https://blog.naver.com/endearment/221022470002
#include <U8glib.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
// 0.96인치 128x64 OLED
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI
// DHT22 온도/습도 센서
#define DHTPIN 2 // Pin which is connected to the DHT sensor.
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t dht22DelayMS = 0;
void setup() {
dht.begin();
sensor_t sensor;
dht.temperature().getSensor(&sensor);
dht22DelayMS = sensor.min_delay / 1000;
}
void loop() {
float temperature;
float humidity;
getDHT22Data(&temperature, &humidity);
u8g.firstPage();
do {
u8g.setFont(u8g_font_unifont);
u8g.setPrintPos(0, 12);
u8g.print("[Air Pollution]");
u8g.setPrintPos(0, 27);
u8g.print("T : ");
u8g.print(temperature);
u8g.print(" *C");
u8g.setPrintPos(0, 42);
u8g.print("H : ");
u8g.print(humidity);
u8g.print("%");
delay(dht22DelayMS);
} while(u8g.nextPage());
}
void getDHT22Data(float *temperature, float *humidity) {
sensors_event_t event;
dht.temperature().getEvent(&event);
if(!isnan(event.temperature)) {
*temperature = event.temperature;
} else {
*temperature = -1;
}
// Get Humidity
dht.humidity().getEvent(&event);
if (!isnan(event.relative_humidity)) {
*humidity = event.relative_humidity;
} else {
*humidity = -1;
}
}
▲ 이 소스를 업로드해 보았다.
▲ 온도와 습도가 정상적으로 출력된다.
2-4> 온도 습도를 한글로 나타내기
"0.96 OLED에 한글 출력하는 방법"
검색을 통해 한글을 이미지화하여 OLED에 출력하는 방법을 알아냈다.
이렇게 하면 용량을 적게 차지하면서도 원하는 글자와 이미지를 출력할 수 있다.
참고로 한 사이트: https://blog.naver.com/kikch/221193831277
① http://en.radzio.dxp.pl/bitmap_converter/LCDAssistant.zip 에서
프로그램을 다운로드 받아 설치한다.
② '그림판'(윈도우 설치시 기본으로 깔리는 프로그램)을 열고
단색 비트맵 이미지를 만든다.
▲ '크기 조정' 창을 열고 이미지 사이즈를 정해준다.
백분율이 아니라 '픽셀'을 클릭하고,
8의 배수가 되도록 가로 세로 크기를 정해준다.
한글 2자를 표현하기에 가로 40(8x5)픽셀, 세로 24(8x3)픽셀로 하니 적당하였다.
▲ 글자체와 크기를 정하고 글씨를 써준다.
이미지 사이즈가 너무 작아서 불편하니 오른쪽 하단에서 보기 비율을 조정하여 크게 놓고 하면 좋다.
▲ 파일 → 저장을 눌러 창을 띄운다.
▲ 저장시 파일형식을 '단색 비트맵'으로 해준다.
③ LCDAssistant 프로그램으로 '.C' 파일을 만든다.
▲ 처음에 받아둔 LCDAssistant 프로그램을 실행한다.
▲ File → Load Image 를 클릭하고
그림판에서 만든 비트맵 파일을 불러온다.
▲ Horizontal을 선택하고,
Size와 나머지가 위 왼쪽 이미지와 같은지 확인 후
File → Save output 을 선택하여 저장한다.
이때, 파일이름 뒤에 꼭 확장자 c 를 붙여서 저장한다.
▲ 그림판에서 만든 온도, 습도 비트맵 파일과
LCDAssistant 프로그램으로 만든 온도, 습도 .c 파일을 확인할 수 있다.
④ C파일 열어서 스케치프로그램에 복사해 넣기
▲ C파일을 연다. 이때 연결프로그램을 메모장으로 해준다.
▲ 메모장(왼쪽 이미지)의 저 부분을 복사하여
아두이노IDE 스케치 프로그램을 열고
const uint8_t temp[] PROGMEM = {
를 삽입후 메모장에서 복사한 부분을 넣어준다.
(아래 코드 참조)
▲ 온도 습도 이미지가 표시될 부분에 draw();를 넣어주고
void draw(void) { u8g.drawBitmapP(0, 14, 5, 24, temp); 도 삽입해준다.
(아래 코드 참고)
여기서 (0, 14, 5, 24, temp) 부분을 살펴보면
0과 14는 이미지의 위치를 나타내고 (0은 x좌표, 14는 y좌표)
5와 24는 이미지의 크기를 나타내는데,
주의할 점은 이미지의 가로길이(40)를 8로 나눈 값, 즉 40÷8=5를 적고
이미지의 세로픽셀은 그대로 24를 적어야 한다는 것이다.
(그림판에서 그림크기를 가로 40, 세로 24로 만들고
LCDAssistant 프로그램에서도 사이즈를 확인하고 저장했는데
그 사이즈를 알고 있어야 한다.)
▲ 습도 글자도 위와 같은 방법으로 삽입해 준다.
이제 스케치 프로그램을 보드에 업로드해 주면
온도와 습도 글씨가 OLED에 표시된다.
▲ 한글을 넣고 폰트의 크기도 변경하고 위치도 여러번 수정해서
원하는대로 표시되도록 했다.
폰트 바꾸고 특수문자 삽입하는 방법은 다음과 같다.
2-5> 폰트 모양, 크기 바꾸고 특수문자 삽입하기
Adafruit 라이브러리를 사용하면
display.setTextSize(2); 와 같이 1,2,3 등의 숫자를 적어주는 것으로 쉽게 폰트 크기가 변경된다.
하지만, U8glib 라이브러리를 사용할 경우에는
u8g.setFont함수에 글자체와 크기를 적어서 변경해야 한다.
https://github.com/olikraus/u8glib/wiki/fontsize
사이트에 들어가 맘에 드는 폰트의 파란색 글씨 부분을 클릭하면
폰트 이름, 크기 등을 확인할 수 있다.
▲ 나는 온도의 기호를 삽입하기 위해 특수문자가 포함된 u8g_font_fub14 폰트를 사용하기로 하고
스케치 프로그램에 u8g.setFont(u8g_font_fub14);를 삽입했다.
Font data size를 확인해서 가능한 적은 용량의 폰트를 선택하는 것이 좋다.
▲ ':' 부분도 빠져서 삽입해주고
▲ 온도를 표시할 때 필요한 기호도 삽입해주었다.
u8g_font_fub14 폰트 표를 보면 기호(연두색 원부분)가 0xb0 위치에 있는 걸 확인할 수 있다.
그래서 u8g.print("\xb0""C"); 코드를 삽입하면 온도 단위를 표시할 수 있다.
위의 과정들을 거친 최종 코드는 다음과 같다.
#include <U8glib.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
// 0.96인치 128x64 OLED
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI
// DHT22 온도/습도 센서
#define DHTPIN 2 // Pin which is connected to the DHT sensor.
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t dht22DelayMS = 0;
//온도 이미지삽입
const uint8_t temp[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
0x07, 0xFF, 0xC0, 0x07, 0xFF, 0x87, 0xFF, 0xC0, 0x07, 0x01, 0xC7, 0x00, 0x00, 0x07, 0x01, 0xC7,
0x00, 0x00, 0x07, 0xFF, 0xC7, 0x00, 0x00, 0x07, 0xFF, 0x87, 0x00, 0x00, 0x01, 0xFF, 0x07, 0xFF,
0xC0, 0x00, 0x38, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0xC0, 0x38, 0x00, 0x0F, 0xFF, 0xC0, 0x38, 0x00,
0x07, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x07,
0xFF, 0xCF, 0xFF, 0xC0, 0x07, 0xFF, 0xCF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//습도 이미지삽입
const uint8_t hum[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x07, 0xFF, 0xC0, 0x01, 0xFE,
0x07, 0xFF, 0xC0, 0x01, 0xCF, 0x07, 0x00, 0x00, 0x03, 0xC7, 0x87, 0x00, 0x00, 0x07, 0x83, 0xC7,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0F, 0xFF, 0xC7, 0xFF, 0xC0, 0x0F, 0xFF, 0xC7, 0xFF,
0xC0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x03, 0xC0, 0x38, 0x00, 0x07, 0xFF, 0xC0, 0x38, 0x00,
0x07, 0xFF, 0xC0, 0x38, 0x00, 0x07, 0x03, 0xC0, 0x38, 0x00, 0x07, 0xFF, 0xCF, 0xFF, 0xC0, 0x07,
0xFF, 0xCF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void setup() {
dht.begin();
sensor_t sensor;
dht.temperature().getSensor(&sensor);
dht22DelayMS = sensor.min_delay / 1000;
}
void loop() {
float temperature;
float humidity;
getDHT22Data(&temperature, &humidity);
u8g.firstPage();
do {
u8g.setFont(u8g_font_unifont);
u8g.setPrintPos(0, 12);
u8g.print("[Air Pollution]");
draw(); //온도 습도 이미지 출력위해 삽입
u8g.setFont(u8g_font_fub14); //폰트지정
u8g.setPrintPos(35, 35);
u8g.print(": ");
u8g.print(temperature);
u8g.print("\xb0""C"); //온도기호삽입
u8g.setFont(u8g_font_fub14); //폰트지정
u8g.setPrintPos(35, 58);
u8g.print(": ");
u8g.print(humidity);
u8g.print("%");
delay(dht22DelayMS);
} while(u8g.nextPage());
}
void draw(void) { u8g.drawBitmapP(0, 14, 5, 24, temp); //온도글자위해삽입.0과 14는 좌표.5는 비트맵이미지 가로(40)/8한거. 24는 비트맵 세로픽셀
u8g.drawBitmapP(0, 38, 5, 24, hum);} //습도글자위해삽입.0과 38는 좌표.5는 비트맵이미지 가로(40)/8한거. 24는 비트맵 세로픽셀
void getDHT22Data(float *temperature, float *humidity) {
sensors_event_t event;
dht.temperature().getEvent(&event);
if(!isnan(event.temperature)) {
*temperature = event.temperature;
} else {
*temperature = -1;
}
// Get Humidity
dht.humidity().getEvent(&event);
if (!isnan(event.relative_humidity)) {
*humidity = event.relative_humidity;
} else {
*humidity = -1;
}
}
▲ 보드에 위 소스를 업로드하면
온도, 습도가 바르게 표시되는 것을 확인할 수 있다.
컴파일 시간은 좀 오래걸린다.
열나는 노트북 옆에 있어서 온도가 상당히 높게 나오고 있다.
이제 다음 단계로 고고~~
'아두이노 프로젝트' 카테고리의 다른 글
아두이노로 비접촉 온도계 만들기(MLX90614 온도센서, 0.91OLED) (0) | 2018.12.18 |
---|---|
아두이노로 온습도계만들기- 시계추가 (DHT22 온습도센서, 0.96 OLED, DS3231 RTC) (3) | 2018.11.28 |
아두이노로 온습도계만들기 (DHT22 온습도센서, 0.96 OLED) - 1 (0) | 2018.11.23 |
아두이노로 시계만들기 (DS3231 RTC, 7세그먼트 TM1637) (1) | 2018.11.07 |
아두이노 IDE (스케치 프로그램) 설치하기 (0) | 2018.10.02 |