#define uchar unsigned char
#define uint unsigned int
//
#define Start_k A8
#define Up_Key A9
#define Down_k A10
#define Stop_k A11
#define WATER_k A12
#define DOOR_k A13
#define ST_k A14
#define K_Start digitalRead(Start_k)
#define K_Up digitalRead(Up_Key)
#define K_Down digitalRead(Down_k)
#define K_Stop digitalRead(Stop_k)
#define water_mv digitalRead(WATER_k)
#define DOOR digitalRead(DOOR_k)
#define ST digitalRead(ST_k)
#define K_UpDown digitalRead(UpDown_k)
#define BUZ 13
#define V_Water_In 2
#define V_Water_Out 3
#define V_Air_In 4
#define V_Air_Out 5
#define V_Vac 6
#define V_PreVac 7
#define V9 8
#define DOOR_L 9
#define FAN_L 10
#define Heater_L1 11
#define Heater_L2 12
char FW_VER[]={"AMV 1.381"};
#include "EEPROM_ADDR_LIST.h"
#include "eeprom.h"
#include "RTClib.h"
RTC_DS1307 rtc;
#include "LiquidCrystal_I2C.h" // https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
#define cols 20
#define rows 4
LiquidCrystal_I2C lcd(0x27, cols, rows);
char *Blank;
#include "ste_parameters.h"
#include "LCD_Display.h"
uchar serial_number[9]={0,0,0,0,0,1,2,0,8}; //apoza add 初始序號:02100000, 8:非正確序號
uchar serial_set_index=0; //apoza add 序號位數
uchar serial_set_mode=0; //apoza add 0:未進入序號設定, 1: 進入序號設定
uint sn=802100000; //apoza add 初始序號:02100000, 8:非正確序號
// RTC time setting
uchar RTC_DefaultTime[] = {12,12,12,12,1,3,21}; // 7, sec min hour day date month year 2020/8/8 12:12:30
uchar CurrentT[7];// OldT[7];
uchar rtc_time_index=0;
uchar rtc_blink=0;
uchar water_full_flag,water_full_flag2;
uchar Show_step,pg_state,run_state,run_step,key_scan_en;
uchar SSTP,steri_start;
uchar door_lock_flag,door_error_en,door_bz_flag;
uchar stop_flag,completed_flag,key_memo_flag;
uchar calibration_flag=0,device_check_flag=0,eeprom_read_f=0,time_setting_mode=00;
uchar tp_update_cnt;
//uchar water_mv,DOOR,ST;
uchar rtc_tmr=2,rtc_cnt,eeprom_key=0;
uchar key_status=0,key_memo_cnt=0;
//uchar K_Start=0;
//uchar K_Up=0;
//uchar K_Down=0;
//uchar K_Stop=0;
uchar www_f=0;
int timer1_counter;
float temp,pressure;
typedef struct {
uchar rtcs[7];
#define secc rtcs[0]
#define minc rtcs[1]
#define hourc rtcs[2]
#define dayc rtcs[3]
#define datec rtcs[4]
#define monthc rtcs[5]
#define yearc rtcs[6]
}DS_RTC ;
DS_RTC New_time,Old_time;
typedef struct {
float tp;
uchar buf[5];
#define _hh buf[0]
#define _mm buf[1]
#define _ss buf[2]
#define _tp_h buf[3]
#define _tp_l buf[4]
}TP_Buf ;
TP_Buf max_temp,mini_temp,max_press,mini_press;
void lcm_cls(void){
lcd.clear();
}
void delay_us(unsigned int d){
delayMicroseconds(d);
}
void delay_ms(unsigned int d){
delay(d);
}
void ReadTime(void)
{
DateTime now = rtc.now();
New_time.yearc=now.year()%100;
New_time.monthc=now.month();
New_time.dayc=now.dayOfTheWeek();
New_time.datec=now.day();
New_time.hourc=now.hour();
New_time.minc=now.minute();
New_time.secc=now.second();
}
//--------------------------------------------
//Name : EEPROMWrite
//Input : unAddr Write address
// pucData Write data
// unLength Write length
//Output : TRUE/FALSE
//Function: AT24C0X Write
//--------------------------------------------
uchar eeprom_write(uchar device_u,uint unAddr,uchar *pucData,uint unLength) // page write
{ // start->device address->word address->data0....datan->stop
uint i;
uchar low_byte,high_byte; // byte0,byte1
uchar eeprom_wradd=0;
switch (device_u) {
case 0:
//eeprom_wradd=_24C32_WRAdd; //_24C32_EEPROM
for(i=0;i<unLength;i++) { _24C32_EEPROM[unAddr+i]=*(pucData+i); }
break;
case 1:
//eeprom_wradd=_eeprom1_WRAdd; //_eeprom1_EEPROM
for(i=0;i<unLength;i++) { _eeprom1_EEPROM[unAddr+i]=*(pucData+i); }
break;
default:
break;
} // switch
delay_ms(10); //Timed_Write_Cycle(); 5 NG
// WP=1; // write protect again !
// if (i2c_fail_flag) { init_I2C(); }
return 1;
}
//
//
/*****************************************
*Name : EEPROMRead
*Input : unAddr raed address
pucData read data
unLength read length
*Output : TRUE/FALSE
*Function : AT24C0X Random Read
******************************************/
uchar eeprom_read(uchar device_u,uint unAddr,uchar *pucData,uint unLength) // random read
{ // start->device write address->word address->start->device readaddress->data0...datan->NACK->stop
uint i;
uchar low_byte,high_byte; // byte0,byte1
// uchar read_data;
uchar eeprom_wradd=0,eeprom_rdadd=0;
switch (device_u) {
case 0:
//eeprom_wradd=_24C32_WRAdd;
//eeprom_rdadd=_24C32_RDAdd;
for(i=0;i<unLength;i++) { *(pucData+i)=_24C32_EEPROM[unAddr+i]; }
break;
case 1:
// eeprom_wradd=_eeprom1_WRAdd;
//eeprom_rdadd=_eeprom1_RDAdd;
for(i=0;i<unLength;i++) { *(pucData+i)=_eeprom1_EEPROM[unAddr+i]; }
break;
default:
break;
} // switch
return 1;
}
//
void calibration(void)
{
//uchar i=0;
// uint ten;
//Test_index=0;
//Test_page=0;
calibration_flag=0;
alarm_mode=1;
time_setting_mode=0;
//key_scan_en=0;
Buz_Short();
lcm_cls();
while(K_Stop)
{
show_string(0,0,"F/W Version:");
show_string(1,0, FW_VER);
}
//lcm_cls();
Buz_Short();
openSubMenu( MENU2_NU, Menu1, txMENU2, 3, 1 );
Buz_Short();
while (!(K_Stop&&K_Start&&K_Up&&K_Down)) { } // leave key
calibration_flag=0;
alarm_mode=0;
}
/*void calibration_sr(void)
{
//sleep_flag=0;
calibration_flag=1;
}*/
void DeviceCheck_sr(void)
{
//sleep_flag=0;
device_check_flag=1;
}
void Buz_Short(void)
{
uint bz_cnt;
//uint bz_step;
// uint bz_step;
//#if BUZ_EN
for(bz_cnt=0;bz_cnt<480;bz_cnt++) { // sound period, 250 230
//BUZ = 1;
digitalWrite(BUZ,HIGH);
//syst_delayus(125); //delay_100us(3);
delay_us(125);
//BUZ = 0;
digitalWrite(BUZ,LOW);
delay_us(125);
//syst_delayus(125);
}
/*
// 200ms:480, 250ms: 601, 500ms:1202
for(bz_cnt=0;bz_cnt<480;bz_cnt++) {
// 1.163KHz: BUZ 1=1190, BUZ 0=1200
// 2.4KHz: BUZ 1=582, BUZ 0=563
//BUZ = 1;
for(bz_step=0;bz_step<540;bz_step++){BUZ = 1;}; //569:200us, 545 592:160us 597
//delay_100us(3); //for(bz_step=0;bz_step<1000;bz_step++); // 4000
//BUZ = 0;
for(bz_step=0;bz_step<540;bz_step++){BUZ = 0;}; // 550:200us 572:160us 621 616 delay_100us(3); //for(bz_step=0;bz_step<1000;bz_step++); // 4000
}
*/
//#endif
}
void detect_Water(void) // unit: mV
{
if (water_mv == LOW) {
water_full_flag=1;
}
else water_full_flag=0;
}
void detect_Door(void) // unit: mV
{
if (!DOOR) { // open
delay_ms(10); // debounce, 50->10
if (!DOOR) {
door_lock_flag=0; // open
// door error status
if (door_error_en) { // set door_error_en while it must be lock !
// lcm_cls();
//Buz_Short_Con(2);
// ===========
//error(Err_Door);
}
//
} // debounce
}
else {
delay_ms(10); // debounce, 50->10
if (DOOR) { door_lock_flag=1; } // close
}
}
void detect_temperature(void) // unit: mV
{
int value2 = analogRead(A1);
temp= ((value2*5.0*1000/1023.0)-958)*(135-121)/(757-958)+121;
}
void detect_pressure(void) // average
{
int value1 = analogRead(A0);
pressure=(((value1*5.0/1023.0/5.0)+0.00842)/0.002421)-101;
}
void seting(void)
{
//char ii,i;
uchar i;
uchar time_set_index,serial_set_index;
key_scan_en=0;
//time_setting_mode=1; // enable key operation
//serial_set_mode=1; // enable key operation
lcm_cls();
if(serial_set_mode)
{
serial_set_index=7;
show_string(0,0," Serial seting ");
show_string(1,0," ");
}
if(time_setting_mode){
time_set_index=2;
show_string(0,0," Time Setting ");
show_string(1,0," 20 / / : e Setting ");
show_string(1,0," 20 / / : "); // line 1
//DS3231_ReadTime(0,New_time.rtc,7);
ReadTime();
Old_time=New_time;
}
show_string(2,0,"Stop Key to Exit or ");
show_string(3,0,"save ");
rtc_tmr=2;eeprom_key=0; key_memo_cnt=0;
while (!(K_Stop&&K_Start&&K_Up&&K_Down)) { }
while(K_Stop){
if(key_memo_cnt>0) key_memo_cnt--;
if(!K_Start)
{
if(!key_memo_cnt) {Buz_Short(); key_memo_cnt=2;}
else key_memo_cnt=2;
rtc_tmr=1;rtc_cnt=0;
if(time_setting_mode){
if(time_set_index>1) time_set_index--;
else {time_set_index=6;}
if(time_set_index==3) time_set_index=2;
}
if(serial_set_mode){
if (serial_set_index>0) serial_set_index--;
else {serial_set_index=7;}
}
eeprom_key=0;
delay_ms(200);
}
if(!K_Down)
{ //show_math1(3,17,2);
if(!key_memo_cnt) {Buz_Short(); key_memo_cnt=2;}
else key_memo_cnt=2;
rtc_tmr=2;rtc_cnt=0;
if(time_setting_mode){
eeprom_key=New_time.rtcs[time_set_index];
if(eeprom_key>0) New_time.rtcs[time_set_index]--;
else New_time.rtcs[time_set_index]=99;
}
if(serial_set_mode){
if (serial_number[serial_set_index]>0) serial_number[serial_set_index]--;
else {serial_number[serial_set_index]=9;}
}
eeprom_key=1;
//delay_ms(80);
}
if(!K_Up)
{ //show_math1(3,17,1);
if(!key_memo_cnt) {Buz_Short(); key_memo_cnt=2;}
else key_memo_cnt=2;
rtc_tmr=2;rtc_cnt=0;
if(time_setting_mode){
New_time.rtcs[time_set_index]++;
}
if(serial_set_mode){
if (serial_number[serial_set_index]<9) serial_number[serial_set_index]++;
else {serial_number[serial_set_index]=0;}
}
eeprom_key=0;
//delay_ms(80);
}
if(time_setting_mode){
if(New_time.yearc>99) New_time.yearc=0;
if(!New_time.monthc||New_time.monthc>12) {New_time.monthc=1+11*eeprom_key;}
//if (New_time.month==1||New_time.month==3||New_time.month==5||New_time.month==7||New_time.month==8||New_time.month==10||New_time.month==12)
//if ((New_time.month<8 && (New_time.month%2)==1) || (New_time.month>7 && (New_time.month%2)==0) )
if (New_time.monthc==4||New_time.monthc==6||New_time.monthc==9||New_time.monthc==11)
{ if (!New_time.datec||New_time.datec>30) New_time.datec=1+29*eeprom_key; } // 31
else if (New_time.monthc==2&&(New_time.yearc%4)==0 )
{ if (!New_time.datec||New_time.datec>29) New_time.datec=1+28*eeprom_key; } // 29
else if (New_time.monthc==2 )
{ if (!New_time.datec||New_time.datec>28) New_time.datec=1+27*eeprom_key; } // 28
else
{ if(!New_time.datec||New_time.datec>31) New_time.datec=1+30*eeprom_key; } // 30
if (New_time.hourc>23) New_time.hourc=23*eeprom_key;
if (New_time.minc>59) New_time.minc=59*eeprom_key;
if (New_time.secc>59) New_time.secc=59*eeprom_key;
}
eeprom_key=0;
if (rtc_tmr==1) {
//rtc_tmr=0;
if(time_setting_mode){
if(time_set_index>3) show_string(1,19-(3*(time_set_index-1))," ");// show_string(1,19-(3*(time_set_index-1))," ");
else show_string(1,19-(3*(time_set_index-0))," "); //show_string(1,19-(3*(time_set_index-0))," ");
}
if(serial_set_mode){
show_string(1,13-serial_set_index," ");//show_string(1,13-serial_set_index," ");
}
rtc_blink=0;
//rtc_tmr=2;
}//time_set_index
else if (rtc_tmr==2) {
//rtc_tmr=0;
if(time_setting_mode){
for (i=1; i<sizeof(RTC_DefaultTime); i++) { // 6 times, "week" ignored, start from minutes
if (i<3) show_math(1,19-(3*(i-0)), New_time.rtcs[i]);// show_math(1,19-(3*(i-0)), CurrentT[i]); // week ignored : Show: Sec - min - hour
else if (i>3) show_math(1,19-(3*(i-1)), New_time.rtcs[i]); //show_math(1,19-(3*(i-1)), CurrentT[i]); // date - month - year
}
//show_math(1,18, New_time.sec);
}
if(serial_set_mode){
for (i=0; i<8; i++) { // 6 times, "week" ignored, start from minutes
show_math1(1,13-i, serial_number[i]); // week ignored : Show: Sec - min - hour
//show_math(1,13-i, serial_number[i]);
}
}
}
//show_Disp();
};
Buz_Short();
while (!(K_Stop&&K_Start&&K_Up&&K_Down)) { } // leave key
// key up
//如果 秒、分、時、天、日、月、年 有改變就寫入RTC
/*for(ii=0; ii<7;ii++){
if( OldT[ii]!=CurrentT[ii]) { DS3231_SetTime(0,CurrentT,7); ii=8; }
}*/
if( New_time.rtcs != Old_time.rtcs){ New_time.rtcs[0]=0;ReadTime();}
rtc_tmr=0;
time_setting_mode=0; serial_set_mode=0; key_scan_en=1;
//key down
}
void running_change_tpdw(void) // t p d w
{
detect_temperature();
if(steri_start){
if(mini_temp.tp==0 || temp< mini_temp.tp){
mini_temp.tp=temp;
mini_temp._hh=New_time.hourc;
mini_temp._mm=New_time.minc;
mini_temp._ss=New_time.secc;
}
if(max_temp.tp==0 || temp> max_temp.tp){
max_temp.tp=temp;
max_temp._hh=New_time.hourc;
max_temp._mm=New_time.minc;
max_temp._ss=New_time.secc;
}
}
#if (Show_Duty)
//show_math3(2,8,heat_duty); // 6
show_math4(2,8,temp_mv);
show_math3(2,14,temp1);
show_string(2,17,".");
ten=temp1*10;
show_math1(2,18,ten%10);
#endif
// pressure
detect_pressure();
if(steri_start){
if(mini_press.tp==0 || pressure< mini_press.tp){
mini_press.tp=pressure;
mini_press._hh=New_time.hourc;
mini_press._mm=New_time.minc;
mini_press._ss=New_time.secc;
}
else if(mini_press.tp==0 || pressure> max_press.tp){
max_press.tp=pressure;
max_press._hh=New_time.hourc;
max_press._mm=New_time.minc;
max_press._ss=New_time.secc;
}
}
detect_Water();
detect_Door();
}
// =================================================
void show_string(uchar row,uchar col,char *ptString) // must be char type
{
//if (row==0||row==1) add=row*0x40+(0x80+col);
//if (row==2||row==3) add=(row-2)*0x40+(0x80+col+0x14);
//PCF8574_WriteCommand(add,1);
//lcd_move_to_yx(row,col,*ptString);
lcd.setCursor(col, row);
//uchar col1;
while (*ptString!='\0'&& col<20) { // space char, end of String, show one row data
//PCF8574_WriteData(*ptString++);
lcd.print(*ptString++);
col++;
// delay_ms(50);
}
}
void ua_lcd_math_2_ASCII(uchar row,uchar col,char num)
{
switch (num)
{
case 1: show_string(row,col,"1");
break;
case 2: show_string(row,col,"2");
break;
case 3: show_string(row,col,"3");
break;
case 4: show_string(row,col,"4");
break;
case 5: show_string(row,col,"5");
break;
case 6: show_string(row,col,"6");
break;
case 7: show_string(row,col,"7");
break;
case 8: show_string(row,col,"8");
break;
case 9: show_string(row,col,"9");
break;
case 0: show_string(row,col,"0");
break;
default:
break;
}
}
//
// ======= math to Text, ex. Uart_show_math(0,5,20); =========
void show_math1(uchar row,uchar col,char math) // 2 digits, 7F=127
{
uchar k;
if ((math & 0x80)== 0x80 ) { // negative number sign bit=1, 1xxx xxxx
show_string(row,col,"-");
k=math & 0x7f ; // 0111 1111, clear sign bit
col++;
}
else k=math;
//ua_lcd_math_2_ASCII(row,col,k);
lcd.setCursor(col, row);lcd.print(k);
}
//
// ======= math to Text, ex. Uart_show_math(0,5,20); ========= if error "char -> int"
void show_math(uchar row,uchar col,int math) // 2 digits, 7F=127, 00~99 (char type +/-128)
{ // char math, compiler warning
uchar k, digit[2];
uchar i;
if ((math & 0x80)== 0x80 ) { // negative number sign bit=1, 1xxx xxxx
show_string(row,col,"-");
k=math & 0x7f ; // 0111 1111, clear sign bit
col++;
}
else k=math;
digit[0]=k/10; // tens digit
digit[1]=k%10; // digits
for (i=0;i<2;i++) {
ua_lcd_math_2_ASCII(row,col+i,digit[i]);
lcd.setCursor(col+i, row);lcd.print(digit[i]);
}
}
//
void show_math3(unsigned char row, unsigned char col,int math)
{
unsigned char i;
int k=math, digit[3]; //0~9999
if (math<0) {
//show_string(row,col,"-");
k=-math;
//col++;
}
digit[0]=k/100; // hunderd digit
k=k%100;
digit[1]=k/10; // ten digits
digit[2]=k%10;
for (i=0;i<3;i++) {
//ua_lcd_math_2_ASCII(row,col+i,digit[i]);
lcd.setCursor(col+i, row);lcd.print(digit[i]);
}
}
//
// ======= math to Text, ex. Uart_show_math(0,5,2000); =========
void show_math4(unsigned char row,unsigned char col,int math) // 4 digits, 0000~9,999 (int type +/-32,768)
{
unsigned char i;
int k=math, digit[4]; //0~9999
if (math<0) {
//show_string(row,col,"-");
lcd.setCursor(col, row);lcd.print("-");
k=-math;
col++;
}
digit[0]=k/1000; // thound digit
k=k%1000;
digit[1]=k/100; // hundred digits
k=k%100;
digit[2]=k/10; // tens digit
digit[3]=k%10; // digits
for (i=0;i<4;i++) {
//ua_lcd_math_2_ASCII(row,col+i,digit[i]);
lcd.setCursor(col+i, row);lcd.print(digit[i]);
}
}
// ======= math to Text, ex. Uart_show_math(0,5,2000); =========
void show_math9(uchar row,uchar col,uint math) // 4 digits, 0000~9,999 (int type +/-32,768)
{
uchar i,j;
uint k=math, digit[10]; //0~9999
i=0;j=0;
if(math==0) {digit[0]=0;j=1;}
while(k){
digit[j]=k%10; k=k/10;
j++;
if(k==0) digit[j]=k;
}
k=j;
for(i=0;i<k;i++)
{
j--;
ua_lcd_math_2_ASCII(row,col+i,digit[j]);
}
}
void show_float_math(unsigned char row,unsigned char col,float math) // 3 digits
{
unsigned int ten=0;
show_math3(row,col+1,math);
if (math>=0) { // >=-0.1
ten=math*10;
lcd.setCursor(col, row);lcd.print(" "); // (10 11)->(12 13)
//lcd.setCursor(0, 1);lcd.print(ten);
}
else {
ten=-math*10;
if(ten>0){lcd.setCursor(col, row);lcd.print("-"); }
else {lcd.setCursor(col, row);lcd.print(" "); }
}
//show_string(row,col+4,".");
lcd.setCursor(col+4, row); lcd.print(".");
lcd.setCursor(col+5, row); lcd.print(ten%10);
//show_math1(row,col+5,ten%10); //
}
void read_data_list(uchar data_arr)
{
uint i;
for(i=0;i<=3;i++){
eeprom_read(1,EE_Datasave_addr(data_arr),buf,11);
show_math(i,1,data_arr+1);
//"01234567890123456789"
//show_string(i,3,": / / _ _P ");
//"01234567890123456789"
if(buf[1]>99) show_string(i,3,":--/--/-- ");
else{
show_math(i,4,buf[1]);show_string(i,6,"/"); //YY
show_math(i,7,buf[2]);show_string(i,9,"/"); //MM
show_math(i,10,buf[3]);show_string(i,12,"_"); //DD
show_math(i,13,buf[4]);show_string(i,15,"_P"); //Px
show_math1(i,17,buf[0]+1);
if(buf[10]==1) show_string(i,18,"_F");
else if(buf[10]==2) show_string(i,18,"_C");
else if(buf[10]==3) show_string(i,18,"_S");
}
data_arr++;
if(data_arr>20) data_arr=0;
}
}
void eeprom_data_list(void)
{
uchar i;
//uchar data_arr,disp_cur;
uchar disp_cur;
key_scan_en=0;
eeprom_read_f=1;
uchar Test_index=0;
//Test_page=0;
eeprom_key=0; key_memo_cnt=0;
//顯示資訊暫存器初始化------
//若沒初始化 則內容可能都是 '\0'
for(i=0;i<=5;i++)
{
//Display_bufs[i]=Dateandtime;
}
//-----------------------
//初始畫面
//data_arr=0;
disp_cur=0;
eeprom_read(0,Data_no_addr,buf,1);
//data_num=buf[0];
//Test_index=data_num;
Test_index=buf[0];
if(Test_index>200) Test_index=0;
read_data_list(Test_index);
//顯示游標---------------
// show_cur(disp_cur);
//顯示畫面----------------
// show_Disp();
//-------------------------
//data_arr=0;Test_index=0;
//while(eeprom_read_f){
while(K_Stop){
} //end of while(eeprom_read_f)
Buz_Short();
while(!(K_Stop && K_Start && K_Up && K_Down)){}
while(!(K_Stop && K_Start && K_Up && K_Down)){}
while(!(K_Stop && K_Start && K_Up && K_Down)){}
key_scan_en=1; eeprom_read_f=0;
}
//*****************************************************************************
//
//*****************************************************************************
void show_info(void)
{
show_string(2,6,"C");show_string(2,7," ");
show_string(3,6,"KPa ");
show_float_math(2,0,temp);
if (run_state==0 && pressure<1 && pressure>-1) {
show_float_math(3,0,0);
}
else show_float_math(3,0,pressure);
//----------------------------------------------------------------
//if (water_full_flag||water_full_flag2){ show_string(3,12,"W"); }
show_string(3,17,(!ST ? "[S]" : "[ ]"));
show_string(3,11,((water_full_flag||water_full_flag2))?"[W]" : "[ ]");
if (door_lock_flag)
{ show_string(3,14,"[D]");
if(!door_bz_flag){ //0: 蜂鳴器沒響過
if(!stop_flag && !completed_flag) //Buz_Short_Con(2); //不是停止模式才響兩聲
//(2021/6/4導入停止模式關門也能回到待機)
door_bz_flag=1;} //1:蜂鳴器響過
}
else { show_string(3,14,"[ ]");door_bz_flag=0; }
//-----------------------------------------------------------------
}
void Show_Date(uchar row,uchar col, uchar sec_on)
{
uchar colss=0;
//DS3231_ReadTime(0,New_time.rtc,7);
ReadTime();
if (Old_time.secc!= New_time.secc) { // sec, ":" blink
rtc_blink ? (rtc_blink=0) : (rtc_blink=1);
}
Old_time=New_time;
if(sec_on) colss=1;
show_string(row,0,(sec_on ? " " : " "));
show_string(row,2-colss,"20");
show_math(row,4-colss,New_time.yearc);
show_string(row,6-colss,"/");
show_math(row,7-colss,New_time.monthc);
show_string(row,9-colss,"/");//show_string(0,15,":");
show_math(row,10-colss,New_time.datec);
show_string(row,12-colss," ");
show_math(row,13-colss,New_time.hourc);
show_string(0,15-colss,(rtc_blink ? " " : ":"));
show_math(row,16-colss,New_time.minc);
if(sec_on){ show_string(0,17,":"); show_math(0,18,New_time.secc);}
//Serial.print(New_time.yearc);
//Serial.print(New_time.monthc);
//Serial.print(New_time.datec);
//Serial.print(New_time.hourc);
//Serial.print(New_time.minc);
}
void Show_EngWindows(uchar menuNU,char **SubMENU, uchar idx,char **VALOnOff)
{
uchar endFor1;
endFor1 = (menuNU+rowsLCD-1) /rowsLCD;
int graphMenu = 0;
for( int i=1 ; i<=endFor1 ; i++ )
{
if( idx < i*rowsLCD ) //如果idxMenu=4, i要等於2才會小於 2*rowLCD(4)
{
graphMenu = (i-1) * rowsLCD; //如果idxMenu=4, graphMenu =(2-1) * 4 =4
break; //跳離for迴圈
}
}
uchar endFor2 = graphMenu+rowsLCD; ////如果idxMenu=4,endFor2 =4+4=8
for( int i=graphMenu, j=0; i< endFor2 ; i++, j++ )
{
show_string(j%2,1+(j/2)*10,((i<menuNU) ? SubMENU[i] : " "));
show_string(j%2,7+(j/2)*10,( VALOnOff[i] ? "ON" : "--"));
show_string(j%2,0+(j/2)*10,((j==idx % rowsLCD) ? ">" : " "));
}
show_info();
}
void Show_EEmWindows(uchar menuNU,char **SubMENU, uchar idx)
{
uchar endFor1,data_arr=idx;
endFor1 = (menuNU+rowsLCD-1) /rowsLCD;
int graphMenu = 0;
for( int i=1 ; i<=endFor1 ; i++ )
{
if( idx < i*rowsLCD ) //如果idxMenu=4, i要等於2才會小於 2*rowLCD(4)
{
graphMenu = (i-1) * rowsLCD; //如果idxMenu=4, graphMenu =(2-1) * 4 =4
break; //跳離for迴圈
}
}
uchar endFor2 = graphMenu+rowsLCD; ////如果idxMenu=4,endFor2 =4+4=8
for( int i=graphMenu, j=0; i< endFor2 ; i++, j++ )
{
eeprom_read(1,EE_Datasave_addr(data_arr),buf,11);
show_math(i,1,data_arr+1);
//"01234567890123456789"
//show_string(i,3,": / / _ _P ");
//"01234567890123456789"
if(buf[1]>99) show_string(i,3,":--/--/-- ");
else{
show_math(i,4,buf[1]);show_string(i,6,"/"); //YY
show_math(i,7,buf[2]);show_string(i,9,"/"); //MM
show_math(i,10,buf[3]);show_string(i,12,"_"); //DD
show_math(i,13,buf[4]);show_string(i,15,"_P"); //Px
show_math1(i,17,buf[0]+1);
if(buf[10]==1) show_string(i,18,"_F");
else if(buf[10]==2) show_string(i,18,"_C");
else if(buf[10]==3) show_string(i,18,"_S");
}
data_arr++;
if(data_arr>20) data_arr=0;
show_string(j,0,((j==idx % rowsLCD) ? ">" : " "));
}
}
void Show_SubWindows(uchar menuNU,char **SubMENU, uchar idx)
{
uchar endFor1;
endFor1 = (menuNU+rowsLCD-1) /rowsLCD;
int graphMenu = 0;
for( int i=1 ; i<=endFor1 ; i++ )
{
if( idx < i*rowsLCD ) //如果idxMenu=4, i要等於2才會小於 2*rowLCD(4)
{
graphMenu = (i-1) * rowsLCD; //如果idxMenu=4, graphMenu =(2-1) * 4 =4
break; //跳離for迴圈
}
}
uchar endFor2 = graphMenu+rowsLCD; ////如果idxMenu=4,endFor2 =4+4=8
for( int i=graphMenu, j=0; i< endFor2 ; i++, j++ )
{
show_string(j,1,((i<menuNU) ? SubMENU[i] : " "));
show_string(j,0,((j==idx % rowsLCD) ? ">" : " "));
}
}
void Show_windows(uchar runing,uchar STsetp,uchar idx)
{
//show_math(2,14,run_step);
//show_math(2,18,SSTP );
switch( runing )
{
case 0: //待機
Show_Date(0,0,0);
show_string(1,0, txMENU1[idx]); //選單
break;
case 1: //執行
show_string(0,0, txMENU1[idx]); //選單
show_string(1,0, runStep[Show_step]); //運行狀態
break;
}
show_info();
}
void openEngMenu( uchar menuNUs, uchar screen, char **SubMENU, uchar sMenuID, int maxValue )
{
//uchar idxMenu = 0;
uchar push_MenuItme;
uchar push_iMENU;
uchar push_MenuID;
uchar exitMenu = FALSE;
uchar forcePrint = TRUE;
btnPressed = Unknown;
push_MenuItme=MenuItme;
push_iMENU=iMENU;
push_MenuID=MenuID;
char *onoff[]={0,0,0,0,0,0,0,0,0,0,0};
iMENU=menuNUs;
MenuItme=0;
MenuID=sMenuID;
lcm_cls();
while( !exitMenu )
{
// btnPressed = readButtons();
if( btnPressed == Start )
{ btnPressed = Unknown;
if(onoff[MenuItme]) onoff[MenuItme]=0;
else onoff[MenuItme]=1;
switch( MenuItme )
{
case 0:
if(onoff[MenuItme]){digitalWrite(V_Water_In,HIGH); }
else digitalWrite(V_Water_In,LOW);//V_Water_In=0;
break;
case 1:
if(onoff[MenuItme]){digitalWrite(V_Water_Out,HIGH); }
else digitalWrite(V_Water_Out,LOW);
break;
case 2:
if(onoff[MenuItme]){digitalWrite(V_Air_In,HIGH); }
else digitalWrite(V_Air_In,LOW);//V_Air_In=0;
break;
case 3:
if(onoff[MenuItme]){digitalWrite(V_Air_Out,HIGH); }
else digitalWrite(V_Air_Out,LOW);//V_Air_Out=0;
break;
case 4:
if(onoff[MenuItme]){digitalWrite(V_PreVac,HIGH); }
else digitalWrite(V_PreVac,LOW);//V_PreVac=0;
break;
case 5:
if(onoff[MenuItme]){digitalWrite(V_Vac,HIGH); }
else digitalWrite(V_Vac,LOW);//V_Vac=0;
break;
case 6:
if(onoff[MenuItme]){digitalWrite(DOOR_L,HIGH); delay_ms(200);digitalWrite(DOOR_L,LOW); }
break;
case 7:
if(onoff[MenuItme]){digitalWrite(FAN_L,HIGH); }
else digitalWrite(FAN_L,LOW);
break;
}
forcePrint = TRUE;
}
else if( btnPressed == Stop )
{
exitMenu=TRUE;
}
if( !exitMenu && (forcePrint || btnPressed != Unknown) )
{
forcePrint = TRUE;
//Show_SubWindows(menuNU,SubMENU,idxMenu);
Show_EngWindows(menuNUs,SubMENU,MenuItme,onoff);
}
}
MenuItme=push_MenuItme;
iMENU=push_iMENU;
MenuID=push_MenuID;
key_scan_en=1;
btnPressed = Unknown;
lcm_cls();
}
void openEEmMenu( uchar menuNUs, uchar screen, char **SubMENU, uchar sMenuID, int maxValue )
{
//uchar idxMenu = 0;
uchar push_MenuItme;
uchar push_iMENU;
uchar push_MenuID;
uchar Test_index;
uchar exitMenu = FALSE;
uchar forcePrint = TRUE;
btnPressed = Unknown;
push_MenuItme=MenuItme;
push_iMENU=iMENU;
push_MenuID=MenuID;
iMENU=menuNUs;
MenuItme=0;
MenuID=sMenuID;
eeprom_read(0,Data_no_addr,buf,1);
MenuItme=buf[0];
if(MenuItme>200) MenuItme=0;
lcm_cls();
while( !exitMenu )
{
// btnPressed = readButtons();
if( btnPressed == Start )
{ btnPressed = Unknown;
switch( MenuItme )
{
case 0: show_math(3,18,MenuItme); break;
case 1: key_scan_en=0;time_setting_mode=1; seting(); btnPressed=NULL; break;
case 2: show_math(3,18,MenuItme); break;
case 3: show_math(3,18,MenuItme); break;
}
forcePrint = TRUE;
}
else if( btnPressed == Stop )
{
exitMenu=TRUE;
}
if( !exitMenu && (forcePrint || btnPressed != Unknown) )
{
forcePrint = TRUE;
//Show_SubWindows(menuNU,SubMENU,idxMenu);
Show_EEmWindows(menuNUs,SubMENU,MenuItme);
//read_data_list(MenuItme);
}
}
MenuItme=push_MenuItme;
iMENU=push_iMENU;
MenuID=push_MenuID;
key_scan_en=1;
btnPressed = Unknown;
lcm_cls();
}
void openSubMenu( uchar menuNUs, uchar screen, char **SubMENU, uchar sMenuID, int maxValue )
{
//uchar idxMenu = 0;
uchar push_MenuItme;
uchar push_iMENU;
uchar push_MenuID;
uchar exitMenu = FALSE;
uchar forcePrint = TRUE;
btnPressed = Unknown;
push_MenuItme=MenuItme;
push_iMENU=iMENU;
push_MenuID=MenuID;
iMENU=menuNUs;
MenuItme=0;
MenuID=sMenuID;
lcm_cls();
while( !exitMenu )
{
// btnPressed = readButtons();
if( btnPressed == Start )
{ btnPressed = Unknown;
if(MenuID==1)
{
switch( MenuItme )
{
case 0: openEEmMenu( 5, Menu1, txSMENU1, 1, 1 ); //eeprom_data_list();
break;
case 1: key_scan_en=0;time_setting_mode=1; seting(); btnPressed=NULL; break;
case 2: show_math(3,18,MenuItme); break;
case 3: show_math(3,18,MenuItme); break;
}
}
if(MenuID==2)
{
switch( MenuItme )
{
case 0:
pg_state=Ster_par[4].pg_states;
// run_state=1;run_step=0;
break;
case 1:
pg_state=Ster_par[5].pg_states;
// run_state=1;run_step=0;
break;
case 2: show_math(3,18,MenuItme); break;
}
run_state=1;run_step=0;
}
if(MenuID==3)
{
switch( MenuItme )
{
case 0: show_math(3,18,MenuItme); break;
case 1: key_scan_en=0;serial_set_mode=1; seting(); btnPressed=Unknown; break;
case 2: openEngMenu( MENU2_sNU1, Menu1, txTSMENU2, 3, 1 ); break;
case 3: show_math(3,18,MenuItme); break;
}
}
forcePrint = TRUE;
}
else if( btnPressed == Stop )
{
exitMenu=TRUE;
}
if(calibration_flag==1 && MenuID!=3){
calibration();
}
if( !exitMenu && (forcePrint || btnPressed != Unknown) )
{
forcePrint = TRUE;
//Show_SubWindows(menuNU,SubMENU,idxMenu);
Show_SubWindows(menuNUs,SubMENU,MenuItme);
}
}
MenuItme=push_MenuItme;
iMENU=push_iMENU;
MenuID=push_MenuID;
key_scan_en=1;
btnPressed = Unknown;
lcm_cls();
}
void openMenu(uchar idxMenu, uchar itemMenu,uchar Sstep)
{
uchar pushh;
if( btnPressed == Start )
{ btnPressed = Unknown;
Show_step=BK;
switch( MenuItme )
{
case 0: //break;
case 1: //break;
case 2: //break;
case 3:
pg_state=Ster_par[MenuItme].pg_states;
run_state=1;run_step=0;
break;
case 4:
openSubMenu( MENU1_sNU1, Menu1, txSMENU1, 1, 1 );
break;
case 5:
openSubMenu( MENU1_sNU2, Menu2, txSMENU2, 2, 1 );
break;
}
_Display_flge = TRUE;
}
if( btnPressed == Stop )
{ btnPressed = Unknown;
}
if(calibration_flag==1){
calibration();
}
Show_DISP_CON;
Show_windows(run_state,run_step,itemMenu);
}
void key_read(void) // call by timer0_irq, once 20ms
{
switch (key_status) {
case 0: // search status
if (!K_Stop||!K_Start||!K_Up||!K_Down) {
key_status=1; // any key pressed, do debounce check
if(!key_memo_flag)
{ key_memo_cnt=0;
key_memo_flag=1;
}
}
break;
case 1: // debounce & key confirm
if (K_Stop&&K_Start&&K_Up&&K_Down ) key_status=0; // no key pressed, debounce fail
else { // debounce pass, timer0 20ms
if (!run_state) { // accept key on standby state
if (K_Stop&&K_Start&&!K_Up&&!K_Down) {
while(!K_Up&&!K_Down && key_memo_cnt<=140){key_memo_cnt++;delay_ms(20);
}
if (key_memo_cnt>140){
if(!calibration_flag && !device_check_flag) calibration_flag=1; //calibration_sr(); // up + down
}
}
else if (!K_Stop&&!K_Start&&K_Up&&K_Down) { if(!calibration_flag && !device_check_flag) DeviceCheck_sr();} // start+ stop
else if (K_Stop&&!K_Start&&K_Up&&K_Down) run_sr(); // accept key on any state
// State: "standby" "running" "time setting"
else if (K_Stop&&K_Start&&!K_Up&&K_Down) up_sr();
else if (K_Stop&&K_Start&&K_Up&&!K_Down) down_sr();
else if (!K_Stop&&K_Start&&K_Up&&K_Down) stop_sr();
} // run_state==0
else { // accept key on running state
if (!K_Stop&&K_Start&&K_Up&&K_Down) stop_sr();
}
//key_status=0; // continue key available
key_status=2; // wait key leave
key_memo_cnt=0;
} // else
break;
case 2: // key leave status
if (K_Stop&&K_Start&&K_Up&&K_Down) {key_status=0;key_memo_flag=0;} // key leave
/*while(!run_state && !K_Up&&!K_Down && key_memo_cnt<=140){key_memo_cnt++;delay_ms(20);}
if (key_memo_cnt>140){
if(!calibration_flag && !device_check_flag) calibration_sr(); // up + down
} */
break;
} // switch
}
//
void run_sr(void) // "standby" -> "running"
{
//sleep_flag=0;
Buz_Short();
//bz_cnt_flag=1;
if (!time_setting_mode && !serial_set_mode && !calibration_flag && !eeprom_read_f) { // program selection mode
if(MenuItme==Menufun) MenuID=1;
else if( MenuItme==Testfun) MenuID=2;
//else MenuID=0;
}
btnPressed = Start;
}
//
void stop_sr(void)
{
if (!time_setting_mode && !serial_set_mode && !calibration_flag && !eeprom_read_f) { // program selection mode
//sleep_flag=0;
Buz_Short();
//bz_cnt_flag=1;
if((Menu_index[1]==0 && Menu_index[2]==0)||Menu_index[2]==99) stop_flag=1;
else {Menu_index[1]=0; Menu_index[2]=0;tp_update_cnt=10;}
}
btnPressed = Stop;
}
//
void up_sr(void) // K_Up, Program + or RTC time setting up
{
//sleep_flag=0; // stop
Buz_Short();
//bz_cnt_flag=1;
//while(!eeprom_read_f && !K_Up && key_memo_cnt<=140){key_memo_cnt++;delay_ms(20);}
// program state +/-
if (key_memo_cnt<140 && !time_setting_mode && !serial_set_mode && !eeprom_read_f) { // program selection mode
// key_memo_flag=0;
(MenuItme-1 >= 0) ? MenuItme-- : (MenuItme = iMENU-1);
//Serial.print(MenuItme);
}
}
//
void down_sr(void) // K_Down, Program - or RTC time setting down
{
//sleep_flag=0; // stop
Buz_Short();
//bz_cnt_flag=1;
// program state +/-
if (!time_setting_mode && !serial_set_mode && !eeprom_read_f) { // program selection mode
//if (pg_state>0) pg_state--;
//else pg_state=pg_Quantity-1; //circulate 3 sizeof(pg0_content)
(MenuItme+1 < iMENU) ? MenuItme++ : (MenuItme = 0);
}
//Serial.print(MenuItme);
}
//
/*void run1_sr(void) // K_Up, Program + or RTC time setting up
{
if(heating_test1) {
Buz_Short(); delay_ms(200);Buz_Short();
heating_test1=0;
temp_mv_offset_flag=1;
}
else {
Buz_Short();
heating_test1=1;
}
}*/
/*void up1_sr(void) // K_Up, Program + or RTC time setting up
{
if(heating_test) {
if(temp_mv_offset>0) temp_mv_offset--;
temp_mv_offset_flag=1;
}
}
void down1_sr(void) // K_Up, Program + or RTC time setting up
{
if(heating_test) temp_mv_offset++;
temp_mv_offset_flag=1;
//buf[1]=temp_mv_offset>>8;
//buf[0]=temp_mv_offset&0x00ff;
//eeprom_write(1,Temp_mv_offset_addr,buf,2);
}*/
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
LiquidCrystal_I2C lcd(0x27, cols, rows);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(Start_k, INPUT_PULLUP);
pinMode(Up_Key, INPUT_PULLUP);
pinMode(Down_k, INPUT_PULLUP);
pinMode(Stop_k, INPUT_PULLUP);
pinMode(WATER_k, INPUT_PULLUP);
pinMode(DOOR_k, INPUT_PULLUP);
pinMode(ST_k, INPUT_PULLUP);
pinMode(BUZ, OUTPUT);
pinMode(V_Water_In, OUTPUT);
pinMode(V_Water_Out, OUTPUT);
pinMode(V_Air_In, OUTPUT);
pinMode(V_Air_Out, OUTPUT);
pinMode(V_Vac, OUTPUT);
pinMode(V_PreVac, OUTPUT);
pinMode(V9, OUTPUT);
pinMode(DOOR_L, OUTPUT);
pinMode(FAN_L, OUTPUT);
pinMode(Heater_L1, OUTPUT);
pinMode(Heater_L2, OUTPUT);
lcd.begin();
lcd.backlight();
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
/*
cli();////關閉全局中斷
//設置定時器0為10kHz(100us)
TCCR0A = 0;//將整個TCCR0A寄存器設置為0
TCCR0B = 0;//將整個TCCR0B寄存器設置為0
TCNT0 = 0;//將計數器值初始化為0
//設置計數器為10kHZ,即100us
OCR0A = 39999;//比較匹配寄存器= [16,000,000Hz /(預分頻器*所需中斷頻率)] - 1
//比較匹配寄存器=24,中斷間隔=100us即中斷頻率10khz
TCCR0A |= (1 << WGM01);//打開CTC模式
TCCR0B |= (1 << CS01) | (1 << CS00); //設置CS01位為1(8倍預分頻)
TIMSK0 |= (1 << OCIE0A);//啟用定時器比較中斷
//設置定時器1為1kHz
TCCR1A = 0;//將整個TCCR1A寄存器設置為0
TCCR1B = 0;//將整個TCCR1B寄存器設置為0
TCNT1 = 0;//將計數器值初始化為0
//設置計數器為10kHZ,即1ms
OCR1A = 199;// = (16*10^6)/(1000*8) - 1 (must be <65536)
TCCR1B |= (1 << WGM12);//打開CTC模式
TCCR1B |= (1 << CS11);//設置CS11位為1(8倍預分頻)
TIMSK1 |= (1 << OCIE1A);
//設置定時器2為8kHz
TCCR2A = 0;// set entire TCCR2A register to 0
TCCR2B = 0;// same for TCCR2B
TCNT2 = 0;//initialize counter value to 0
// set compare match register for 8khz increments
OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
// turn on CTC mode
TCCR2A |= (1 << WGM21);//打開CTC模式
// Set CS21 bit for 8 prescaler
TCCR2B |= (1 << CS21);
// enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
sei();//打開全局中斷
*/
noInterrupts(); //禁止所有中断
TCCR1A = 0;
TCCR1B = 0;
//为我们的中断设置timer1_counter为正确的时间间隔
// 10ms = timer1_counter = 65536-(62500*10ms)=64911
// 20ms = timer1_counter = 65536-(62500*20ms)=64286
// 500ms = timer1_counter = 65536-(62500*500ms)=34286
timer1_counter = 65536-(62500*20/1000); // 1/20ms = 50Hz
TCNT1 = timer1_counter; //预加载timer
TCCR1B |= (1 << CS12); //256 分频器(256 prescaler?)
TIMSK1 |= (1 << TOIE1); //启用定时器溢出中断
interrupts(); //允许所有中断
key_scan_en=1;
}
//中斷0服務函數
ISR(TIMER1_OVF_vect) { //常规中断服务
TCNT1 = timer1_counter; //预加载timer digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
if (key_scan_en){ key_read(); }
if (rtc_tmr==1 || rtc_tmr==2) {
if (rtc_cnt<3) rtc_cnt++;
else if (rtc_cnt==3) { rtc_tmr=2; rtc_cnt++; }
else if (rtc_cnt<13) rtc_cnt++;
else {rtc_tmr=1; rtc_cnt=0; } // >CNT2
}
//if(www_f==0) {digitalWrite(V_Water_In,HIGH);www_f=1;}
// else {digitalWrite(V_Water_In,LOW);www_f=0;}
}
/*ISR(TIMER0_COMPA_vect){
//產生頻率為2kHz / 2 = 1kHz的脈衝波(全波切換為兩個周期,然後切換為低)
if(toggle0){
digitalWrite(8,HIGH);
toggle0 = 0;
}
else{
digitalWrite(8,LOW);
toggle0 = 1;
}
}
ISR(TIMER1_COMPA_vect){// timer1中斷1Hz切換引腳13(LED)
//產生頻率為1Hz / 2 = 0.5kHz的脈衝波(全波切換為兩個周期,然後切換為低)
if(toggle1){
digitalWrite(13,HIGH);
toggle1 = 0;
}
else{
digitalWrite(13,LOW);
toggle1 = 1;
}
}
ISR(TIMER2_COMPA_vect){// timer1中斷8kHz切換引腳9
//產生頻率為8kHz / 2 = 4kHz的脈衝波(全波切換為兩個周期,然後切換為低)
if(toggle2){
digitalWrite(9,HIGH);
toggle2 = 0;
}
else{
digitalWrite(9,LOW);
toggle2 = 1;
}
}*/
void loop() {
//detect_temperature();
//detect_pressure();
running_change_tpdw();
openMenu(MenuID,MenuItme,0);
// put your main code here, to run repeatedly:
//float pressure;
//float Vout;
//float Vout=value1*5.0/1023.0;
//Vout=(value2*5.0*1000/1023.0);
//show_float_math(2,0,temp);show_string(2,6,"C");//lcd.print("C");
//show_float_math(3,0,pressure);show_string(3,6,"Kpa");//lcd.print("Kpa");
// delay(100);
//lcd.print(now.second());
//delay(3000);
}