/* ----------------------------------------------------------------------- DigiTemp DOS interface v1.2 Copyright 1997-99 by Nexus Computing digitemp -i Initalize digitemp.cfg file digitemp -s0 Set serial port (required) digitemp -f5 Set Fail timeout to 5 seconds digitemp -r500 Set Read timeout to 500mS digitemp -la:\temp.log Send output to logfile digitemp -v Verbose mode digitemp -t0 Read Temperature of sensor # digitemp -a Read all Temperatures digitemp -d5 Delay between samples (in sec.) digitemp -n50 Number of times to repeat digitemp -o1 Output format for logfile See description below Logfile formats: 1 = (default) - 1 line per sensor, time, øC, øF 1 line for each sample, elapsed time, sensor #1, #2, ... tab seperated 2 = Reading in øC 3 = Reading in øF ======================================================================= 01/16/99 Fixing an error in do_temp that caused erratic behavior when reading temperatures below 0øC! 08/28/98 Additions TODO 1. Pause time between samples 2. Number of times to sample 3. Logfile format 4. Check for DS1820 family code, possibly 1620 too. Done! 03/21/97 Porting Linux code over to DOS 03/13/97 Error in CRC calculation. Wrong # of bytes. Error with 3 sensors. Sometimes doesn't store correct ROM data to .digitemprc -- need to malloc more memory dummy! 03/08/97 Adding user defined timeouts for failure and for the read delay. 01/24/97 Changed over to correct baud rate and 6 bits @ 115.2k ROM search function is now working. All low level code is functioning except for Alarm Search. Starting to move into a seperate object file with API for users to write their own code with. 01/22/97 Working on ROM search routine, double cannot handle a full 64 bits for some reason, converting to 64 byte array for each bit. 01/19/97 Rewriting for new interface. This programs handles all the low level communications with the temperature sensor using the 115200k serial adapter. 01/02/96 Rewriting this code to be more user friendly -----------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "onewire.h" #include "ds1820.h" extern char *optarg; extern int optind, opterr, optopt; char log_file[1024]; unsigned char serial_port; int fail_time, /* Failure timeout */ read_time, /* Pause during read */ log_format = 1; /* Format for logfile */ time_t elapsed_time = 0; /* Elapsed from start */ /* ----------------------------------------------------------------------- * Print out the program usage * ----------------------------------------------------------------------- */ void usage() { printf("\nUsage: digitemp -s [-i -d -l -r -v -t -p -a]\n"); printf(" -i Initalize .digitemprc file\n"); printf(" -s1 Set serial port [1-4]\n"); printf(" -la:\\temp.log Send output to logfile\n"); printf(" -f5 Fail delay in S\n"); printf(" -r500 Read delay in mS\n"); printf(" -v Verbose output\n"); printf(" -t0 Read Sensor #\n"); printf(" -a Read all Sensors\n"); printf(" -d5 Delay between samples (in sec.)\n"); printf(" -n50 Number of times to repeat\n"); printf(" -o2 Output format for logfile\n"); printf("\nLogfile formats: 1 = One line per sensor, time, øC, øF (default)\n"); printf(" 2 = One line per sample, elapsed time, temperature in øC\n"); printf(" 3 = Same as #2, except temperature is in øF\n"); printf(" #2 and #3 have the data seperated by tabs, suitable for import\n"); printf(" into a spreadsheet or other graphing software.\n"); } /* ----------------------------------------------------------------------- Return the high-precision temperature value Calculated using formula from DS1820 datasheet Temperature = scratch[0] Sign = scratch[1] TH = scratch[2] TL = scratch[3] Count Remain = scratch[6] Count Per C = scratch[7] CRC = scratch[8] count_per_C - count_remain (temp - 0.25) * -------------------------- count_per_C If Sign is not 0x00 then it is a negative (Centigrade) number, and the temperature must be subtracted from 0x100 and multiplied by -1 ----------------------------------------------------------------------- */ float do_temp( unsigned char *scratch ) { float temp, hi_precision; if( scratch[1] == 0 ) { temp = (int) scratch[0] >> 1; } else { temp = -1 * (int) (0x100-scratch[0]) >> 1; } temp -= 0.25; hi_precision = (int) scratch[7] - (int) scratch[6]; hi_precision = hi_precision / (int) scratch[7]; temp = temp + hi_precision; return temp; } /* ----------------------------------------------------------------------- Convert degrees C to degrees F ----------------------------------------------------------------------- */ float c2f( float temp ) { return 32 + ((temp*9)/5); } /* ----------------------------------------------------------------------- Log one line of text to the logfile with the current date and time ----------------------------------------------------------------------- */ int log_line( char *buf ) { unsigned char temp[1024]; time_t mytime; FILE *fd; if( (fd = fopen( log_file, "a" ) ) == NULL ) { printf("Error opening logfile: %s\n", log_file ); return -1; } switch( log_format ) { case 2: case 3: fprintf( fd, "%s", buf ); break; default: mytime = time(NULL); strftime( temp, 1024, "%b %d %H:%M:%S ", localtime( &mytime ) ); fprintf( fd, "%s%s", temp, buf ); break; } fclose( fd ); return 0; } /* ----------------------------------------------------------------------- Read the temperature from one sensor ----------------------------------------------------------------------- */ int read_temp( int fd, struct _roms *rom_list, int sensor, int opts ) { char temp[1024]; unsigned char scratch[9]; float temp_c; MatchROM( fd, fail_time, rom_list, sensor ); ReadTemperature( fd, fail_time, read_time ); MatchROM( fd, fail_time, rom_list, sensor ); if( ReadScratchpad( fd, fail_time, scratch ) < 0 ) { printf("Error reading Scratchpad\n"); return -1; } /* Convert data to temperature */ temp_c = do_temp( scratch ); /* Write the data to the logfile or console */ switch( log_format ) { case 2: sprintf( temp, "\t%3.2f", temp_c ); break; case 3: sprintf( temp, "\t%3.2f", c2f(temp_c) ); break; default: sprintf( temp, "Sensor %d C: %3.2f F: %3.2f\n", sensor, temp_c, c2f(temp_c) ); break; } /* If file logging is enabled, log it with a timestamp */ if( log_file[0] != 0 ) { log_line( temp ); } else { printf("%s", temp ); } /* If verbose mode is enabled, show the DS1820's internal registers */ if( opts & 0x0004 ) { if( log_file[0] != 0 ) { sprintf( temp, " Temperature : 0x%02X\n", scratch[0] ); sprintf( temp, " Sign : 0x%02X\n", scratch[1] ); sprintf( temp, " TH : 0x%02X\n", scratch[2] ); sprintf( temp, " TL : 0x%02X\n", scratch[3] ); sprintf( temp, " Remain : 0x%02X\n", scratch[6] ); sprintf( temp, " Count Per C : 0x%02X\n", scratch[7] ); sprintf( temp, " CRC : 0x%02X\n", scratch[8] ); } else { printf(" Temperature : 0x%02X\n", scratch[0] ); printf(" Sign : 0x%02X\n", scratch[1] ); printf(" TH : 0x%02X\n", scratch[2] ); printf(" TL : 0x%02X\n", scratch[3] ); printf(" Remain : 0x%02X\n", scratch[6] ); printf(" Count Per C : 0x%02X\n", scratch[7] ); printf(" CRC : 0x%02X\n", scratch[8] ); } } return 0; } /* ----------------------------------------------------------------------- Read the temperaturess for all the connected sensors Step through all the sensors in the list of serial numbers ----------------------------------------------------------------------- */ int read_all( int fd, struct _roms *rom_list, int opts ) { int x; for( x = 0; x < rom_list->max; x++ ) read_temp( fd, rom_list, x, opts ); return 0; } /* ----------------------------------------------------------------------- Read a .digitemprc file from the current directory The rc file contains: TTY LOG FAIL_TIME