#!/usr/bin/perl -w use strict; use FileHandle; # Program to convert a binary (xmodem) module dump to a hex file that # can be edited if necessary and then processed by processA2Mod. # 2/1/2006 - A few lines were added to handle module dumps whose headers are # garbage (so that the header[12] and [13] values are bad). User can now # enter the values for header[12] and [13] (which correspond to record count # and buffer size). main:{ my $datfile = $ARGV[0]; while ( defined($datfile) and ! -f $datfile ) { print "Enter path and filename for file to be converted: "; $datfile = <>; chomp $datfile; } (my $outfile = $datfile) =~ s/(\.\w*)/$1hex/; #hopefully will append hex to the name print "outfilename is: $outfile \n"; my $infh = new FileHandle("$datfile","r") or die "Can't open input $datfile: $!"; binmode $infh; my $outfh = new FileHandle("$outfile","w") or die "Can't open output $outfile: $!"; my $headerstuff; my $stuff; my $headstuff; my $modtype; my $nsensors = 0; my @headdata; my @data; ###### # read and decode xmodem header ###### seek $infh, 0 ,0; read $infh, $headerstuff,1024; my @header = split("&",(uc join "&",unpack("H4 H4 H4 H4 H2 H2 H2 H2 H2 H4 C C n n N n n n n n A10 A10 A10 H2 H2 H2 n", $headerstuff))); # Note that the software revision # is read in as an integer, - divide by 100 to get, for example, .07 instead of 7 printf "\nHeader array length is %d (Should be 27)\n", $#header+1; for (0 .. $#header) { printf "#%2d %s\n", $_, $header[$_]; } print "\n"; # Figuring out the type of module this is: # $header[16] = sensor type # bits 7 6 5 4 3 2 1 0 # | # SST or SSC # bits 7 6 5 4 3 2 1 0 # | # T,P,C,V and all combinations # bits 7 6 5 4 3 2 1 0 # | # no sensor # # $sensor[17] = sensor configuration # bits 7 6 5 4 3 2 1 0 # | # vishay # bits 7 6 5 4 3 2 1 0 # | # T # bits 7 6 5 4 3 2 1 0 # | # P for type 1 # bits 7 6 5 4 3 2 1 0 # | # C for type 2 # bits 7 6 5 4 3 2 1 0 # | # C for type 1 # bits 7 6 5 4 3 2 1 0 # | # V # bit 0 (vishay) is always set. # Ex: type 1 # 3 = 1 + 2 + 0 + 0 + 0 T # 7 = 1 + 2 + 4 + 0 + 0 TP # 11 = 1 + 2 + 0 + 8 + 0 TC # 19 = 1 + 2 + 0 + 0 + 16 TV # 27 = 1 + 2 + 0 + 8 + 16 TCV # if ( $header[16] == 2 ) { # type 2: SST or SSC $modtype = 'SS '; if ($header[17] & 2) { ++$nsensors; substr($modtype,2,1) = 'T'; } if ($header[17] & 4) { ++$nsensors; substr($modtype,2,1) = 'C'; } if ( $nsensors == 1 ) { if ( $modtype !~ /SST/ ) { printf "\n ** Wrong module type indicated (%s) for number of sensors detected (%d)\n", $modtype, $nsensors; } if ( $header[13] != 303 ) { printf "\n ** Wrong record size reported for one sensor: %d (should be 303)\n", $header[13]; } } if ( $nsensors == 2 ) { if ( $modtype !~ /SSC/ ) { printf "\n ** Wrong module type indicated (%s) for number of sensors detected (%d)\n", $modtype, $nsensors; } if ( $header[13] != 591 ) { printf "\n ** Wrong record size reported for two sensors: %d (should be 591)\n", $header[13]; } } } elsif ( $header[16] == 1 ) { # type 1 $modtype = ''; if ($header[17] & 2) { # T sensor ++$nsensors; $modtype .= 'T'; } if ($header[17] & 4) { # P sensor ++$nsensors; $modtype .= 'P'; } if ($header[17] & 8) { # C sensor ++$nsensors; $modtype .= 'C'; } if ($header[17] & 16) { # V sensor ++$nsensors; $modtype .= 'V'; } if ( $nsensors == 1 ) { if ( $modtype ne 'T' ) { printf "\n ** Wrong module type indicated (%s) for number of sensors detected (%d)\n", $modtype, $nsensors; } if ( $header[13] != 303 ) { printf "\n ** Wrong record size reported for one sensor: %d (should be 303)\n", $header[13]; } } if ( $nsensors == 2 ) { if ( $modtype !~ /T[PCV]/ ) { printf "\n ** Wrong module type indicated (%s) for number of sensors detected (%d)\n", $modtype, $nsensors; } if ( $header[13] != 591 ) { printf "\n ** Wrong record size reported for two sensors: %d (should be 591)\n", $header[13]; } } if ( $nsensors == 3 ) { if ( $modtype !~ /T[PCV]{2}/ ) { printf "\n ** Wrong module type indicated (%s) for number of sensors detected (%d)\n", $modtype, $nsensors; } if ( $header[13] != 879 ) { printf "\n ** Wrong record size reported for three sensors: %d (should be 879)\n", $header[13]; } } } else { $modtype = '??' } my $modvers = $header[10] + ($header[11]/100.0); printf "\nModule type from XModem header is %s\n", $modtype; printf "Record Count from XModem header is %d\n", $header[12]; printf "Buffer Size from XModem header is %d\n", $header[13]; printf "\nEnter Correct Module Type [%s]: ", $modtype; my $newty = ; $newty =~ s/[^TPCVS]//g; $modtype = $newty if length($newty); printf "Enter Correct Record Count [%d]: ", $header[12]; my $newrc = ; $newrc =~ s/\D//g; $header[12] = $newrc if length($newrc); printf "Enter Buffer Size Count [%d]: ", $header[13]; my $newbs = ; $newbs =~ s/\D//g; $header[13] = $newbs if length($newbs); my $mod_byte_size = $header[12] * $header[13]; printf "\nUsing Record Count = %d\n", $header[12]; printf "Using Buffer Size = %d\n\n", $header[13]; printf "Stored data size = (Buffer Size * Record Count) = %d\n", $mod_byte_size; printf "The Module Type is %s\n", $modtype; printf "Software version is %.2f\n", $modvers; # Outfile header should look similar to the following: # #ATLAS2 SENSOR #VERSION NUMBER 05.04 03/98 #DATE/TIME IS 11/23/2000 02:35:17 #NUMBER RECORDS IS 0123 #DATA LAST READ ON 11/23/2000 02:33:48 #Memory detected is 512K #MODULE TYPE IS T #SERIAL NUMBER IS 12332 #ADDRESS IS 0008 #SAMPLING INTERVAL IS 00:10:00 #AVERAGE INTERVAL IS 0018 #BATTERY VOLTAGE IS 8.59 printf $outfh "ATLAS2 SENSOR\n"; printf $outfh "VERSION NUMBER %.2f\n", $modvers; printf $outfh "DATE/TIME IS %s/%s/%s %s:%s:%s\n", $header[4], $header[5], $header[3], $header[6], $header[7] ,$header[8]; printf $outfh "NUMBER RECORDS IS %04d\n", $header[12]; print $outfh "DATA LAST READ ON ????\n"; printf $outfh "Memory detected is %dK\n\n", $header[15]; printf $outfh "MODULE TYPE IS %s\n", $modtype; printf $outfh "SERIAL NUMBER IS %s\n", $header[18]; printf $outfh "ADDRESS IS %03d\n\n", $header[19]; if ($modvers =~m/5.07/) { # Version 5.07 bug, - no seconds, & the sampling interval is in (hh mm) format, preceded by 2 filler 00's printf $outfh "SAMPLING INTERVAL IS %s:%s:00\n", $header[24], $header[25]; } else { printf $outfh "SAMPLING INTERVAL IS %s:%s:%s\n", $header[23], $header[24], $header[25]; } printf $outfh "AVERAGE INTERVAL IS %04d\n", $header[26]; printf $outfh "BATTERY VOLTAGE IS %9.2f\n", (hex($header[2])/256) * 10.0; print $outfh "\n\n"; my $pos = 1024; my $bytesread; my $i = 0; my $j = 0; my $k = 0; ###### # read data records ###### print "\nConverting binary data:\n"; while ( tell $infh < (1024+$mod_byte_size) ) { my $bytesread = read $infh, $headstuff, 15; $bytesread += read $infh, $stuff, ($header[13] - 15); #for example, 303-15 @headdata = split(" ",(uc join " ",unpack("H4 H4 H4 H4 H2 H2 H2 H2 H2 H4", $headstuff))); # print "The # of variables in the header is: ",$#headdata+1,"\n"; printf $outfh "%s ", $headdata[0]; printf $outfh "%s/%s/%s ", $headdata[3], $headdata[4], $headdata[5]; printf $outfh "%s:%s:%s ", $headdata[6], $headdata[7], $headdata[8]; printf $outfh "0%s 0%s 0%s\n", $headdata[9], $headdata[2], $headdata[1]; #vishay, battery & checksum print "."; if ( ++$k > 49 ) { print "\n"; $k = 0; } # print "Position is: ",(tell $infh),"\n"; @data = split(" ",(uc join " ", unpack(("H4") x ($header[13] - 15), $stuff))); for (0..$#data) { printf $outfh "%4.4s ", $data[$_]; print $outfh "\n" if ( ($_ % 12) == 11 ); $i++; } print $outfh "\n"; $j++; } print "\n"; print $outfh $header[12]," records read\n"; printf "\nNumber of data blocks (records) read: %d\n", $j; printf "Number of data samples read: %d\n", $i; printf "Should be %d (144 * Nsensors * Nrecords)\n", (144 * $nsensors * $header[12]); $infh->close; $outfh->close; exit; }