----------------------------------------------------------------------------- #include #include #include #include /* Personal includes and defines */ #include "adc.h" #define USAGE "sampling_rate(in seconds)(0-300) num_samples(1-20) channel(0-7)" /* End Personal includes */ /* Prototypes */ int adc(int,int); /* End Prototypes */ int main(int argc,char *argv[]) { /* Sampling rate (in seconds) passed to sleep system call. and Number of samples */ int sampling_rate,num_samples; /* Channel number of adc read from */ int channel; /* Number of points in data file */ int num_point=1; /* The integer value returned by adc */ int data_point=0; /* The temperature obtained by rescaling the integer value returned by adc */ float temp; /* An index variable */ int i; /* File pointers for input , output and log files */ FILE * infile; FILE * outfile; FILE * logfile; /* POSIX type time_t for time system call */ time_t init_time,current_time; /* A string for ctime system call to convert time_t type to a friendlier format */ char *timestr; /* A string to read into and a char * to check the status of fgets */ char instring[80]; char *fget_stat; /* Parse and assign command line arguments */ if (argc !=4 ) { fprintf(stderr,"%s %s\n",argv[0],USAGE);exit(-2); } sampling_rate=atoi(argv[1]); num_samples=atoi(argv[2]); channel=atoi(argv[3]); /* Debugging purposes only */ #ifdef DEB fprintf(stderr,"Channel Number:%d\t Sampling Rate:%d Seconds \t Number of Samples : %d \n",channel,sampling_rate,num_samples); #endif /* Get Starting time (Returns time as seconds elapsed since 00:00:00 January 1,1970 */ init_time=time(NULL); /* ctime converts time to a string of form Sun Jun 28 00:00:00 1996 */ timestr=ctime((const time_t *)&init_time); /* Write starting time into logfile */ logfile=fopen("adcerr.log","w"); fprintf(logfile,"Start Time: %s",timestr); fflush(logfile); /* Open the output file (temperature.dat) */ outfile=fopen("temperature.dat","w"); /* Start The infinite loop */ for(;;) { /* Open adc device */ if(adc(channel,DEVICE_OPEN) != -4) { /* Read a data value from adc */ data_point=adc(channel,DEVICE_READ); /* Set time of data read */ current_time=time(NULL); /* Convert to an easier format */ timestr=ctime((const time_t *)¤t_time); /* Rescale the data as per sensor requirements */ temp=(float)(data_point-2730)/10.0; /* Debugging purposes only */ #ifdef DEB fprintf(stderr,"Temperature:%3.1f \t Time:%s\n ",temp,timestr); #endif /* Close the adc device */ adc(channel,DEVICE_CLOSE); } else { /* If device could not be opened log error and exit */ fprintf(logfile,"Could not open device now \n"); fclose(logfile); fclose(outfile); exit(-1); } /* Initially at startup write num_samples data points (Sampled at a sampling_rate(in seconds) interval ) to the output file . This is read by another program which averages , finds minimum and maximum, and outputs a HTML file containing the relevant data */ if (num_point<=num_samples) { /* Just a precaution in case outfile is open to flush it */ fclose(outfile); /* Open output file in append mode */ outfile=fopen("temperature.dat","a"); /* Output the temperature as a float and time of reading as a string */ fprintf(outfile,"%3.1f %s",temp,timestr); fclose(outfile); /* Increment number of points written to file */ num_point++; } else { /* If the number of points in file is greater than num_samples */ if (num_point>num_samples) { /* Open the output file (temperature.dat) as read only and a temporary file (temperature.datt) . Copy the last fourteen lines of temperature.dat to the temporary file */ infile=fopen("temperature.dat","r"); outfile=fopen("temperature.datt","w"); for(i=0;i<=14;i++) { fgets(instring,32,infile); if (i>0) fprintf(outfile,"%s",instring); } fclose(infile); fclose(outfile); /* Delete original file (temperature.dat) and copy the temporary file to temperature.dat */ infile=fopen("temperature.datt","r"); outfile=fopen("temperature.dat","w"); while ((fget_stat=fgets(instring,32,infile))!=NULL) { fprintf(outfile,"%s",instring); } fclose(infile); /* Delete tempfile */ unlink("temperature.datt"); /* Write the current data point and time stamp to temperature.dat . This ensures that temperature.dat always contains the most recent fifteen temperature values */ fprintf(outfile,"%3.1f %s",temp,timestr); /* Flush and close output stream */ fflush(outfile); fclose(outfile); } /* End if (num_points>num_samples) */ } /* End Else */ /* Sleep for sixty seconds ( Sampling at one minute intervals) */ sleep(sampling_rate); } /* Infinite Loop */ } /* Close Main */ /* Listing 1*/ --------------------------------------------------------------------------- #!/usr/bin/perl # Number of Sample points to make running average of is supplied as a command line argumnt $num_samples=$ARGV[0]; # Set minimum and maximum to arbitrarily high and low values respectively $min_temp = 100.0; $max_temp = -100.0; @minimum=split(/ +/,localtime()); $min_temp_time=$minimum[3]; $min_temp_date=$minimum[1]." ".$minimum[2]; @maximum=split(/ +/,localtime()); $max_temp_time=$maximum[3]; $max_temp_date=$maximum[1]." ".$maximum[2]; # Infinite Loop to run as a daemon for(;;) { # Open temperature.dat for input (contains $num_samples lines of the format # temperature Sun Jul 28 00:00:00 1996 open(INFILE,"; close(INFILE); # $num_lines contains number of lines in the file $num_lines=@inputs; # Check to see if the number of lines is greater than number of sample points to average over if ($num_lines >= $num_samples) { # If true then average over the temperature field and also find the minimum and maximum values for temperature. # Initialize counter,sum and average $counter = 1; $sum = 0.0; $average = 0.0; while($counter <= $num_samples) { # Split each element of input array on whitespace @data = split(/ +/,$inputs[$num_lines-$counter]); # Extract the first field as temperature $temperature = $data[0]; $data_time = $data[4]; $data_date= $data[2]." ".$data[3]; if ($data_date ne $min_temp_date) { $min_temp_date=$data_date; $min_temp=$temperature; $min_temp_time=$data[4]; $max_temp_date=$data_date; $max_temp=$temperature; $max_temp_time=$data[4]; } # Find the minimum and maximum temperature of num_sample points if ($temperature < $min_temp) { $min_temp = $temperature; $min_temp_time=$data_time; $min_temp_date=$data_date; } if ($temperature > $max_temp) { $max_temp = $temperature; $max_temp_time=$data_time; $max_temp_date=$data_date; } $sum += $temperature; $counter++; } # Compute average $average = $sum/($counter-1); $current_time=localtime; # Open output file in HTML format (Weather.html) open(OUTFILE,">Weather.html") || die "can't write output HTML file\n"; print OUTFILE "\n"; print OUTFILE " The Weather at IUCAA\n"; print OUTFILE "\n"; print OUTFILE "\n"; print OUTFILE "
\n
\n"; print OUTFILE "

The Weather at IUCAA

"; print OUTFILE "
\n"; print OUTFILE "Time of record (IST) is $current_time\n
\n"; printf OUTFILE ("Average Temperature for the past $num_samples minutes:\t %3.1f degrees Celsius\n",$average); printf OUTFILE ("
\nMinimum Temperature:%3.1f degrees Celsius at $min_temp_time on $min_temp_date\n
\nMaximum Temperature:%3.1f degrees Celsius at $max_temp_time on $max_temp_date
\n",$min_temp,$max_temp); print OUTFILE "
\n"; print OUTFILE "
\n"; print OUTFILE "
\n"; print OUTFILE "Back to Instrumentation\n"; print OUTFILE "\n"; close(OUTFILE); # Move Weather.html ~ilab/public_html system("mv Weather.html .."); } else { sleep(15*60); } # End of If $numlines < $numsamples condition sleep(15*60); } # End infinite loop #Listing 2 --------------------------------------------------------------------------- #!/bin/sh echo "Cleaning evrything\n" make clean echo "Starting Temperature reader \n" ./adc_read 60 15 7 & sleep 15m echo "Starting HTML constructor \n" ./read_data_average.perl 15 & /*The adc.h file and adc() function*/ /*code for adc()*/ adc(channel_number,init) { char * filename; int data_point,count=2; static int fd; unsigned char buf[3]; filename=FILES[channel_number]; switch(init) { case DEVICE_OPEN: filename=FILES[channel_number]; printf("File is %s\n",filename); fd=open(filename,O_RDONLY); if (fd<0) { printf("Could not open device\n"); return -4; } else { printf("ADC Channel %d opened\n",channel_number); return 1; } break; case DEVICE_CLOSE: printf("Closing Device\n"); close(fd); return 1; break; case DEVICE_READ: read(fd,buf,count); data_point=((int)buf[1]*256+(int)buf[0]); return data_point; break; } } /***********************/ /*device driver code read function*/ static int adc_read(struct inode * inode,struct file * file,char * buf,int count) { unsigned char data[16]; int adc_val; unsigned int temp_val; int temp1,temp2,temp3; unsigned int minor=MINOR(inode->i_rdev); if (count < 1) return -EINVAL; switch (minor) { case CHANNEL_0: temp1=0x8f; break; case CHANNEL_1: temp1=0xcf; break; case CHANNEL_2: temp1=0x9f; break; case CHANNEL_3: temp1=0xdf; break; case CHANNEL_4: temp1=0xaf; break; case CHANNEL_5: temp1=0xef; break; case CHANNEL_6: temp1=0xbf; break; case CHANNEL_7: temp1=0xff; break; default: temp1=0x8f; break; } cli(); for(temp2=0; temp2<8; temp2++) { temp3= (temp1 << temp2) & 0x80; outb(temp3,data_port); temp3=temp3 | 1; outb(temp3,data_port); outb(temp3,data_port); /* this is to make the clk 50% duty cycle*/ /* Duty cycle as measured with a 66 MHz 486 is 48% */ temp3=temp3 & 0xfe; outb(temp3,data_port); } temp3=temp3 & 0x7f; outb(temp3,data_port); for(temp2=0; temp2<16; temp2++) { temp3= 01; outb(temp3,data_port); data[temp2]=inb(data_port+1)&0x80; temp3=temp3 & 0xfe; outb(temp3,data_port); outb(temp3,data_port); } sti(); adc_val=0; for(temp2=0; temp2<16; temp2++) { temp_val=( (unsigned int) data[temp2] & 0x00ff) << 8; adc_val= adc_val | ( (temp_val ^ 0x8000) >> temp2); } adc_val=adc_val>> 3; put_fs_word(adc_val,buf); /* printk("ADC: Input value from port: %d\n",adc_val); */ return 1; } /**********************/ /*adc.h*/ #define ADC_MAJOR 31 #define ADC_MINOR 8 #define CHANNEL_0 0 #define CHANNEL_1 1 #define CHANNEL_2 2 #define CHANNEL_3 3 #define CHANNEL_4 4 #define CHANNEL_5 5 #define CHANNEL_6 6 #define CHANNEL_7 7 #define PARALLEL_1 0x378 #define PARALLEL_2 0x3bc #define PARALLEL_3 0x278 #define ADC_BUSY 1 #define ADC_FREE 0 #define ADC_AVAILABLE 1 #define ADC_NOT_AVAILABLE 0