/*** Beginheader */ #ifndef __AIT_OW_LIB #define __AIT_OW_LIB /*** Endheader */ /* START LIBRARY DESCRIPTION ********************************************* AIT_OW.LIB Copyright (c) 2003, Adaptive Internet Technologies DESCRIPTION: AIT Dallas One-Wire Bus utilities SUPPORT LIBS: AIT_GEN.LIB REVISION HISTORY: 1.1 12/04/03 Original Issue END DESCRIPTION **********************************************************/ //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--// /*** Beginheader OW_Init,OW_Reset, OW_CalculateTemp,OW_ConvertAll, OW_FilterSensors,OW_GetTemps,OW_ScaleTemps,OW_TempRates, OW_BuildWebPost */ // One-Wire Constants for AIT_OW.LIB #define DEV_NULL 0 #define DEV_PWR 0x01 #define DEV_RELAY 0x02 #define DEV_18S20 0x10 #define EINBUFSIZE 31 #define EOUTBUFSIZE 31 #define OW_TEMP_OK 1 #define OW_SCRATCH_OK 1 #define OW_VARS_OK 1 #define OW_ERROR_CONVERTNOTDONE -10 #define OW_ERROR_CONVERTINVALID -20 #define OW_SCRATCH_NOT_READ -30 #define OW_BAD_CRC -40 #define OW_SCRATCH 8 #define OW_SCRATCH_PLUS_CRC 9 #define OW_SCRATCH_PLUS_CRC_CHARS 18 #define OW_ADDRESS_BYTES 8 #define OW_ADDRESS_CHARS 16 #define OW_MAX_SIGNAL_NAME_LEN 32 #define OW_BAUD 9600 // One-Wire Typedefs for AIT_OW.LIB typedef char OW_ADDR[OW_ADDRESS_CHARS + 1]; typedef char OW_NAME[OW_MAX_SIGNAL_NAME_LEN + 1]; typedef struct { OW_ADDR Addr; float Scale; float Offset; char *Name; } SENSOR_CONST; typedef struct { OW_NAME Name; // ACS Name OW_ADDR Addr; // 1-Wire address string int Type; // Device Type BYTE Scratch[OW_SCRATCH_PLUS_CRC]; float Raw; // Value converted from Sensor: Dec C float Scale; // Scaled and calibrated value BYTE Valid ; // Indicates first true value has been scaled float Offset; // Offset for conversion float Scaled; // Scale for conversion float Filtered; // Filtered Value float Last; // Filtered value at last rate calculation float FilterTC; // Coefficient for filter float Rate; // Filtered Rate value } SENSOR ; // One-Wire Function Prototypes for AIT_OW.LIB int OW_BuildWebPost(char * URL, int MaxChars, char * User, char * Passwd, SENSOR * Devices); int OW_CalculateTemp(SENSOR * Device); cofunc void OW_ConvertAll(); void OW_FilterSensors(SENSOR * Devices); cofunc void OW_GetTemps(SENSOR * Devices, int ScaleNow); void OW_Init(); cofunc int OW_LoadScratch(SENSOR * Device); void OW_Reset(); void OW_ScaleSensor(SENSOR * pDevice); void OW_ScaleTemps(SENSOR * Devices); void OW_TempRates(SENSOR * Devices, float Interval, float Coefficient); /*** endheader */ /* START FUNCTION DESCRIPTION ******************************************** OW_CalculateTemp SYNTAX: int OW_CalculateTemp(SENSOR * Device); DESCRIPTION: Calculate the temperature from the Scratch Pad. PARAMETER1: The data structure for the desired sensor RETURN VALUE: OW_TEMP_OK if good read, <0 for error condition SEE ALSO: OW_LoadScratch END DESCRIPTION **********************************************************/ int OW_CalculateTemp(SENSOR * Device) { int BaseReading; int CountsPerC; int Counts; float Temp ; // Check for error conditions if (Device->Scratch[0] == 0xAA) return OW_ERROR_CONVERTNOTDONE ; if (Device->Scratch[7] == 0) return OW_ERROR_CONVERTINVALID; /* calculate the temperature */ BaseReading = (int)(((unsigned int)(Device->Scratch[1]) << 8) | ((unsigned int)(Device->Scratch[0]) & 0xFE) ); CountsPerC = Device->Scratch[7] ; Counts = CountsPerC - Device->Scratch[6] ; // Interpolate : = Temp - 0.25 + (CountsPerC - CountsRemaining)/CountsPerC; Temp = (float)(BaseReading >> 1) - 0.25 + ((float)Counts / (float)CountsPerC); // Validate to possible range if ((Temp > -50) && (Temp < 100)) Device->Raw = Temp ; else return OW_ERROR_CONVERTINVALID; return OW_TEMP_OK; } /* START FUNCTION DESCRIPTION ******************************************** OW_GetTemps SYNTAX: cofunc void OW_GetTemps(SENSOR * Devices, int ScaleNow); DESCRIPTION: Load and calculate all temperatures the Scratch Pad data. PARAMETER1: The array of data structures for the desired sensor PARAMETER2: =0 Do not generate the scaled value for this sensor !=0 Calculated Scaled from Raw using Scale and Offset RETURN VALUE: None SEE ALSO: OW_LoadScratch, OW_CalculateTemp END DESCRIPTION **********************************************************/ cofunc void OW_GetTemps(SENSOR * Devices, int ScaleNow) { SENSOR * pDevice; int Status; for (pDevice = Devices; pDevice->Name[0]; pDevice++) { if (pDevice->Type == DEV_18S20) { wfd Status = OW_LoadScratch(pDevice); if ( Status > 0) { // Convert To Temp (with optional scaling) if ((OW_CalculateTemp(pDevice) == OW_TEMP_OK) && (ScaleNow)) { OW_ScaleSensor(pDevice); } // printf ("%s %02X%02X = %.2f (%.2f)\n", pDevice->Name, // pDevice->Scratch[1],pDevice->Scratch[0], // pDevice->Raw, pDevice->Scaled); } tcp_tick(NULL); } } } /* START FUNCTION DESCRIPTION ******************************************** OW_ConvertAll SYNTAX: cofunc void OW_ConvertAll(); DESCRIPTION: Send One Wire command to convert all devices RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ cofunc void OW_ConvertAll() { ledOut(CONVERT_LED, 1); OW_Reset(); serEwrite("p", 1); // Byte Pull Up serEwrite("CC44", 4); // ROM Skip & Convert serEwrite("\r", 1); // End Byte Mode wfd AIT_EflushRx(4, 0); waitfor( DelayMs(1000) ); ledOut(CONVERT_LED, 0); } /* START FUNCTION DESCRIPTION ******************************************** OW_Init SYNTAX: void OW_Init() DESCRIPTION: Initialize the One Wire serial port RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ void OW_Init() { struct tm Time; // Build the time variables mktm(&Time, read_rtc()); sprintf(StartDateText, "%02d/%02d/%04d", Time.tm_mon,Time.tm_mday,Time.tm_year + 1900); sprintf(StartTimeText, "%02d:%02d:%02d", Time.tm_hour,Time.tm_min,Time.tm_sec); serEopen(OW_BAUD); serEwrFlush(); serErdFlush(); serEputc('\r'); OW_Reset(); } /* START FUNCTION DESCRIPTION ******************************************** OW_LoadScratch SYNTAX: cofunc int OW_LoadScratch(BYTE * Scratch) DESCRIPTION: Load the 1-wire serial characters into the scratch pad PARAMETER1: Pointer to scratch pad string RETURN VALUE: OW_SCRATCH_OK if good read, <0 for error condition SEE ALSO: OW_CalculateTemp END DESCRIPTION **********************************************************/ cofunc int OW_LoadScratch(SENSOR * Device) { char Buffer[32]; char * pBuffer ; int B; int Bytes; OW_Reset(); // Read values serEwrite("b", 1); // LINK High Z Byte Mode serEwrite("55", 2); // LINK Address Match serEwrite(Device->Addr, 16); // LINK Address serEwrite("BE", 2); // LINK Read Cmd wfd AIT_EflushRx(4, 0); serEwrite("FFFFFFFFFFFFFFFFFF", 18); // LINK clock output serEwrite("\r", 1); // LINK End Byte Mode // Wait for the TX buffer to be empty and the First RX char to turn up waitfor(serEwrFree() == EOUTBUFSIZE); waitfor(serEpeek() != -1 ); // Read all chars until no chars for "Wait Time" Bytes = serEread(Buffer, 31, 4); // puts("Scratch="); // puts(Buffer); if (Bytes >= OW_SCRATCH_PLUS_CRC_CHARS ) { Buffer[Bytes] = 0 ; pBuffer = Buffer; for (B = 0; B < OW_SCRATCH_PLUS_CRC; B++) { Device->Scratch[B] = (AIT_htob(*pBuffer++) << 4) + AIT_htob(*pBuffer++); } return (OW_SCRATCH_OK); } else return (OW_SCRATCH_NOT_READ); } // Functions /* START FUNCTION DESCRIPTION ******************************************** OW_Reset SYNTAX: void OW_Reset() DESCRIPTION: Reset the 1-Wire Bus and rait for completion RETURN VALUE: None SEE ALSO: OW_CalculateTemp, OW_LoadScratch END DESCRIPTION **********************************************************/ void OW_Reset() { serEputc('r'); while(serEgetc() == -1); return; } /* START FUNCTION DESCRIPTION ******************************************** OW_ScaleSensor SYNTAX: void OW_ScaleSensor(SENSOR * Devices) DESCRIPTION: Calculate the scaled values of a single sensor PARAMETER1: Pointer to the SENSOR element RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ void OW_ScaleSensor(SENSOR * pDevice) { pDevice->Scaled = (pDevice->Raw * pDevice->Scale) + pDevice->Offset ; if (pDevice->Valid == 0) { pDevice->Filtered = pDevice->Scaled; pDevice->Last = pDevice->Scaled; pDevice->Valid = 1; } return ; } /* START FUNCTION DESCRIPTION ******************************************** OW_ScaleSensors SYNTAX: void OW_ScaleSensors(SENSOR * Devices) DESCRIPTION: Calculate the scaled values of all temperatures PARAMETER1: Pointer to the SENSOR array RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ void OW_ScaleSensors(SENSOR * Devices) { SENSOR * pDevice; for (pDevice = Devices; pDevice->Name[0]; pDevice++) { OW_ScaleSensor(pDevice); } return ; } /* START FUNCTION DESCRIPTION ******************************************** OW_FilterSensors SYNTAX: void OW_FilterSensors(SENSOR * Devices) DESCRIPTION: Calculate the scaled values of all temperatures PARAMETER1: Pointer to the SENSOR array RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ void OW_FilterSensors(SENSOR * Devices) { SENSOR * pDevice; for (pDevice = Devices; pDevice->Name[0]; pDevice++) { pDevice->Filtered += (pDevice->Scaled - pDevice->Filtered) * pDevice->FilterTC; } return ; } /* START FUNCTION DESCRIPTION ******************************************** OW_TempRates SYNTAX: void OW_TempRates(SENSOR * Devices, float Interval, float Coefficient) DESCRIPTION: Calculate the rate of temp change PARAMETER1: Pointer to the SENSOR array PARAMETER2: Measurement interval (in units required for reporting) PARAMETER2: Filter Coefficient 1 = Zero Time constant 0 = Infinate Time constant RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ void OW_TempRates(SENSOR * Devices, float Interval, float Coefficient) { SENSOR * pDevice; float NewRate; for (pDevice = Devices; pDevice->Name[0]; pDevice++) { NewRate = (pDevice->Filtered - pDevice->Last) / Interval; pDevice->Rate += (NewRate - pDevice->Rate) * Coefficient; pDevice->Last = pDevice->Filtered ; } return ; } /* START FUNCTION DESCRIPTION ******************************************** OW_BuildWebPost SYNTAX: int OW_BuildWebPost(char * URL, int MaxChars, char * User, char * Passwd, SENSOR * Devices) DESCRIPTION: Calculate the scaled values of all temperatures PARAMETER1: Pointer to the SENSOR array RETURN VALUE: None SEE ALSO: END DESCRIPTION **********************************************************/ int OW_BuildWebPost(char * URL, int MaxChars, char * User, char * Passwd, SENSOR * Devices) { struct tm Time; SENSOR * pDevice; char Work[24]; // Build Post URL strcpy(URL, "GET /go/acs_url?U="); strcat(URL, User); strcat(URL, "&P="); strcat(URL, Passwd); // Build the time variables mktm(&Time, read_rtc()); sprintf(DateText, "%02d/%02d/%04d", Time.tm_mon,Time.tm_mday,Time.tm_year + 1900); sprintf(TimeText, "%02d:%02d:%02d", Time.tm_hour,Time.tm_min,Time.tm_sec); // Build Value List strcat(URL, "&V="); strcat(URL, DateText); strcat(URL, ","); strcat(URL, TimeText); strcat(URL, ","); for (pDevice = Devices; pDevice->Name[0]; pDevice++) { sprintf(Work, "%.1f,", pDevice->Scaled); strcat(URL, Work); } // Build Signal List strcat(URL, "&S=Date,Time,"); for (pDevice = Devices; pDevice->Name[0]; pDevice++) { strcat(URL, pDevice->Name); strcat(URL, ","); } strcat(URL, " HTTP/1.0\r\n\r\n "); return (1); } //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--// /*** Beginheader OW_AddServerVars */ // One-Wire Function Prototypes for AIT_OW.LIB int OW_AddServerVars(SENSOR * Device); /*** endheader */ /* START FUNCTION DESCRIPTION ******************************************** OW_AddServerVars SYNTAX: int OW_AddServerVars(SENSOR * Devices); DESCRIPTION: Add all OW sensors to Web Server List PARAMETER1: The data structure for the sensor List RETURN VALUE: OW_VARS_OK if good read, <0 for error condition SEE ALSO: END DESCRIPTION **********************************************************/ int OW_AddServerVars(SENSOR * Devices) { auto SENSOR * pDevice; auto int var; var = sspec_addvariable("StartDate", StartDateText, PTR16, "%s" , SERVER_HTTP); var = sspec_addvariable("StartTime", StartTimeText, PTR16, "%s" , SERVER_HTTP); var = sspec_addvariable("Date", DateText, PTR16, "%s" , SERVER_HTTP); var = sspec_addvariable("Time", TimeText, PTR16, "%s" , SERVER_HTTP); for (pDevice = Devices; pDevice->Name[0]; pDevice++) { // printf("Adding %s\n", pDevice->Name); var = sspec_addvariable(pDevice->Name, &(pDevice->Filtered), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); } return (OW_VARS_OK); } /*** BeginHeader */ #endif /*** EndHeader */