#include <TFT.h> // Arduino LCD library #include <SPI.h> #define MAX_LINE 13 #define MAX_LEN 30 // pin definition for the Uno #define cs 10 #define dc 9 #define rst 8 #define ledBackLight 3 typedef struct { int len; char buf[MAX_LEN]; }STR_LINE; bool g_bRefresh = false; STR_LINE g_serial_lines[MAX_LINE] = { 0, }; STR_LINE * g_cur_line = NULL; long g_refresh_tick = 0; void str_concat(STR_LINE * str, char * data) { if( str->len >= MAX_LEN-1) return; int data_len = strlen(data); int new_len = (str->len + data_len); if( new_len >= MAX_LEN ) { data_len = (MAX_LEN - str->len - 1); // 마지막 0 new_len = MAX_LEN-1; } strncpy(str->buf+str->len, data, data_len ); str->len += data_len; str->buf[str->len]= 0; } void str_concat(STR_LINE * str, char ch) { char tmp[2] = { ch, 0 }; str_concat(str, tmp); } void str_cpy(STR_LINE * dst, STR_LINE * src) { memcpy(dst->buf, src->buf, src->len+1 ); dst->len = src->len; } void str_reset(STR_LINE * str) { str->buf[0] = 0; str->len = 0; } // create an instance of the library TFT TFTscreen = TFT(cs, dc, rst); void setup() { pinMode(ledBackLight, OUTPUT); Serial.begin(9600); // Put this line at the beginning of every sketch that uses the GLCD: TFTscreen.begin(); // clear the screen with a black background TFTscreen.background(0, 0, 0); // write the static text to the screen // set the font color to white TFTscreen.stroke(255, 255, 255); // set the font size TFTscreen.setTextSize(1); memset( g_serial_lines, 0, sizeof(g_serial_lines) ); for( int i = 0; i < MAX_LINE; i ++ ) { str_reset( &g_serial_lines[i] ); } g_cur_line = &g_serial_lines[0]; str_concat(g_cur_line, "Debugging console by MJPark"); g_cur_line++; str_concat(g_cur_line, "Made in 2016-09-15."); g_cur_line++; g_bRefresh = true; g_refresh_tick = 0; analogWrite(ledBackLight, 255 ); } void loop() { while( Serial.available() ) { char inChar = (char)Serial.read(); // new line이 검출되면 new line을 적용함. // new line이 아닐 경우 현재 line에 데이터를 추가한다. if( inChar == '\n' || inChar == '\r' ) { if( inChar == '\n' ) { // new line을 적용하고자 하는데 MAX LINE (LCD가 display할 수 있는 최대 line)을 넘을 경우 // 기존 text line을 scroll하고 새 라인을 적용한다. if( &g_serial_lines[MAX_LINE-1] <= g_cur_line ) { for( int i = 1; i < MAX_LINE; i ++ ) { str_cpy(&g_serial_lines[i-1], &g_serial_lines[i]); } } else { g_cur_line ++; } str_reset(g_cur_line ); } } else { str_concat(g_cur_line, inChar); } // 데이터를 수신했음으로 화면을 update한다. Refresh를 최소화 하기 위해 refresh_tick 시간을 초기화 함. // Serial로 한 글자씩 받기 때문에 너무 많은 Refresh가 발생하여 최소한의 Refresh를 위해 100ms 이내에 연속 수신 데이터는 Update하지 않도록 하다. g_bRefresh = true; g_refresh_tick = millis(); } // 최소한의 리프레쉬가 되도록 refresh_tick을 도입함. // Serial로 한 글자씩 받기 때문에 너무 많은 Refresh가 발생하여 최소한의 Refresh를 위해 100ms 이내에 연속 수신 데이터는 Update하지 않도록 하다. if( (millis() - g_refresh_tick) > 100 ) { if( g_bRefresh) { TFTscreen.background(0, 0, 0); TFTscreen.stroke(255, 255, 255); // lcd에 line을 출력한다. for( int i = 0; i < MAX_LINE; i ++ ) { if( strlen(g_serial_lines[i].buf) == 0 ) continue; TFTscreen.text(g_serial_lines[i].buf, 0, 10 * i); } g_bRefresh = false; } g_refresh_tick = millis(); } }