많이 부족하지만 기존에 실습한 내용 참조하여 만들어 보았습니다.
충분한 테스트를 하지 못하여 버그가 있을수 있습니다.
우리 교육원 IoT 8기 동기들이 혹시 도움이 되었으면 하는 마음에 올려봅니다.
// sys Lib
#include <Arduino.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Device Lib
#include <LiquidCrystal_I2C.h> //LCD
//My Lib
#include "My_Arduino_GPIO_Lib_V1_6.h"
#include "my_Arduino_LiqCry_I2C_LCD_Lib_V1_3.h"
#define Aduino_Mode 1
#define i2c_Char_LCD 2
#define HW_Uart_mode 3 // Arduino HW UART 사용가능
#include "My_MCU_Printf_Lib_V2_2.h"
#include "My_Uart_MCU_Lib_V1_4.h"
// 변수선언및 초기화
int cnt = 1234;
char rx_end_flag = 0; // 수신완료여부 chk flag = 1프레임 ,1 프로토클 수신 완료 체크 flag
unsigned char mode_status=0;
String rx_data;
//char buf[20];
//시간변수 UART모드 테스트를 위해 부득이 전역변수로 사용
struct Time
{
unsigned char hour;
unsigned char min;
unsigned char sec;
}time_set={11,30,0}; // 시간 구조체 선언과 동시 11시30분0초로 초기화설정
//구구단 UART모드 테스트를 위해 부득이 전역변수로 사용
struct gugudan
{
unsigned char dan;
unsigned char su;
}gugudansu={1,1};
//함수원형부
void uart_mode(String mode, char rx_end_flag); //실행모드 함수
void time(); //시간함수
void gugudan_call(); //구구단함수
void dispaly_lcd(String mode, int cnt); //LCD 표시함수
//LCD내 설정된 X를 좌표를 기점으로 X의 끝까지 내용지우기
//구현사유: MODE=1과 같은 명령어 수행후 RUN을 수행시 RUNE=1과 같이 화면에 표시됨 이에 이상헤하게 출력된 부분 제거를 위해
//설정된 X좌표부터 MAX X좌표까지 LCD 내용 지우기
void set_char_x_clr(char x, char y, char max_x);
//시리얼통신시 키보드로부터 입력받은 문자를 캐리지리턴('\r')로 구분한다.
void serialEvent()
{
rx_data = Serial.readStringUntil('\r');
rx_end_flag = 1;
}
void setup()
{
Serial.begin(115200); // 시리얼초기화
lcd_init(); // LCD 초기화
}
void loop()
{
if(rx_end_flag==1) dispaly_lcd(rx_data,cnt); //디스플레이 호출 처음시작시 디스플레이가 출력되지 않음 rx_end_flag가 처음시작시 0이고 MODE명령어 입력시 serialEvent()함수에 의해 rx_end_flag값이 1로 변해 실행된다.
uart_mode(rx_data,rx_end_flag); //Mode명령어 호출
delay(300);
}
void uart_mode(String mode, char rx_end_flag)
{
rx_end_flag=0;
if(mode.compareTo("STOP")==0) mode_status=254; //Mode_status 코드를 통해 키보드로 입력된 MODE명령어를 제어 부득이 전역 변수로 사용함.
else if(mode.compareTo("MODE=1")==0) mode_status=1;
else if(mode.compareTo("MODE=2")==0) mode_status=2;
else if(mode.compareTo("MODE=3")==0) mode_status=3;
else if(mode.compareTo("MODE=4")==0) mode_status=4;
else if(mode.compareTo("MODE=5")==0) mode_status=5;
else if(mode.compareTo("MODE=6")==0) mode_status=6;
else if(mode.compareTo("MODE=7")==0) mode_status=7;
else if(mode.compareTo("DN")==0 && mode_status==254 || mode_status==5) mode_status=252;
else if(mode.compareTo("UP")==0 && mode_status==254 || mode_status==5) mode_status=253;
//else mode_status=255;
switch(mode_status)
{
case 1: if(mode.compareTo("RUN")==0) dev_printf("UP Count : %d\r\n", cnt++); break; //MODE=1 일때수행
case 2: if(mode.compareTo("RUN")==0) dev_printf("DN Count : %d\r\n", cnt=cnt-10); break; //MODE=2 일때수행
case 3: if(mode.compareTo("RUN")==0) if(cnt%2==1) dev_printf("ODD UP Count : %d\r\n", cnt); cnt++; break; //MODE=3 일때수행
case 4: if(mode.compareTo("RUN")==0) if(cnt%2==0) dev_printf("EVEN DN Count : %d\r\n", cnt); cnt--; break; //MODE=4 일때수행
case 5 : break; //MODE=5 일때수행
case 6 : time();break; //MODE=6 일때수행
case 7 : gugudan_call(); break; //MODE=7 일때수행
case 252: dev_printf("DN : %d", cnt--);rx_data="STOP"; break; //STOP 일때 수행
case 253: dev_printf("UP : %d", cnt+=10);rx_data="STOP"; break; //STOP 일때 수행
case 254 :break;
//case 255 : dev_printf("Unnwon Command");break;
}
}
//시계표시부 구현
void time()
{
time_set.sec++;
if(time_set.sec>59)
{
time_set.sec=0;
time_set.min++;
}
if(time_set.min>59)
{
time_set.min=0;
time_set.hour++;
}
if(time_set.hour>23) time_set.hour=0;
dev_printf("Now Time %dH:%dM:%ds\r\n",time_set.hour,time_set.min,time_set.sec);
}
//구구단 함수구현
void gugudan_call()
{
if(gugudansu.su >9)
{
gugudansu.su=1;
gugudansu.dan++;
}
if(gugudansu.dan >9) gugudansu.dan=1;
dev_printf("%d * %d = %d\r\n",gugudansu.dan, gugudansu.su, gugudansu.dan * gugudansu.su);
gugudansu.su++;
}
//디스플레이표시 함수구현
void dispaly_lcd(String Mode, int cnt)
{
rx_end_flag=0;
char buf_temp[20];
char mode_buf[20];
char cnt_temp[20];
//lcd.clear(); //LCD내에 저장된 이전내용을 지우기 위해 사용된 함수 단점 delay가 너무 빠르면 화면이 안보일수도 있음
if(Mode.length()==3) set_char_x_clr(13,0,17); // MODE 명령어가 3자리일경우 LCD13번째부터 남아있는값 지우기
if(Mode.length()==4) set_char_x_clr(14,0,17); // MODE 명령어가 4자리일경우 LCD14번째부터 남아있는값 지우기
if(cnt < 1000) set_char_x_clr(14,1,17); // 1000미만시 LCD14번째부터 남아있는값 지우기
if(cnt < 100) set_char_x_clr(13,1,17); // 100미만시 LCD13번째부터 남아있는값 지우기
if(cnt < 10) set_char_x_clr(12,1,17); // 10미만시 LCD12번째부터 남아있는값 지우기
if(cnt < 1 && cnt >=0) set_char_x_clr(11,1,17); // 0~1미만시 LCD11번째부터 남아있는값 지우기
Mode.toCharArray(buf_temp,Mode.length()+1); //NULL문자를 저장하기위해 rx_data에 저장된 Mode 변수의 길의 +1을 추가하여 display_lcd 함수내에 사용된 임시 buffer 변수에 저장한다.
sprintf(cnt_temp,"Now Count: %d",cnt);
sprintf(mode_buf,"Now Mode: %s",buf_temp);
//Serial.println(mode_buf);
print_xy_str(0,0,mode_buf);
if(cnt > 0 ) print_xy_str(0,1,cnt_temp); // CNT가 0이하일때는 표시하지 않음
}
//LCD 디스플레이내 이전에 실행된 MODE명령어 지우기
void set_char_x_clr(char x, char y, char max_x)
{
lcd.setCursor(x, y);
for(x;x<=max_x;x++)
{
lcd.write(' ');
x++;
}
}
첫댓글 감사합니다
감사요