#include #include #include #include #include "Nano100Series.h" #include "adc.h" #include "gpio.h" #include "pwm.h" #include "timer.h" #include "uart.h" #include "sys.h" #include "clk.h" #include "EEPROM_Emulate.h" #include "My_define.h" void delay_us(uint32_t us) { CLK_SysTickDelay(us); } void delay_ms(uint32_t ms) { while(ms--) { delay_us(1000); } } void UART0_Init()//hood { /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ SYS_ResetModule(UART0_RST); UART_Open(UART0, 9600); UART_EnableInt(UART0, UART_IER_RDA_IE_Msk); NVIC_EnableIRQ(UART0_IRQn); } void UART1_Init() { /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ SYS_ResetModule(UART1_RST); UART_Open(UART1, 115200); // HOMENET_485 : ErvDashboard 바이너리 프로토콜 (115200 N81) UART_EnableInt(UART1, UART_IER_RDA_IE_Msk); NVIC_EnableIRQ(UART1_IRQn); } void SC0_Init() // to roomcon { SCUART_Open(SC0, 1200); // Enable smartcard receive interrupt SCUART_ENABLE_INT(SC0, SC_IER_RDA_IE_Msk); NVIC_EnableIRQ(SC0_IRQn); } void SC1_Init() // to display { SCUART_Open(SC1, 115200); // Enable smartcard receive interrupt SCUART_ENABLE_INT(SC1, SC_IER_RDA_IE_Msk); NVIC_EnableIRQ(SC1_IRQn); } void PowerDownFunction(void) { ; } volatile uint32_t Bldc1_signal = 0, Bldc2_signal = 0; void GPABC_IRQHandler(void) { uint32_t reg; if(GPIO_GET_INT_FLAG(PA, BIT13)) { GPIO_CLR_INT_FLAG(PA, BIT13); CLK->WK_INTSTS = 1; /* clear interrupt status */ Bldc2_signal++; } else { reg = PA->ISRC; PA->ISRC = reg; reg = PB->ISRC; PB->ISRC = reg; reg = PC->ISRC; PC->ISRC = reg; } } void GPDEF_IRQHandler(void) { uint32_t reg; if(GPIO_GET_INT_FLAG(PE, BIT5)) { GPIO_CLR_INT_FLAG(PE, BIT5); CLK->WK_INTSTS = 1; /* clear interrupt status */ Bldc1_signal++; } else { reg = PD->ISRC; PD->ISRC = reg; reg = PE->ISRC; PE->ISRC = reg; reg = PF->ISRC; PF->ISRC = reg; } } volatile uint16_t Process_1000ms = 0, Process_333ms = 0,Process_100ms = 0, Process_10ms = 2,Process_5ms = 0; uint16_t com_roomcon_delay = 0; uint8_t Rx_homenet_TimeOut, Tx_homenet_TimeOut; uint16_t InCom_polling_timer = 0; uint16_t Hood_polling_timer = 0; uint8_t rx_hood_485_TimeOut = 0; uint16_t Hood_Conn_Timeout = 0; /* 후드 통신연결 생존 카운터(ms). 유효 응답 수신 시 재충전, 0이면 미연결 */ void TMR0_IRQHandler(void) { if(rx_hood_485_TimeOut)rx_hood_485_TimeOut--; if(Hood_polling_timer)Hood_polling_timer--; if(Hood_Conn_Timeout)Hood_Conn_Timeout--; if(InCom_polling_timer)InCom_polling_timer--; if(Tx_homenet_TimeOut)Tx_homenet_TimeOut--; if(Rx_homenet_TimeOut)Rx_homenet_TimeOut--; if(Rx_roomcon_TimeOut)Rx_roomcon_TimeOut--; if(com_roomcon_delay)com_roomcon_delay--; if(Process_1000ms)Process_1000ms--; if(Process_333ms)Process_333ms--; if(Process_100ms)Process_100ms--; if(Process_10ms)Process_10ms--; if(Process_5ms)Process_5ms--; // clear timer interrupt flag TIMER_ClearIntFlag(TIMER0); } // TIMER_ClearWakeupFlag(TIMER0); void Timer0_Init(void) { TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1000); // 1ms -> HZ // Enable timer interrupt TIMER_EnableInt(TIMER0); NVIC_EnableIRQ(TMR0_IRQn); // Start Timer 0 TIMER_Start(TIMER0); } void TMR1_IRQHandler(void) { Step_process(); // clear timer interrupt flag TIMER_ClearIntFlag(TIMER1); } void Timer1_Init(void) { TIMER_Open(TIMER1, TIMER_PERIODIC_MODE, 1000); // 2ms -> HZ // Enable timer interrupt TIMER_EnableInt(TIMER1); NVIC_EnableIRQ(TMR1_IRQn); // Start Timer 0 TIMER_Start(TIMER1); } void BLDC1_Duty_Change(uint32_t BLDC1_duty) // 0 ~ 10000 { PWM_ConfigOutputChannel(PWM1, 0, 1000, BLDC1_duty); // BLDC1 } void BLDC2_Duty_Change(uint32_t BLDC2_duty) // 0 ~ 10000 { PWM_ConfigOutputChannel(PWM0, 0, 1000, BLDC2_duty); // BLDC2 } void PWM_Init(void) { // PWM0 frequency is 300Hz, duty 50% PWM_ConfigOutputChannel(PWM0, 0, 1000, 10000); // BLDC2 PWM_ConfigOutputChannel(PWM1, 0, 1000, 10000); // BLDC1 // Enable output of all PWM channels PWM_EnableOutput(PWM0, 1<<0); // ch0 PWM_EnableOutput(PWM1, 1<<0); // // Start PWM_Start(PWM0, 1<<0); // pwm0_ch0 PWM_Start(PWM1, 1<<0); } volatile uint8_t ADC_Complete = 0; void ADC_IRQHandler(void) { uint32_t u32Flag; // Get ADC conversion finish interrupt flag u32Flag = ADC_GET_INT_FLAG(ADC, ADC_ADF_INT); if(u32Flag & ADC_ADF_INT) { ADC_Complete = 1; } ADC_CLR_INT_FLAG(ADC, u32Flag); } void ADC_Init(void) { // Enable channel 1 ADC_Open(ADC, ADC_INPUT_MODE_SINGLE_END, ADC_OPERATION_MODE_SINGLE_CYCLE, ADC_CH_0_MASK|ADC_CH_1_MASK|ADC_CH_2_MASK|ADC_CH_3_MASK|ADC_CH_4_MASK); // Set reference voltage to AVDD ADC_SET_REF_VOLTAGE(ADC, ADC_REFSEL_POWER); // Power on ADC ADC_POWER_ON(ADC); // Enable ADC ADC_IF interrupt ADC_EnableInt(ADC, ADC_ADF_INT); NVIC_EnableIRQ(ADC_IRQn); ADC_START_CONV(ADC); } void GPIO_Init(void) { GPIO_SetMode(PA, BIT13, GPIO_PMD_INPUT); // BLDC2_FG GPIO_ENABLE_PULL_UP(PA, BIT13); GPIO_EnableInt(PA, 13, GPIO_INT_FALLING); GPIO_SetMode(PA, BIT11, GPIO_PMD_INPUT); // SW GPIO_SetMode(PE, BIT5, GPIO_PMD_INPUT); // BLDC1_FG GPIO_ENABLE_PULL_UP(PE, BIT5); GPIO_EnableInt(PE, 5, GPIO_INT_FALLING); GPIO_SetMode(PC, BIT7, GPIO_PMD_OUTPUT); // BUNBAGI_485_DIR = 0; GPIO_SetMode(PB, BIT6, GPIO_PMD_OUTPUT); // HOMENET_485_DIR = 0; GPIO_SetMode(PB, BIT2, GPIO_PMD_OUTPUT); // HOOD_485_DIR = 0; GPIO_SetMode(PB, BIT7, GPIO_PMD_OUTPUT); // BLDC_PW BLDC_PW = 1; // OFF GPIO_SetMode(PA, BIT5, GPIO_PMD_OUTPUT); // ROOM_PW UV_PW = 1; GPIO_SetMode(PA, BIT10, GPIO_PMD_OUTPUT); // STATUS LED ST_LED = 1; GPIO_SetMode(PF, BIT2, GPIO_PMD_OUTPUT); // UV P_UV = 0; GPIO_SetMode(PA, BIT15|BIT14|BIT6, GPIO_PMD_OUTPUT); // STEP GPIO_SetMode(PB, BIT3|BIT9|BIT10|BIT12|BIT13|BIT14|BIT15|BIT8, GPIO_PMD_OUTPUT); // STEP GPIO_SetMode(PC, BIT8|BIT9|BIT10|BIT11|BIT2|BIT3|BIT14|BIT15|BIT6, GPIO_PMD_OUTPUT); // STEP GPIO_SetMode(PD, BIT15|BIT14|BIT7|BIT6, GPIO_PMD_OUTPUT); // STEP NVIC_EnableIRQ(GPABC_IRQn); NVIC_EnableIRQ(GPDEF_IRQn); /* Enable interrupt de-bounce function and select de-bounce sampling cycle time */ GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_HCLK, GPIO_DBCLKSEL_1); GPIO_ENABLE_DEBOUNCE(PA, BIT12); GPIO_ENABLE_DEBOUNCE(PE, BIT5); } void SYS_Init(void) { /* Unlock protected registers */ SYS_UnlockReg(); /* Enable clock source */ CLK_EnableXtalRC(CLK_PWRCTL_LIRC_EN_Msk|CLK_PWRCTL_HIRC_EN_Msk); /* Waiting for clock source ready */ CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk|CLK_CLKSTATUS_HIRC_STB_Msk); /* If the defines do not exist in your project, please refer to the related clk.h in the Header folder appended to the tool package. */ /* Set HCLK clock */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_HCLK_CLK_DIVIDER(1)); /* Enable IP clock */ CLK_EnableModuleClock(GPIO_MODULE); CLK_EnableModuleClock(ADC_MODULE); // CLK_EnableModuleClock(I2C0_MODULE); // CLK_EnableModuleClock(I2C1_MODULE); // CLK_EnableModuleClock(PWM0_CH23_MODULE); CLK_EnableModuleClock(PWM0_CH01_MODULE); CLK_EnableModuleClock(PWM1_CH01_MODULE); CLK_EnableModuleClock(ISP_MODULE); CLK_EnableModuleClock(SC0_MODULE); CLK_EnableModuleClock(SC1_MODULE); CLK_EnableModuleClock(SRAM_MODULE); CLK_EnableModuleClock(TICK_MODULE); CLK_EnableModuleClock(TMR0_MODULE); CLK_EnableModuleClock(TMR1_MODULE); CLK_EnableModuleClock(UART0_MODULE); CLK_EnableModuleClock(UART1_MODULE); CLK_EnableModuleClock(WDT_MODULE); /* Set IP clock */ CLK_SetModuleClock(ADC_MODULE, CLK_CLKSEL1_ADC_S_HIRC, CLK_ADC_CLK_DIVIDER(1)); // CLK_SetModuleClock(PWM0_CH23_MODULE, CLK_CLKSEL1_PWM0_CH23_S_HIRC, MODULE_NoMsk); CLK_SetModuleClock(PWM0_CH01_MODULE, CLK_CLKSEL1_PWM0_CH01_S_HIRC, MODULE_NoMsk); CLK_SetModuleClock(PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HIRC, MODULE_NoMsk); CLK_SetModuleClock(SC0_MODULE, CLK_CLKSEL2_SC_S_HIRC, CLK_SC0_CLK_DIVIDER(6)); CLK_SetModuleClock(SC1_MODULE, CLK_CLKSEL2_SC_S_HIRC, CLK_SC1_CLK_DIVIDER(1)); CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HIRC, MODULE_NoMsk); CLK_SetModuleClock(TMR1_MODULE, CLK_CLKSEL1_TMR1_S_HIRC, MODULE_NoMsk); CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_UART_CLK_DIVIDER(1)); CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_UART_CLK_DIVIDER(1)); /* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */ SystemCoreClockUpdate(); //If the defines do not exist in your project, please refer to the corresponding sys.h in the Header folder appended to the tool package. SYS->PA_H_MFP = SYS_PA_H_MFP_PA12_MFP_PWM0_CH0 | SYS_PA_H_MFP_PA9_MFP_SC0_DAT | SYS_PA_H_MFP_PA8_MFP_SC0_CLK; SYS->PA_L_MFP = SYS_PA_L_MFP_PA4_MFP_ADC_CH4 | SYS_PA_L_MFP_PA3_MFP_ADC_CH3 | SYS_PA_L_MFP_PA2_MFP_ADC_CH2 | SYS_PA_L_MFP_PA1_MFP_ADC_CH1 | SYS_PA_L_MFP_PA0_MFP_ADC_CH0; SYS->PB_H_MFP = SYS_PB_H_MFP_PB11_MFP_PWM1_CH0; SYS->PB_L_MFP = SYS_PB_L_MFP_PB5_MFP_UART1_TX | SYS_PB_L_MFP_PB4_MFP_UART1_RX | SYS_PB_L_MFP_PB1_MFP_UART0_TX | SYS_PB_L_MFP_PB0_MFP_UART0_RX; SYS->PC_H_MFP = 0x00000000; SYS->PC_L_MFP = SYS_PC_L_MFP_PC1_MFP_SC1_DAT | SYS_PC_L_MFP_PC0_MFP_SC1_CLK; SYS->PD_H_MFP = 0x00000000; SYS->PD_L_MFP = 0x00000000; SYS->PE_L_MFP = 0x00000000; SYS->PF_L_MFP = SYS_PF_L_MFP_PF1_MFP_ICE_CLK | SYS_PF_L_MFP_PF0_MFP_ICE_DAT; /* Lock protected registers */ SYS_LockReg(); return; } volatile uint8_t Run_Mode = 0, Auto_Mode = 0, Fan_Mode = 0; uint8_t Power_On = 0; extern signed int Out_Temperature; extern uint8_t Fan1_Speed, Fan2_Speed; volatile uint32_t Reserve_timer_sec = 0; uint16_t Filter_timer_sec = 1800; volatile uint16_t Filter_timer_clean = 0; volatile uint16_t Filter_timer_change = 0; volatile uint16_t Soja_timer_change = 0; void Reservation_process(void) { if(Power_On == 1)// power on - run { if(Reserve_timer_sec)Reserve_timer_sec--; if(Reserve_timer_sec == 1) { Power_off_process(1); } } } uint16_t UV_OnOff_Timer = 0; void UV_process(void) // 1sec { if(Roomcon_connect_mode == 0) { UV_OnOff = 0x00; if((Power_On == 0)) { UV_OnOff_Timer = 0; return; } if(UV_OnOff_Timer++ >= 3600)UV_OnOff_Timer = 0; if((Run_Mode == MODE_VENTILATION)||(Run_Mode == MODE_AUTO)||(Run_Mode == MODE_AIRCLEAN)) { #if(((SPEC_DEVICE_TYPE_INFO&0x0F) == 0x06)||((SPEC_DEVICE_TYPE_INFO&0x0F) == 0x08))//EF1 if(Run_Mode == MODE_AIRCLEAN) { if(UV_OnOff_Timer < 1800) { UV_OnOff = 0x10; } } #elif((SPEC_DEVICE_TYPE_INFO&0x0F) == 0x04)//EBSN if(Fan_Mode >= 2) { if(UV_OnOff_Timer < 900) { UV_OnOff = 0x10; } } #endif } } if(Power_On == 1) { if(UV_OnOff == 0x10) { if(Fan1_Speed != 0) P_UV = 1; else P_UV = 0; } else { P_UV = 0; } } else { P_UV = 0; } } extern volatile uint8_t Err_Code; void Filter_process(void) { if(Power_On == 1) { if(Filter_timer_sec++ >= 3600) { Filter_timer_sec = 0; if(Filter_timer_clean++ >= 2000) { Filter_timer_clean = 2000; Err_Code |= ERROR_FILTER_CLEAN; } if(Filter_timer_change++ >= 4000) { Filter_timer_change = 4000; Err_Code |= ERROR_FILTER_CHANGE; } if(Soja_timer_change++ >= 20000) { Soja_timer_change = 20000; Err_Code |= ERROR_SOJA_CHANGE; } EEP_Save_Flag = 1; } } if(Filter_Reset_Flag == 1) { Filter_Reset_Flag = 0; if(Filter_Reset_Process() == 1)EEP_Save_Flag = 1; } } uint8_t Sometime_cycle = 0, Pre_Sometime_cycle = 0; uint8_t Protect_Mode = 0; uint16_t Sometime_Timer = 0; uint8_t Sometime_Mode = 0; uint8_t Sometime_before_speed = 0; uint8_t Sometime_before_mode = 0; uint8_t Kijer_Mode = 0; uint16_t Kijer_Timer = 0; void Exception_mode_process(void) { if(Out_Temperature <= -15) { Protect_Mode = 1; Err_Code |= ERROR_PROTECT; Sometime_Mode = 0; Err_Code &= ~ERROR_SOMETIME; } else if(Out_Temperature >= -13) { Protect_Mode = 0; Err_Code &= ~ERROR_PROTECT; } if((Out_Temperature <= -7)&&(Protect_Mode == 0)) { if((Power_On == 1)&&(Run_Mode == MODE_AUTO)) { if(Sometime_Mode == 0) { Sometime_Mode = 1; Err_Code |= ERROR_SOMETIME; Sometime_Timer = 1800; // 30min } } else { Sometime_Mode = 0; Err_Code &= ~ERROR_SOMETIME; } } if(Out_Temperature >= -5) { if(Sometime_Mode == 1) { Sometime_Mode = 0; Err_Code &= ~ERROR_SOMETIME; } } if(Protect_Mode == 1) { if(Power_On == 0) { return; } else { Run_Mode = MODE_VENTILATION; Fan_Mode = 0; Reserve_timer_sec = 0; Power_off_process(1); } } else if(Sometime_Mode == 1) { if((Power_On == 0)||(Run_Mode != MODE_AUTO)) { Sometime_Timer = 0; Pre_Sometime_cycle = Sometime_cycle = 0; Sometime_Mode = 0; Err_Code &= ~ERROR_SOMETIME; return; } if(Sometime_Timer > 600) // 600 ~ 1800 -- 20min { Sometime_cycle = 1; Sometime_Timer--; } else if(Sometime_Timer > 0) // 600 ~ 0 -- 10min { Sometime_cycle = 0; Sometime_Timer--; } else { Sometime_cycle = 0; Sometime_Timer = 1800; } if(Sometime_cycle != Pre_Sometime_cycle) { if(Sometime_cycle == 1) { Run_Mode = MODE_AUTO; Fan_Mode = 1; } else { Run_Mode = MODE_AUTO; Fan_Mode = 0; } Pre_Sometime_cycle = Sometime_cycle; } } else { Pre_Sometime_cycle = Sometime_cycle = 0; } } //------------------------------------------------ typedef struct { char name; // 변수 이름 (a, b, c, d) uint8_t value; // 변수 값 }Var; Var vars[4] = { {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0} }; // 내림차순 정렬 함수 int compare(const void *x, const void *y) { Var *a = (Var *)x; Var *b = (Var *)y; // 값이 큰 순서대로 if (b->value != a->value) return b->value - a->value; else return a->name - b->name; // 값이 같으면 이름 순으로 } //----------------------------------------------- uint8_t CO2_quality[7] = {0,}; uint8_t PM2_5_quality[7] = {0,}; uint8_t VOC_quality[7] = {0,}; uint8_t ROOM_air_volume[7] = {0,}; uint16_t volatile CO2_Histeresys = 50; uint16_t Focus_Mode_RunTime = 0; uint8_t Focus_Mode = 0; uint8_t Focus_Air_Volume = 0; uint8_t Focus_Room_Number = 0; uint8_t Pre_Ext_Run_Mode = 0; uint16_t Ext_Run_Mode_Off_Delay = 0; uint8_t Memory_Hood_Status = 0; uint8_t RJ_Memory_Run_Mode = 0, RJ_Memory_Fan_Mode = 0; uint8_t My_Memory_Run_Mode = 0, My_Memory_Fan_Mode = 0; uint8_t Hood_YeunDong_Enable = 0; uint8_t Total_CV_Mode_Factot = 0; uint8_t Total_CVP_Fan_Factor = 0; /* ============================================================================ * 260428 v.Final 자동 동작로직 (집중/분산) - 제어로직_260428.xlsx (정본) * 실별 4종 센서를 0~4 단계로 변환 -> 실별 최고단계(Level) -> 부하총점(Score)/dP * - 풍량 단수 : Score 매핑 (0->0, 1~4->1, 5~8->2, 9~12->3, 13~16->4) * - dP = 정렬 내림차순[0]-[1] (두번째로 높은 단계, 동점 포함) * - 댐퍼 : P_max==0 전체대기 / dP>=2 집중(P_max 실만) / 그 외 분산(1단계↑ 실만) * ==========================================================================*/ /* 공기질 센서 히스테리시스 — 모드별(0=ECO,1=NORMAL,2=TURBO) 오염단계 상한 임계값. * [preset][4개 상한] = 0/1/2/3단계(좋음/보통/나쁨/매우나쁨)의 상한, 그 초과는 4단계(최악). * (변경 가능 : HOMENET 프리셋 값 설정으로 갱신) - 기본값은 사양서 표(260613 10p) */ uint16_t Co2_Thr[3][4] = {{1000,1300,1600,2000}, {800,1100,1400,1700}, {700,1000,1300,1600}}; uint16_t Pm25_Thr[3][4] = {{ 20, 38, 60, 86}, { 14, 29, 49, 69}, { 12, 23, 38, 52}}; uint16_t Pm10_Thr[3][4] = {{ 40, 86, 126, 173}, { 28, 66, 102, 138}, { 24, 53, 78, 104}}; uint16_t Voc_Thr[3][4] = {{ 171, 195, 308, 438}, {120, 150, 250, 350}, {103, 120, 192, 263}}; /* 히스테리시스 데드밴드(하강 시) [preset] : CO2,PM2.5,PM10,VOC */ uint16_t Co2_Db[3] = { 50, 50, 30}; uint16_t Pm25_Db[3] = { 2, 2, 2}; uint16_t Pm10_Db[3] = { 5, 5, 5}; uint16_t Voc_Db[3] = { 5, 5, 3}; uint8_t Hyst_Preset = 1; /* 0 ECO / 1 NORMAL / 2 TURBO */ uint8_t Room_Level[7] = {0,}; /* 실별 오염단계 0~4 (1=거실 2=침1 3=침2 4=침3) */ uint8_t Load_Score = 0; /* 부하 총점 0~16 */ uint8_t Auto_P_max = 0; /* 최고 단계 */ uint8_t Auto_dP = 0; /* P_max - P_2nd */ uint8_t Auto_Concentrate = 0; /* 0 분산 / 1 집중 (HOMENET autoState) */ /* 센서별 이전 단계(히스테리시스 데드존 유지용) */ static uint8_t Prev_CO2_Lv[7] = {0,}; static uint8_t Prev_PM25_Lv[7] = {0,}; static uint8_t Prev_PM10_Lv[7] = {0,}; static uint8_t Prev_VOC_Lv[7] = {0,}; /* 센서값 -> 0~4 단계. 하강 시 (임계-데드밴드) 이하라야 내려감. 데드존이면 이전 단계 유지 */ static uint8_t sensor_level(uint16_t v, const uint16_t *T, uint16_t db, uint8_t prev) { uint8_t lv = prev; if (v <= (uint16_t)(T[0] - db)) lv = 0; else if ((v > T[0]) && (v <= (uint16_t)(T[1] - db))) lv = 1; else if ((v > T[1]) && (v <= (uint16_t)(T[2] - db))) lv = 2; else if ((v > T[2]) && (v <= (uint16_t)(T[3] - db))) lv = 3; else if (v > T[3]) lv = 4; return lv; } /* 부하 총점(0~16) -> 풍량 단수(0~4) */ static uint8_t score_to_stage(uint8_t score) { if (score == 0) return 0; if (score <= 4) return 1; if (score <= 8) return 2; if (score <= 12) return 3; return 4; } uint8_t Air_Quality_damper_process(void) { uint8_t Tmp_Air_Volume = 0; uint8_t room_CV_quality = 0, room_CVP_quality = 0; uint8_t Room_Num = 0; Tmp_Air_Volume = 0; if(Force_Damper_Mode == 1) { if(Damper_Status_Display & 0x01){Memory_Diffuser_Dmp_Ang_SA[4] = 110;}else{Memory_Diffuser_Dmp_Ang_SA[4] = 0;}; if(Damper_Status_Display & 0x02){Memory_Diffuser_Dmp_Ang_RA[4] = 110;}else{Memory_Diffuser_Dmp_Ang_RA[4] = 0;}; if(Damper_Status_Display & 0x04){Memory_Diffuser_Dmp_Ang_SA[3] = 110;}else{Memory_Diffuser_Dmp_Ang_SA[3] = 0;}; if(Damper_Status_Display & 0x08){Memory_Diffuser_Dmp_Ang_RA[3] = 110;}else{Memory_Diffuser_Dmp_Ang_RA[3] = 0;}; if(Damper_Status_Display & 0x10){Memory_Diffuser_Dmp_Ang_SA[2] = 110;}else{Memory_Diffuser_Dmp_Ang_SA[2] = 0;}; if(Damper_Status_Display & 0x20){Memory_Diffuser_Dmp_Ang_RA[2] = 110;}else{Memory_Diffuser_Dmp_Ang_RA[2] = 0;}; if(Damper_Status_Display & 0x40){Memory_Diffuser_Dmp_Ang_SA[1] = 110;}else{Memory_Diffuser_Dmp_Ang_SA[1] = 0;}; if(Damper_Status_Display & 0x80){Memory_Diffuser_Dmp_Ang_RA[1] = 110;}else{Memory_Diffuser_Dmp_Ang_RA[1] = 0;}; if((Memory_Diffuser_Dmp_Ang_SA[4] != 0)||(Memory_Diffuser_Dmp_Ang_RA[4] != 0))Diffuser_Air_quality[4] = 5; else Diffuser_Air_quality[4] = 0; if((Memory_Diffuser_Dmp_Ang_SA[3] != 0)||(Memory_Diffuser_Dmp_Ang_RA[3] != 0))Diffuser_Air_quality[3] = 5; else Diffuser_Air_quality[3] = 0; if((Memory_Diffuser_Dmp_Ang_SA[2] != 0)||(Memory_Diffuser_Dmp_Ang_RA[2] != 0))Diffuser_Air_quality[2] = 5; else Diffuser_Air_quality[2] = 0; if((Memory_Diffuser_Dmp_Ang_SA[1] != 0)||(Memory_Diffuser_Dmp_Ang_RA[1] != 0))Diffuser_Air_quality[1] = 5; else Diffuser_Air_quality[1] = 0; Tmp_Air_Volume = Set_Fan_Mode; Ext_Run_Mode_Off_Delay = 0; goto PASS_RETURN; } else if((Ext_Run_Mode == 1)&&(Pre_Ext_Run_Mode != 1)) //안심회복 모드 { Memory_Diffuser_Dmp_Ang_SA[6] = 110; Memory_Diffuser_Dmp_Ang_SA[5] = 110; Memory_Diffuser_Dmp_Ang_SA[4] = 110; Memory_Diffuser_Dmp_Ang_SA[3] = 110; Memory_Diffuser_Dmp_Ang_SA[2] = 110; Memory_Diffuser_Dmp_Ang_SA[1] = 110; Memory_Diffuser_Dmp_Ang_RA[6] = 0; Memory_Diffuser_Dmp_Ang_RA[5] = 0; Memory_Diffuser_Dmp_Ang_RA[4] = 0; Memory_Diffuser_Dmp_Ang_RA[3] = 0; Memory_Diffuser_Dmp_Ang_RA[2] = 0; Memory_Diffuser_Dmp_Ang_RA[1] = 0; Memory_Diffuser_Dmp_Ang_SA[Ext_Select_Room] = 0; Memory_Diffuser_Dmp_Ang_RA[Ext_Select_Room] = 110; Diffuser_Air_quality[6] = 5;//ON Diffuser_Air_quality[5] = 5;//ON Diffuser_Air_quality[4] = 5;//ON Diffuser_Air_quality[3] = 5;//ON Diffuser_Air_quality[2] = 5;//ON Diffuser_Air_quality[1] = 5;//ON Tmp_Air_Volume = 2;//3;/////////////// 2026.1.8 전경선... Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED); My_Memory_Run_Mode = Run_Mode; My_Memory_Fan_Mode = Fan_Mode; Set_Run_Mode = MODE_VENTILATION; Set_Fan_Mode = 2;//3; /////////////// 2026.1.8 전경선... Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; goto PASS_VOLUME; } else if((Ext_Run_Mode == 2)&&(Pre_Ext_Run_Mode != 2)) //쾌적조리 En { Hood_YeunDong_Enable = 1; Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; } else if((Ext_Run_Mode == 3)&&(Pre_Ext_Run_Mode != 3)) //집중청정 모드 { Memory_Diffuser_Dmp_Ang_SA[6] = 0; Memory_Diffuser_Dmp_Ang_SA[5] = 0; Memory_Diffuser_Dmp_Ang_SA[4] = 0; Memory_Diffuser_Dmp_Ang_SA[3] = 0; Memory_Diffuser_Dmp_Ang_SA[2] = 0; Memory_Diffuser_Dmp_Ang_SA[1] = 0; Memory_Diffuser_Dmp_Ang_RA[6] = 0; Memory_Diffuser_Dmp_Ang_RA[5] = 0; Memory_Diffuser_Dmp_Ang_RA[4] = 0; Memory_Diffuser_Dmp_Ang_RA[3] = 0; Memory_Diffuser_Dmp_Ang_RA[2] = 0; Memory_Diffuser_Dmp_Ang_RA[1] = 0; Memory_Diffuser_Dmp_Ang_SA[Ext_Select_Room] = 110; Memory_Diffuser_Dmp_Ang_RA[Ext_Select_Room] = 110; Diffuser_Air_quality[6] = 0;//OFF Diffuser_Air_quality[5] = 0;//OFF Diffuser_Air_quality[4] = 0;//OFF Diffuser_Air_quality[3] = 0;//OFF Diffuser_Air_quality[2] = 0;//OFF Diffuser_Air_quality[1] = 0;//OFF Diffuser_Air_quality[Ext_Select_Room] = 5;//ON Tmp_Air_Volume = 2; Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED); My_Memory_Run_Mode = Run_Mode; My_Memory_Fan_Mode = Fan_Mode; Set_Run_Mode = MODE_VENTILATION; Set_Fan_Mode = 2; Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; goto PASS_VOLUME; } else if(Ext_Run_Mode == 4) //스마트 수면 모드 (사양서 8p) : 환기 수동·1단 고정, 실별 CO2 기준 댐퍼 개폐 { if(Pre_Ext_Run_Mode != 4) /* 진입 1회 : 모드/풍량 + 초기상태(거실 CLOSE, 침실1~3 OPEN) */ { Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED); My_Memory_Run_Mode = Run_Mode; My_Memory_Fan_Mode = Fan_Mode; Set_Run_Mode = MODE_VENTILATION; Set_Fan_Mode = 1; Memory_Diffuser_Dmp_Ang_SA[1] = 0; Memory_Diffuser_Dmp_Ang_RA[1] = 0; /* 거실 CLOSE */ for(Room_Num = 2; Room_Num < 5; Room_Num++) /* 침실1~3 OPEN */ { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; } Memory_Diffuser_Dmp_Ang_SA[5] = 0; Memory_Diffuser_Dmp_Ang_RA[5] = 0; Memory_Diffuser_Dmp_Ang_SA[6] = 0; Memory_Diffuser_Dmp_Ang_RA[6] = 0; Pre_Ext_Run_Mode = Ext_Run_Mode; Pre_Ext_Select_Room = Ext_Select_Room; } /* 매 틱 : 실별 CO2 히스테리시스. CO2 >= 1000 OPEN, <= 800 CLOSE, 그 사이(데드존)는 현재 상태 유지 */ for(Room_Num = 1; Room_Num < 5; Room_Num++) { if(SEN66_CO2_value[Room_Num] >= 1000) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; } else if(SEN66_CO2_value[Room_Num] <= 800) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 0; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 0; } if((Memory_Diffuser_Dmp_Ang_SA[Room_Num] != 0)||(Memory_Diffuser_Dmp_Ang_RA[Room_Num] != 0)) Diffuser_Air_quality[Room_Num] = 5;//ON else Diffuser_Air_quality[Room_Num] = 0;//OFF } Tmp_Air_Volume = 1; /* 1단 고정 */ Ext_Run_Mode_Off_Delay = 0; goto PASS_VOLUME; } else if((Ext_Run_Mode == 0)&&((Pre_Ext_Run_Mode == 1)||(Pre_Ext_Run_Mode == 3)||(Pre_Ext_Run_Mode == 4))) { if(Power_On == 1) { Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED); Set_Run_Mode = My_Memory_Run_Mode; Set_Fan_Mode = My_Memory_Fan_Mode; Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; } Ext_Run_Mode_Off_Delay = 0; } else if((Ext_Run_Mode == 0)&&(Pre_Ext_Run_Mode == 2))// 쾌적조리(후드연동) 토글 OFF -> 연동 없음(사양 260613 9p 3.1) { Hood_YeunDong_Enable = 0; /* 메이크업 에어 동작중(후드 가동/롤백 유지)이었으면 본래 운전모드/풍량으로 즉시 복귀(롤백 딜레이 없음) */ if((Power_On == 1)&&((Hood_Status != 0)||(Hood_Yeundong_flag != 0)||(Hood_Warming_up_Timer != 0))) { Set_Run_Mode = My_Memory_Run_Mode; Set_Fan_Mode = My_Memory_Fan_Mode; Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED); } Hood_Yeundong_flag = 0; Hood_Warming_up_Timer = 0; Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; goto PASS_VOLUME; } else if((Ext_Run_Mode != 0)&&(Ext_Run_Mode != 2)) { Pre_Ext_Run_Mode = Ext_Run_Mode ; Pre_Ext_Select_Room = Ext_Select_Room; if(Run_Mode != MODE_AUTO)goto PASS_VOLUME; } Total_CV_Mode_Factot = 0; Total_CVP_Fan_Factor = 0; for(Room_Num = 1; Room_Num < 6; Room_Num++) { uint8_t lc, lp25, lp10, lvc, lvl; /* 4종 센서 각각 0~4 단계 (모드별 임계 + 하강 히스테리시스) */ lc = sensor_level(SEN66_CO2_value[Room_Num], Co2_Thr[Hyst_Preset], Co2_Db[Hyst_Preset], Prev_CO2_Lv[Room_Num]); lp25 = sensor_level(SEN66_pm2p5[Room_Num], Pm25_Thr[Hyst_Preset], Pm25_Db[Hyst_Preset], Prev_PM25_Lv[Room_Num]); lp10 = sensor_level(SEN66_pm10p0[Room_Num], Pm10_Thr[Hyst_Preset], Pm10_Db[Hyst_Preset], Prev_PM10_Lv[Room_Num]); lvc = sensor_level((uint16_t)SEN66_VOC_value[Room_Num], Voc_Thr[Hyst_Preset], Voc_Db[Hyst_Preset], Prev_VOC_Lv[Room_Num]); Prev_CO2_Lv[Room_Num]=lc; Prev_PM25_Lv[Room_Num]=lp25; Prev_PM10_Lv[Room_Num]=lp10; Prev_VOC_Lv[Room_Num]=lvc; /* 실 오염단계 = 4종 중 최고 */ lvl = lc; if(lp25 > lvl) lvl = lp25; if(lp10 > lvl) lvl = lp10; if(lvc > lvl) lvl = lvc; Room_Level[Room_Num] = lvl; ROOM_air_volume[Room_Num] = lvl; if(lvl) Total_CV_Mode_Factot = 1; /* AUTO 외(수동/바이패스/공청) 및 전원OFF 댐퍼는 여기서 결정. AUTO 는 집중/분산 판정 후 일괄 처리하므로 여기서 건드리지 않음 */ if(Power_On != 1) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 0; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 0; Diffuser_Air_quality[Room_Num] = 0;//OFF Diffuser_Damper_Manual[Room_Num] = 0; /* 전원OFF - 수동 댐퍼 해제 */ } else if(Run_Mode != MODE_AUTO) { /* 환기/공청/바이패스 : 전실 개방. 단, 대시보드 수동 댐퍼(Manual) 실은 위치 유지 */ if(Diffuser_Damper_Manual[Room_Num] == 0) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; } Diffuser_Air_quality[Room_Num] = 5;//ON Tmp_Air_Volume = Diffuser_Fan_Speed[1] = Fan_Mode; //manual } else /* MODE_AUTO : 자동 제어 - 수동 댐퍼 해제 */ { Diffuser_Damper_Manual[Room_Num] = 0; } } if(Power_On != 1) { Focus_Mode = 0; Focus_Mode_RunTime = 0; Auto_Concentrate = 0; Tmp_Air_Volume = 0; } /* ===== 부하 총점(Score) / P_max / dP : 거실+침실3실(1~4) ===== */ Load_Score = (uint8_t)(Room_Level[1] + Room_Level[2] + Room_Level[3] + Room_Level[4]); { uint8_t max1 = 0, max2 = 0, r, v; /* 260428 v.Final : dP = 정렬 내림차순[0]-[1] (= 두번째로 높은 단계, 동점 포함). 최고단계 실이 2개 이상 동점이면 max2=max1 -> dP=0 -> 분산. 한 실만 확실히(2↑) 나쁠 때만 집중. 예) {0,3,3,0}->분산, {0,3,0,0}->집중, {2,2,1,1}->분산, {4,4,4,4}->분산 */ for(r = 1; r < 5; r++) { v = Room_Level[r]; if(v > max1) { max2 = max1; max1 = v; } /* 1·2위 갱신 */ else if(v > max2) { max2 = v; } /* 2위만 갱신(동점 포함) */ } Auto_P_max = max1; Auto_dP = (uint8_t)(max1 - max2); } if(Run_Mode == MODE_AUTO) { /* 자동 = 환기 기반 */ if(Auto_Mode != (MODE_VENTILATION+1)) { Auto_Mode = MODE_VENTILATION+1; Command_request_type |= (TYPE_MODE); } /* === 댐퍼 개폐 모드 결정 (대기 / 집중 / 분산) === */ if(Auto_P_max == 0) /* 대기 : 전 실 OFF */ { Auto_Concentrate = 0; Focus_Mode = 0; for(Room_Num = 1; Room_Num < 7; Room_Num++) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 0; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 0; Diffuser_Air_quality[Room_Num] = 0; } } else if(Auto_dP >= 2) /* 집중 : P_max 실만 개방 */ { Auto_Concentrate = 1; Focus_Mode = 1; for(Room_Num = 1; Room_Num < 7; Room_Num++) { if((Room_Num < 5) && (Room_Level[Room_Num] == Auto_P_max)) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; Diffuser_Air_quality[Room_Num] = 5; } else { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 0; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 0; Diffuser_Air_quality[Room_Num] = 0; } } } else /* 분산 : 1단계 이상 실만 개방 (260428 : 0단계 좋음 실은 닫음) */ { Auto_Concentrate = 0; Focus_Mode = 0; for(Room_Num = 1; Room_Num < 7; Room_Num++) { if((Room_Num < 5) && (Room_Level[Room_Num] >= 1)) { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; Diffuser_Air_quality[Room_Num] = 5; } else { Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 0; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 0; Diffuser_Air_quality[Room_Num] = 0; } } } /* === 최종 풍량 : 부하 총점 매핑 === */ Tmp_Air_Volume = score_to_stage(Load_Score); if(Tmp_Air_Volume > 4) Tmp_Air_Volume = 4; if(Set_Fan_Mode != Tmp_Air_Volume) { Set_Fan_Mode = Diffuser_Fan_Speed[1] = Tmp_Air_Volume; Command_request_type |= (TYPE_FAN_SPEED); } } else { Focus_Mode = 0; Focus_Mode_RunTime = 0; /* 쾌적조리 메이크업 에어(사양 260613 9p) : 후드 가동중(Hood_Status!=0 / 연동플래그) 전실 급기(SA) 100% 개방, 배기(RA) 닫힘. 풍량은 Hood_process() 가 후드 단수를 추종(1->1,2->2,3->3,4->4,5->4)하여 Set_Fan_Mode 로 반영. 조리 종료 후 잔여 배출(메이크업 유지)은 후드측이 담당 → 후드 OFF 시 즉시 복귀. */ if((Hood_YeunDong_Enable == 1)&&((Hood_Status != 0)||(Hood_Yeundong_flag == 1))) { Memory_Diffuser_Dmp_Ang_SA[1] = 110; Memory_Diffuser_Dmp_Ang_RA[1] = 0; Memory_Diffuser_Dmp_Ang_SA[2] = 110; Memory_Diffuser_Dmp_Ang_RA[2] = 0; Memory_Diffuser_Dmp_Ang_SA[3] = 110; Memory_Diffuser_Dmp_Ang_RA[3] = 0; Memory_Diffuser_Dmp_Ang_SA[4] = 110; Memory_Diffuser_Dmp_Ang_RA[4] = 0; Diffuser_Air_quality[1] = 5;//ON Diffuser_Air_quality[2] = 5;//ON Diffuser_Air_quality[3] = 5;//ON Diffuser_Air_quality[4] = 5;//ON } } PASS_VOLUME: if(Tmp_Air_Volume > 4)Tmp_Air_Volume = 4; if(Focus_Mode_RunTime != 0) { if(Tmp_Air_Volume != Focus_Air_Volume) { Command_request_type |= (TYPE_FAN_SPEED); if(Tmp_Air_Volume > Focus_Air_Volume){Set_Fan_Mode = Focus_Air_Volume = Tmp_Air_Volume;} else {Set_Fan_Mode = Tmp_Air_Volume = Focus_Air_Volume;} } } if(Ext_Run_Mode == 4) { if(Tmp_Air_Volume >= 2)Tmp_Air_Volume -= 1; if(Set_Fan_Mode != Tmp_Air_Volume) { Set_Fan_Mode = Diffuser_Fan_Speed[1] = Tmp_Air_Volume; Command_request_type |= (TYPE_FAN_SPEED); } } /* ===== LED 추종 : 댐퍼 개방→LED ON(9), 닫힘/전원OFF→소등. 수동 LED(CTRL_LED, Diffuser_Led_Manual)는 모든 모드에서 값 유지, 전원OFF 시에만 해제. ===== */ for(Room_Num = 1; Room_Num < 5; Room_Num++) { if(Power_On != 1) Diffuser_Led_Manual[Room_Num] = 0; /* 전원OFF - 수동 LED 해제 */ if(Diffuser_Led_Manual[Room_Num]) continue; /* 수동값 유지 */ if((Power_On == 1) && ((Memory_Diffuser_Dmp_Ang_SA[Room_Num] != 0) || (Memory_Diffuser_Dmp_Ang_RA[Room_Num] != 0))) Light_Bright[Room_Num] = 9; else Light_Bright[Room_Num] = 0; } PASS_RETURN: return(Tmp_Air_Volume); } uint8_t Air_Quality_color_process(void) { uint8_t room_CV_quality = 0, room_PM_quality = 0, total_room_CV_quality = 0, total_room_PM_quality = 0; uint8_t Room_Num = 0; total_room_CV_quality = 0; total_room_PM_quality = 0; ///////////////////////////////////////////////// return(0); /////////////////////////////////////////////////// for(Room_Num = 1; Room_Num < 7; Room_Num++) { room_CV_quality = 0; room_PM_quality = 0; if(SEN66_CO2_value[Room_Num] <= (uint16_t)(m_CO2_Level_1-CO2_Histeresys)) CO2_quality[Room_Num] = 0; // 2025.5.13 himpel else if((SEN66_CO2_value[Room_Num] > (uint16_t)(m_CO2_Level_1))&&(SEN66_CO2_value[Room_Num] <= (uint16_t)(m_CO2_Level_2-CO2_Histeresys))) CO2_quality[Room_Num] = 0x01; else if((SEN66_CO2_value[Room_Num] > (uint16_t)(m_CO2_Level_2))&&(SEN66_CO2_value[Room_Num] <= (uint16_t)(m_CO2_Level_3-CO2_Histeresys))) CO2_quality[Room_Num] = 0x02; else if((SEN66_CO2_value[Room_Num] > (uint16_t)(m_CO2_Level_3))&&(SEN66_CO2_value[Room_Num] <= (uint16_t)(m_CO2_Level_4-CO2_Histeresys))) CO2_quality[Room_Num] = 0x04; else if(SEN66_CO2_value[Room_Num] > (uint16_t)(m_CO2_Level_4)) CO2_quality[Room_Num] = 0x08; if(SEN66_pm2p5[Room_Num] <= m_PM2_5_Level_1) PM2_5_quality[Room_Num] = 0; else if(SEN66_pm2p5[Room_Num] < m_PM2_5_Level_2) PM2_5_quality[Room_Num] = 0x01; else if(SEN66_pm2p5[Room_Num] < m_PM2_5_Level_3) PM2_5_quality[Room_Num] = 0x02; else if(SEN66_pm2p5[Room_Num] < m_PM2_5_Level_4) PM2_5_quality[Room_Num] = 0x04; else PM2_5_quality[Room_Num] = 0x08; if(SEN66_VOC_value[Room_Num] <= m_VOC_Level_1) VOC_quality[Room_Num] = 0; else if(SEN66_VOC_value[Room_Num] < m_VOC_Level_2) VOC_quality[Room_Num] = 0x01; else if(SEN66_VOC_value[Room_Num] <= m_VOC_Level_3) VOC_quality[Room_Num] = 0x02; else if(SEN66_VOC_value[Room_Num] <= m_VOC_Level_4) VOC_quality[Room_Num] = 0x04; else VOC_quality[Room_Num] = 0x08; room_CV_quality = CO2_quality[Room_Num] | VOC_quality[Room_Num]; room_PM_quality = PM2_5_quality[Room_Num]; if(room_CV_quality == 0) //Quality - Good { Diffuser_Air_quality[Room_Num] = Memory_Diffuser_Air_quality[Room_Num] = 0; } else if(room_CV_quality < 2) //Quality - Normal { Diffuser_Air_quality[Room_Num] = Memory_Diffuser_Air_quality[Room_Num] = 5; } else if(room_CV_quality < 4) //Quality - Bad { Diffuser_Air_quality[Room_Num] = 5; } else if(room_CV_quality < 8) //Quality - Bad Bad { Diffuser_Air_quality[Room_Num] = Memory_Diffuser_Air_quality[Room_Num] = 5; } else //Quality - Very Bad { Diffuser_Air_quality[Room_Num] = Memory_Diffuser_Air_quality[Room_Num] = 5; } total_room_CV_quality |= room_CV_quality; total_room_PM_quality |= room_PM_quality; } return(0); }