온도 표시

온도에 대해서 알아본 것과 디스플레이를 함께 적용하여 온도와 현재 설정을 디스플레이로 보여주도록 구현하는 것이 목표입니다.

먼저 필요한 온도 테이블 배열을 추가하도록 하겠습니다.
 1#include "ssd1306.h" // 라이브러리 포함
 2
 3#define BTN_A       8     // A버튼
 4#define BTN_B       7     // B버튼
 5#define BTN_C       11    // C버튼
 6#define BTN_D       12    // D버튼
 7
 8#define MOTOR_EN    5     // 모터 활성화 핀
 9#define MOTOR_DIR   6     // 모터 방향 핀
10#define MOTOR_SPEED 10    // 모터 속도 핀
11
12#define HEATER_EN   9     // 열선 핀
13
14#define TEMP_IN     A0    // 온도 읽는 핀
15
16/*
17 *  온도 테이블 배열
18 *  첫번째 항목은 신호 값, 두번째 항목은 온도 값
19 */
20int temptable[23][2] = {
21    {1023,0},
22    {1022,10},
23    {1020,20},
24    {1016,30},
25    {1011,40},
26    {1009,50},
27    {1006,60},
28    {1004,70},
29    {1000,80},
30    {990,90},
31    {983,100},
32    {976,110},
33    {972,120},
34    {964,130},
35    {955,140},
36    {942,150},
37    {929,160},
38    {910,170},
39    {895,180},
40    {864,190},
41    {839,200},
42    {800,210},
43    {744,220}
44};
45
46void setup()
47{
48    pinMode(BTN_A, INPUT_PULLUP);
49    pinMode(BTN_B, INPUT_PULLUP);
50    pinMode(BTN_C, INPUT_PULLUP);
51    pinMode(BTN_D, INPUT_PULLUP);
52
53    pinMode(MOTOR_EN, OUTPUT);
54    pinMode(MOTOR_DIR, OUTPUT);
55    pinMode(MOTOR_SPEED, OUTPUT);
56
57    pinMode(HEATER_EN, OUTPUT);
58
59    digitalWrite(MOTOR_EN, HIGH); // 모터 활성화
60
61    ssd1306_128x32_i2c_init(); // 32로 변경
62    ssd1306_fillScreen(0x00);  // 화면 초기화
63    ssd1306_setFixedFont(ssd1306xled_font6x8); // 폰트 설정
64    ssd1306_flipHorizontal(1); // x 화면 대칭 회전
65    ssd1306_flipVertical(1);   // y 화면 대칭 회전
66}
67
68void loop()
69{
70
71}
이어서 디스플레이에 글자를 표시하는 코드를 작성해야 합니다. 이 코드는 작성해놓으면 자주 사용될것 같으니 함수로 만들어 줍니다.
1void showTextToScreen(int x, int y, String text)
2{
3    text = text + "\n";
4    char ch[10];
5    text.toCharArray(ch,text.length());
6    ssd1306_printFixedN(x, y, ch, STYLE_NORMAL, FONT_SIZE_2X);
7}
디스플레이의 어디 부분에 표시될지를 x, y로 결정하고, 문자는 text 변수로 설정합니다.

위 코드에 이 함수를 추가하고, 온도를 읽고 디스플레이에 표시하는 코드를 작성해봅니다.
아래 코드에서는 온도를 읽는 부분도 함수로 추가하였습니다.
  1#include "ssd1306.h" // 라이브러리 포함
  2
  3#define BTN_A           8     // A버튼
  4#define BTN_B           7     // B버튼
  5#define BTN_C           11    // C버튼
  6#define BTN_D           12    // D버튼
  7
  8#define MOTOR_EN        5     // 모터 활성화 핀
  9#define MOTOR_DIR       6     // 모터 방향 핀
 10#define MOTOR_SPEED     10    // 모터 속도 핀
 11
 12#define HEATER_EN       9     // 열선 핀
 13
 14#define TEMP_IN         A0    // 온도 읽는 핀
 15
 16#define VALUE_TEMPTB    0     // 온도 테이블의 신호 값 인덱스
 17#define CELSIUS_TEMPTB  1     // 온도 테이블의 온도 값 인덱스
 18
 19String strToShow; // 디스플레이에 보여줄 문자열을 저장하는 변수
 20
 21int curTemp = 0; // 현재온도
 22
 23/*
 24 *  온도 테이블 배열
 25 *  첫번째 항목은 신호 값, 두번째 항목은 온도 값
 26 */
 27int temptable[23][2] = {
 28    {1023,0},
 29    {1022,10},
 30    {1020,20},
 31    {1016,30},
 32    {1011,40},
 33    {1009,50},
 34    {1006,60},
 35    {1004,70},
 36    {1000,80},
 37    {990,90},
 38    {983,100},
 39    {976,110},
 40    {972,120},
 41    {964,130},
 42    {955,140},
 43    {942,150},
 44    {929,160},
 45    {910,170},
 46    {895,180},
 47    {864,190},
 48    {839,200},
 49    {800,210},
 50    {744,220}
 51};
 52
 53/*
 54 * 입력받은 문자를 디스플레이 좌표에 표시
 55 */
 56void showTextToScreen(int x, int y, String text)
 57{
 58    text = text + "\n";
 59    char ch[10];
 60    text.toCharArray(ch,text.length());
 61    ssd1306_printFixedN(x, y, ch, STYLE_NORMAL, FONT_SIZE_2X);
 62}
 63
 64/*
 65 * checkA0 함수로 온도를 읽고, 정확한 온도로 계산 후
 66 * 결과 값을 화면에 표시하고 반환하는 함수
 67 * VALUE_TEMPTB = 0, CELSIUS_TEMPTB = 1 으로 온도표의 각 항목을 지시함
 68 */
 69int getTemperature()
 70{
 71    float ratioTemp;
 72    float tempADU = analogRead(A0);
 73    int result;
 74
 75    for(int i=1; i<23; i++){
 76        if(tempADU >= temptable[i][VALUE_TEMPTB])
 77        {
 78            ratioTemp = (tempADU - temptable[i][VALUE_TEMPTB])/(temptable[i-1][VALUE_TEMPTB] - temptable[i][VALUE_TEMPTB]);
 79
 80            result = temptable[i][CELSIUS_TEMPTB] - ratioTemp*(temptable[i][CELSIUS_TEMPTB] - temptable[i-1][CELSIUS_TEMPTB]);
 81
 82            strToShow = String(result);
 83
 84            showTextToScreen(0,0,strToShow);
 85
 86            return result;
 87        }
 88    }
 89
 90    return ;
 91}
 92
 93void setup()
 94{
 95    pinMode(BTN_A, INPUT_PULLUP);
 96    pinMode(BTN_B, INPUT_PULLUP);
 97    pinMode(BTN_C, INPUT_PULLUP);
 98    pinMode(BTN_D, INPUT_PULLUP);
 99
100    pinMode(MOTOR_EN, OUTPUT);
101    pinMode(MOTOR_DIR, OUTPUT);
102    pinMode(MOTOR_SPEED, OUTPUT);
103
104    pinMode(HEATER_EN, OUTPUT);
105
106    digitalWrite(MOTOR_EN, HIGH); // 모터 활성화
107
108    ssd1306_128x32_i2c_init(); // 32로 변경
109    ssd1306_fillScreen(0x00);  // 화면 초기화
110    ssd1306_setFixedFont(ssd1306xled_font6x8); // 폰트 설정
111    ssd1306_flipHorizontal(1); // x 화면 대칭 회전
112    ssd1306_flipVertical(1);   // y 화면 대칭 회전
113}
114
115void loop()
116{
117    curTemp = getTemperature();
118}

getTemperature 로 온도를 계산하는 함수를 따로 만들었기 때문에 마지막 loop 함수는 간단해 졌습니다.
온도 챕터에서 작업했던 코드와 마찬가지로 온도측정 함수를 따로 작성하고, bool isHigherTemp 변수를 추가하였습니다.
아래는 업로드를 한 결과 입니다.

../../_images/Step2_1.gif

위 영상과 같이 숫자가 너무 빨리 바뀌고, 일정하지 않은 점이 있습니다.
loop의 2개의 함수를 50ms 마다 1번씩 작동하도록 작성해봅니다.

  1#include "ssd1306.h" // 라이브러리 포함
  2
  3#define BTN_A           8     // A버튼
  4#define BTN_B           7     // B버튼
  5#define BTN_C           11    // C버튼
  6#define BTN_D           12    // D버튼
  7
  8#define MOTOR_EN        5     // 모터 활성화 핀
  9#define MOTOR_DIR       6     // 모터 방향 핀
 10#define MOTOR_SPEED     10    // 모터 속도 핀
 11
 12#define HEATER_EN       9     // 열선 핀
 13
 14#define TEMP_IN         A0    // 온도 읽는 핀
 15
 16#define VALUE_TEMPTB    0     // 온도 테이블의 신호 값 인덱스
 17#define CELSIUS_TEMPTB  1     // 온도 테이블의 온도 값 인덱스
 18
 19String strToShow; // 디스플레이에 보여줄 문자열을 저장하는 변수
 20
 21bool isHeating = false; // 온도가 목표보다 높은지 확인하는 bool 변수
 22
 23int curTemp = 0; // 현재온도
 24
 25long timeInterval = millis(); // 50ms 에 1회씩 작동하기 위한 시간 변수
 26
 27/*
 28 *  온도 테이블 배열
 29 *  첫번째 항목은 신호 값, 두번째 항목은 온도 값
 30 */
 31int temptable[23][2] = {
 32    {1023,0},
 33    {1022,10},
 34    {1020,20},
 35    {1016,30},
 36    {1011,40},
 37    {1009,50},
 38    {1006,60},
 39    {1004,70},
 40    {1000,80},
 41    {990,90},
 42    {983,100},
 43    {976,110},
 44    {972,120},
 45    {964,130},
 46    {955,140},
 47    {942,150},
 48    {929,160},
 49    {910,170},
 50    {895,180},
 51    {864,190},
 52    {839,200},
 53    {800,210},
 54    {744,220}
 55};
 56
 57/*
 58 * 입력받은 문자를 디스플레이 좌표에 표시
 59 */
 60void showTextToScreen(int x, int y, String text)
 61{
 62    text = text + "\n";
 63    char ch[10];
 64    text.toCharArray(ch,text.length());
 65    ssd1306_printFixedN(x, y, ch, STYLE_NORMAL, FONT_SIZE_2X);
 66}
 67
 68/*
 69 * 온도를 읽고, 정확한 온도로 계산 후 결과 값을 화면에 표시하고 반환하는 함수
 70 * VALUE_TEMPTB = 0, CELSIUS_TEMPTB = 1 으로 온도표의 각 항목을 지시함
 71 */
 72int getTemperature()
 73{
 74    float ratioTemp;
 75    float tempADU = analogRead(A0);
 76    int result;
 77
 78    for(int i=1; i<23; i++){
 79        if(tempADU >= temptable[i][VALUE_TEMPTB])
 80        {
 81            ratioTemp = (tempADU - temptable[i][VALUE_TEMPTB])/(temptable[i-1][VALUE_TEMPTB] - temptable[i][VALUE_TEMPTB]);
 82
 83            result = temptable[i][CELSIUS_TEMPTB] - ratioTemp*(temptable[i][CELSIUS_TEMPTB] - temptable[i-1][CELSIUS_TEMPTB]);
 84
 85            strToShow = String(result);
 86
 87            showTextToScreen(0,0,strToShow);
 88
 89            return result;
 90        }
 91    }
 92
 93    return ;
 94}
 95
 96void setup()
 97{
 98    pinMode(BTN_A, INPUT_PULLUP);
 99    pinMode(BTN_B, INPUT_PULLUP);
100    pinMode(BTN_C, INPUT_PULLUP);
101    pinMode(BTN_D, INPUT_PULLUP);
102
103    pinMode(MOTOR_EN, OUTPUT);
104    pinMode(MOTOR_DIR, OUTPUT);
105    pinMode(MOTOR_SPEED, OUTPUT);
106
107    pinMode(HEATER_EN, OUTPUT);
108
109    digitalWrite(MOTOR_EN, HIGH); // 모터 활성화
110
111    ssd1306_128x32_i2c_init(); // 32로 변경
112    ssd1306_fillScreen(0x00);  // 화면 초기화
113    ssd1306_setFixedFont(ssd1306xled_font6x8); // 폰트 설정
114    ssd1306_flipHorizontal(1); // x 화면 대칭 회전
115    ssd1306_flipVertical(1);   // y 화면 대칭 회전
116}
117
118void loop()
119{
120    if(millis() - timeInterval > 50)
121    {
122        curTemp = getTemperature();
123
124        timeInterval = millis();
125    }
126}
아직도 빠르긴 하지만 그나마 알아볼 수 있는 정도가 되었습니다.