공기청정기 프로젝트
[0x02] 2.42 Inch OLED Display 사용하기
jemin0619
2024. 5. 1. 11:21
https://www.devicemart.co.kr/goods/view?no=12525556
작년에 한 번 써봐서 사용하는데 어렵진 않았습니다.
아두이노용 OLED의 통신 방법에는 I2C와 SPI가 있습니다.
간단하게 SPI는 7핀, I2C는 4핀으로 보시면 될 것 같습니다.
대부분의 OLED는 I2C 통신을 지원하기에 해당 제품으로 구매했습니다.
물론 I2C가 항상 좋은 것은 아닙니다. 속도는 SPI가 더 낫다는 말도 있습니다.
해당 제품엔 RES핀이 붙어있는데 해당 핀은 무시해도 되는 것 같습니다.
Vcc 5V
Gnd Gnd
SDA 20
SCL 21
RES X
전에 PM2008M 미세먼지 센서도 I2C 통신이기에 SDA SCL이 겹쳐서 고민이었는데 병렬로 연결해도 문제가 없었습니다.
아두이노에서 OLED를 제어하는 라이브러리에는 Adafruit과 u8glib이 있습니다.
기능은 Adafruit이 많긴 하지만 간단한 프로젝트이기에 u8glib을 선택했습니다.
아래 코드는 u8glib을 사용해 OLED에 Progress Bar을 띄우는 코드입니다.작년에 테스트 용으로 확인한 코드라 출처는 잘 모르겠습니다...
#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // 4핀 OLED 디스플레이에 대한 I2C 통신 설정
int progress = 0;
void setup() {
u8g.setFont(u8g_font_7x13B);
u8g.setColorIndex(1); // set color to white
}
void loop(){
//test code
u8g.firstPage();
do{
u8g.drawStr(20,50,"Now Loading...");
//u8g.drawFrame(0, 10, 128, 20);
u8g.drawBox(10, 15, progress, 10);
}while(u8g.nextPage());
if(progress<100){
progress++;
}else{
progress = 0;
}
}
이전에 했던 미세먼지 센서 코드와 합쳐서 테스트용 코드를 작성해보았습니다.
후에 UI는 개선을 할 생각입니다.
더보기
#include <pm2008_i2c.h>
#include "U8glib.h"
// #define PM2008N
PM2008_I2C pm2008_i2c;
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
int getAirState(){
uint8_t ret = pm2008_i2c.read();
uint8_t pm1p0_grade = 0;
uint8_t pm2p5_grade = 0;
uint8_t pm10p_grade = 0;
uint8_t total_grade = 0;
if (ret == 0) {
// PM 1.0
if (pm2008_i2c.pm1p0_grimm < 16) {
pm1p0_grade = 1;
} else if (pm2008_i2c.pm1p0_grimm < 51) {
pm1p0_grade = 2;
} else if (pm2008_i2c.pm1p0_grimm < 101) {
pm1p0_grade = 3;
} else {
pm1p0_grade = 4;
}
// PM 2.5
if (pm2008_i2c.pm2p5_grimm < 16) {
pm2p5_grade = 1;
} else if (pm2008_i2c.pm2p5_grimm < 51) {
pm2p5_grade = 2;
} else if (pm2008_i2c.pm2p5_grimm < 101) {
pm2p5_grade = 3;
} else {
pm2p5_grade = 4;
}
// PM 10
if (pm2008_i2c.pm10_grimm < 31) {
pm10p_grade = 1;
} else if (pm2008_i2c.pm10_grimm < 81) {
pm10p_grade = 2;
} else if (pm2008_i2c.pm10_grimm < 151) {
pm10p_grade = 3;
} else {
pm10p_grade = 4;
}
// Get worst grade
total_grade = max(pm1p0_grade, pm2p5_grade);
total_grade = max(total_grade, pm10p_grade);
switch (total_grade) {
case 1: {
Serial.println("Good!");
return 1;
break;
}
case 2: {
Serial.println("Normal!");
return 2;
break;
}
case 3: {
Serial.println("Bad!");
return 3;
break;
}
case 4: {
Serial.println("Worst!");
return 4;
break;
}
default:
break;
}
}
}
void setup() {
// wait for PM2008N to be changed to I2C mode
#ifdef PM2008N
delay(10000);
#endif
pm2008_i2c.begin();
Serial.begin(9600);
pm2008_i2c.command();
u8g.setFont(u8g_font_7x13B);
u8g.setColorIndex(1); // set color to white
delay(1000);
}
void loop() {
u8g.firstPage();
do{
int state = getAirState();
delay(100);
if(state==1) u8g.drawStr(20,50,"Good");
if(state==2) u8g.drawStr(20,50,"Normal");
if(state==3) u8g.drawStr(20,50,"Bad");
if(state==4) u8g.drawStr(20,50,"Worst");
}while(u8g.nextPage());
delay(3000);
}