/*** Beginheader */ #ifndef __AIT_PWR_LIB #define __AIT_PWR_LIB #define USERBLOCK_INTERVAL_SEC 300 #define NEW_BLOCK_DEFINITION 0 static unsigned long int UserBlockID ; static struct UB { unsigned long Updated; unsigned long PowerCount; unsigned long PowerMin; unsigned long PowerDay; unsigned long PowerYesterday; int DayNum; unsigned long PowerYestermonth; float Z1_Setpoint; float Z2_Setpoint; float Z3_Setpoint; float Z4_Setpoint; float WW_Setpoint; float AIR_Delta; float WATER_Delta; float Z1_Setback; float Z2_Setback; float Z3_Setback; float Z4_Setback; float WW_LowerLimit; int Comfort_Start; int Comfort_Stop; int DHW_Priority_Start; int DHW_Priority_Stop; } UB ; #define POWER_INTERVAL_SEC 60 #define POWER_FILTER_COEFF 1.0 #define KWATTHOURS_PER_COUNT 3.448e-5 #define WATTLOAD_PER_COUNT ((3.448e-2 * 3600.0) / (float)POWER_INTERVAL_SEC ) #define AIR_HEAT_SETPOINT_DEFAULT 70.0 #define AIR_COOL_SETPOINT_DEFAULT 76.0 #define AIR_HEAT_SETBACK_DEFAULT 65.0 #define AIR_DELTA_DEFAULT 1.0 #define WATER_SETPOINT_DEFAULT 120.0 #define WATER_DELTA_DEFAULT 3.0 #define HVAC_COMFORT_START_DEFAULT 700 #define HVAC_COMFORT_STOP_DEFAULT 2300 #define HVAC_DHW_PRIORITY_START_DEFAULT 630 #define HVAC_DHW_PRIORITY_STOP_DEFAULT 930 /*** Endheader */ /* START LIBRARY DESCRIPTION ********************************************* AIT_PWR.LIB Copyright (c) 2004, Adaptive Internet Technologies DESCRIPTION: AIT Power Meter Functions, and User Block Management SUPPORT LIBS: REVISION HISTORY: 1.1 12/04/03 Original Issue END DESCRIPTION **********************************************************/ //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--// /*** BeginHeader AIT_InitUserBlock, AIT_WriteUserData, PRW_Init, PWR_ReadMeter, PWR_End */ // ----------------------------------------------- // PowerMonitoring variables // ----------------------------------------------- static unsigned long int PowerLast; int P1_Index; int P2_Index; int P3_Index; int P4_Index; int DayNum; unsigned long int PowerPrior; unsigned long int PowerNow; unsigned long int PowerMin; unsigned long int PowerDay; SENSOR * pSensor; struct tm rtc; // time struct void PowerMonitor_ISR(); void AIT_InitUserBlock(); void AIT_WriteUserData(); int PWR_Init(SENSOR * Devices, int ActiveDevices); void PWR_ReadMeter(SENSOR * Devices); void PWR_End(); /*** EndHeader */ /* START _FUNCTION DESCRIPTION ******************************************** AIT_InitUserBlock SYNTAX: void AIT_InitUserBlock() DESCRIPTION: Reads Block ID and reads/writes based on ID match Response characters SEE ALSO: END DESCRIPTION **********************************************************/ void AIT_InitUserBlock() { if (readUserBlock(&UserBlockID, 0, sizeof(UserBlockID)) < 0) printf ("Error: Could not read user block ID\n"); else printf ("User Block ID = %08lX\n", UserBlockID); // read or write ?? if (UserBlockID == USER_BLOCK_ID) { // Good ID so read last values... printf("Reading Block\n"); readUserBlock(&UB, sizeof(UserBlockID), sizeof(UB)); // CODE for loading new variables into block if ( NEW_BLOCK_DEFINITION ) { // rtc.tm_sec = 0; // 0-59 // rtc.tm_min = 15; // 0-59 // rtc.tm_hour = 11; // 0-23 // rtc.tm_mday = 4; // 1-31 // rtc.tm_mon = 4; // 1-12 // rtc.tm_year = 104; // 80-147, add 1900 to get year // tm_wr(&rtc); // set clock // printf("RTC changed!\n\n"); AIT_WriteUserData(); } if (AIT_GetDay() != UB.DayNum) { UB.PowerYesterday = UB.PowerDay; UB.PowerDay = 0l; UB.DayNum = AIT_GetDay(); // Check for new month if (UB.DayNum == 1) { // New month so save count value UB.PowerYestermonth = UB.PowerCount; UB.PowerCount = 0l ; } // Update User Block with new numbers. AIT_WriteUserData(); } } else { // Bad ID so write new values... printf("Writing Block\n"); UB.Updated = SEC_TIMER; UB.DayNum = AIT_GetDay(); UB.PowerCount = 0l ; UB.PowerMin = 0l ; UB.PowerDay = 0l ; UB.PowerYesterday = 0l ; UB.PowerYestermonth = 0l ; UB.Z1_Setpoint = AIR_HEAT_SETPOINT_DEFAULT; UB.Z2_Setpoint = AIR_HEAT_SETPOINT_DEFAULT; UB.Z3_Setpoint = AIR_HEAT_SETPOINT_DEFAULT; UB.Z4_Setpoint = AIR_HEAT_SETPOINT_DEFAULT; UB.WW_Setpoint = WATER_SETPOINT_DEFAULT; UB.AIR_Delta = AIR_DELTA_DEFAULT; UB.WATER_Delta = WATER_DELTA_DEFAULT; UB.Z1_Setback = AIR_HEAT_SETBACK_DEFAULT; UB.Z2_Setback = AIR_HEAT_SETBACK_DEFAULT; UB.Z3_Setback = AIR_HEAT_SETBACK_DEFAULT; UB.Z4_Setback = AIR_HEAT_SETBACK_DEFAULT; UB.WW_LowerLimit = WATER_SETPOINT_DEFAULT - WATER_DELTA_DEFAULT; UB.Comfort_Start = HVAC_COMFORT_START_DEFAULT; UB.Comfort_Stop = HVAC_COMFORT_STOP_DEFAULT; UB.DHW_Priority_Start = HVAC_DHW_PRIORITY_START_DEFAULT; UB.DHW_Priority_Stop = HVAC_DHW_PRIORITY_STOP_DEFAULT; AIT_WriteUserData(); // write correct Block ID UserBlockID = USER_BLOCK_ID ; writeUserBlock(0, &UserBlockID, sizeof(UserBlockID)); } // printf("\nPower: %d, %lu, %lu, %lu, %lu \n", // UB.DayNum, UB.PowerCount, UB.PowerMin, UB.PowerDay, UB.PowerYesterday); } /* START _FUNCTION DESCRIPTION ******************************************** PWR_Init SYNTAX: int PWR_Init(SENSOR * Devices, int ActiveDevices) PARAMETER1: The array of Sensor data structures PARAMETER2: Number of sensors currently defined DESCRIPTION: Uses User Block and sets up power monitor. Sets Up Interrupt Load additional sensor variables RETURNS: New number of Active devices SEE ALSO: END DESCRIPTION **********************************************************/ int PWR_Init(SENSOR * Devices, int ActiveDevices) { // Add additional Power devices to sensor list P1_Index = ActiveDevices++; P2_Index = ActiveDevices++; P3_Index = ActiveDevices++; P4_Index = ActiveDevices++; strncpy(Devices[P1_Index].Name, "P1", sizeof(Devices[0].Name)-1); Devices[P1_Index].Type = DEV_PWR; // Accumulated Power Sensor Devices[P1_Index].Scale = KWATTHOURS_PER_COUNT; Devices[P1_Index].Offset = 0.0; Devices[P1_Index].FilterTC = POWER_FILTER_COEFF ; strncpy(Devices[P2_Index].Name, "P2", sizeof(Devices[0].Name)-1); Devices[P2_Index].Type = DEV_PWR; // Load Devices[P2_Index].Scale = WATTLOAD_PER_COUNT; Devices[P2_Index].Offset = 0.0; Devices[P2_Index].FilterTC = POWER_FILTER_COEFF ; strncpy(Devices[P3_Index].Name, "P3", sizeof(Devices[0].Name)-1); Devices[P3_Index].Type = DEV_PWR; // Today's Total so far Devices[P3_Index].Scale = KWATTHOURS_PER_COUNT; Devices[P3_Index].Offset = 0.0; Devices[P3_Index].FilterTC = POWER_FILTER_COEFF ; strncpy(Devices[P4_Index].Name, "P4", sizeof(Devices[0].Name)-1); Devices[P4_Index].Type = DEV_PWR; // Yesterday's total Devices[P4_Index].Scale = KWATTHOURS_PER_COUNT; Devices[P4_Index].Offset = 0.0; Devices[P4_Index].FilterTC = POWER_FILTER_COEFF ; PowerLast = MS_TIMER; PowerPrior = UB.PowerCount; PowerNow = 0l; // Set equal to 1 to use fast interrupt in I&D space #define FAST_INTERRUPT 1 #if __SEPARATE_INST_DATA__ && FAST_INTERRUPT interrupt_vector ext1_intvec PowerMonitor_ISR; #else SetVectExtern3000(1, PowerMonitor_ISR); #endif WrPortI(I1CR, &I1CRShadow, 0x09); // enable external INT1 on PE1, rising edge, priority 1 return (ActiveDevices); } /* START _FUNCTION DESCRIPTION ******************************************** PWR_End SYNTAX: void PWR_End() DESCRIPTION: Disables Interrupt SEE ALSO: END DESCRIPTION **********************************************************/ void PWR_End() { WrPortI(I1CR, &I1CRShadow, 0x00); // disable external interrupt 1 } /* START _FUNCTION DESCRIPTION ******************************************** PWR_ReadMeter SYNTAX: read PWR_ReadMeter(SENSOR * Devices) PARAMETER1: The array of Sensor data structures DESCRIPTION: Reads the power usage and updates sensor variables SEE ALSO: END DESCRIPTION **********************************************************/ void PWR_ReadMeter(SENSOR * Devices) { // Accumulate all the Power Sensor Values PowerNow = UB.PowerCount; UB.PowerMin = PowerNow - PowerPrior; UB.PowerDay += UB.PowerMin; // See if we are next day if (AIT_GetDay() != UB.DayNum) { UB.PowerYesterday = UB.PowerDay; UB.PowerDay = 0l; UB.DayNum = AIT_GetDay(); // Check for new month if (UB.DayNum == 1) { // New month so save count value UB.PowerYestermonth = UB.PowerCount; UB.PowerCount = 0l ; PowerNow = 0l; PowerPrior = 0l; } // Update User Block with new numbers. AIT_WriteUserData(); // printf("\nSaving: %d, %lu, %lu, %lu, %lu > ", // UB.DayNum, UB.PowerCount, UB.PowerMin, UB.PowerDay, UB.PowerYesterday); } PowerPrior = PowerNow ; // Store all the connverted values in the Sensor Array pSensor = &Devices[P1_Index] ; pSensor->Raw = (float)UB.PowerCount; OW_ScaleSensor(pSensor); pSensor = &Devices[P2_Index] ; pSensor->Raw = (float)UB.PowerMin ; OW_ScaleSensor(pSensor); pSensor = &Devices[P3_Index] ; pSensor->Raw = (float)UB.PowerDay ; OW_ScaleSensor(pSensor); pSensor = &Devices[P4_Index] ; pSensor->Raw = (float)UB.PowerYesterday ; OW_ScaleSensor(pSensor); // printf("\nSaving: %d, %lu, %lu, %lu, %lu > ", // UB.DayNum, UB.PowerCount, UB.PowerMin, UB.PowerDay, UB.PowerYesterday); } /* START _FUNCTION DESCRIPTION ******************************************** AIT_WriteUserData SYNTAX: void AIT_WriteUserData() DESCRIPTION: Writes the power usage SEE ALSO: END DESCRIPTION **********************************************************/ void AIT_WriteUserData() { UB.Updated = SEC_TIMER; writeUserBlock(sizeof(UserBlockID), &UB, sizeof(UB)); // printf("\nSaving: %d, %lu, %lu, %lu, %lu > ", // UB.DayNum, UB.PowerCount, UB.PowerMin, UB.PowerDay, UB.PowerYesterday); } // ----------------------------------------------- /****** interrupt routines ******/ // ----------------------------------------------- int Pulse ; nodebug root interrupt void PowerMonitor_ISR() { if ((MS_TIMER - PowerLast) > 5) { Pulse = !Pulse ; ledOut(PWR_PULSE, Pulse); UB.PowerCount++; PowerLast = MS_TIMER ; } } /*** BeginHeader */ #endif /*** EndHeader */