/* * Data Logging Format Converter for QM1538 Multimeter, * Author: telford@bespoke.homelinux.net * Copyright: Telford Tendys 2007 * Version: 2007-01-18 * * The author releases this work into the public domain. * This comes with NO WARRANTY, it is the responsibility of * the user to review this code and asses fitness for purpose. */ #include #include #include #include #include #include #include #include struct seg7_S { char S1; char S2; char S3; char S4; char S5; char S6; char S7; }; struct reading_S { /* * Reading digits */ char negative; char dig[4]; char dp1; char dp2; char dp3; /* * Reading scale-factors */ char mega; char kilo; char milli; char micro; char nano; char percent; /* * Reading units */ char ac; char amp; char dc; char farad; char hertz; char volt; char ohm; /* * Other flags */ char autorange; char battery; char beeper; char delta; char diode; /* Is this a unit?!? */ char hold; char rs232; }; int seg2digit( struct seg7_S *S ) { int x = 0; if( S->S1 ) x += 0x01; if( S->S2 ) x += 0x02; if( S->S3 ) x += 0x04; if( S->S4 ) x += 0x08; if( S->S5 ) x += 0x10; if( S->S6 ) x += 0x20; if( S->S7 ) x += 0x40; switch( x ) { case 0x3F: return( '0' ); case 0x06: return( '1' ); case 0x5B: return( '2' ); case 0x4F: return( '3' ); case 0x66: return( '4' ); case 0x6D: return( '5' ); case 0x7D: return( '6' ); case 0x07: return( '7' ); case 0x7F: return( '8' ); case 0x6F: return( '9' ); default: fprintf( stderr, "illegal digit %02X\n", x ); fprintf( stderr, " %c%c%c\n", S->S1 ? '#' : ' ', S->S1 ? '#' : ' ', S->S1 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S6 ? '#' : ' ', S->S2 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S6 ? '#' : ' ', S->S2 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S6 ? '#' : ' ', S->S2 ? '#' : ' ' ); fprintf( stderr, " %c%c%c\n", S->S7 ? '#' : ' ', S->S7 ? '#' : ' ', S->S7 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S5 ? '#' : ' ', S->S3 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S5 ? '#' : ' ', S->S3 ? '#' : ' ' ); fprintf( stderr, " %c %c\n", S->S5 ? '#' : ' ', S->S3 ? '#' : ' ' ); fprintf( stderr, " %c%c%c\n", S->S4 ? '#' : ' ', S->S4 ? '#' : ' ', S->S4 ? '#' : ' ' ); return( 'X' ); } } char *serial_filename = "/dev/ttyS0"; int ser_dev; int real_numbers = 0; int main( int argc, char *argv[] ) { struct termios TIO; struct reading_S reading; struct seg7_S seg7; for(;;) { int i = getopt( argc, argv, "n" ); switch( i ) { case 'n': real_numbers = 1; break; case -1: goto dunops; } } dunops: ser_dev = open( serial_filename, O_RDONLY ); if( ser_dev < 0 ) { perror( "open serial device" ); exit( -1 ); } if( 0 > tcgetattr( ser_dev, &TIO )) { perror( "get serial attributes" ); exit( -1 ); } cfmakeraw( &TIO ); cfsetispeed( &TIO, B2400 ); cfsetospeed( &TIO, B2400 ); if( 0 > tcsetattr( ser_dev, TCSAFLUSH, &TIO )) { perror( "set serial attributes" ); exit( -1 ); } for(;;) { char buf[ 4 ]; int i; if( 1 != read( ser_dev, buf, 1 )) { perror( "read" ); exit( -1 ); } i = buf[ 0 ] & 0x0F; switch(( buf[ 0 ] & 0x00F0 ) >> 4 ) { case 1: bzero( &reading, sizeof( reading )); reading.rs232 = ( i & 0x01 ); reading.autorange = ( i & 0x02 ); reading.dc = ( i & 0x04 ); reading.ac = ( i & 0x08 ); break; case 2: bzero( &seg7, sizeof( seg7 )); seg7.S1 = ( i & 0x01 ); seg7.S6 = ( i & 0x02 ); seg7.S5 = ( i & 0x04 ); reading.negative = ( i & 0x08 ); break; case 3: seg7.S2 = ( i & 0x01 ); seg7.S7 = ( i & 0x02 ); seg7.S3 = ( i & 0x04 ); seg7.S4 = ( i & 0x08 ); reading.dig[ 0 ] = seg2digit( &seg7 ); break; case 4: bzero( &seg7, sizeof( seg7 )); seg7.S1 = ( i & 0x01 ); seg7.S6 = ( i & 0x02 ); seg7.S5 = ( i & 0x04 ); reading.dp1 = ( i & 0x08 ); break; case 5: seg7.S2 = ( i & 0x01 ); seg7.S7 = ( i & 0x02 ); seg7.S3 = ( i & 0x04 ); seg7.S4 = ( i & 0x08 ); reading.dig[ 1 ] = seg2digit( &seg7 ); break; case 6: bzero( &seg7, sizeof( seg7 )); seg7.S1 = ( i & 0x01 ); seg7.S6 = ( i & 0x02 ); seg7.S5 = ( i & 0x04 ); reading.dp2 = ( i & 0x08 ); break; case 7: seg7.S2 = ( i & 0x01 ); seg7.S7 = ( i & 0x02 ); seg7.S3 = ( i & 0x04 ); seg7.S4 = ( i & 0x08 ); reading.dig[ 2 ] = seg2digit( &seg7 ); break; case 8: bzero( &seg7, sizeof( seg7 )); seg7.S1 = ( i & 0x01 ); seg7.S6 = ( i & 0x02 ); seg7.S5 = ( i & 0x04 ); reading.dp3 = ( i & 0x08 ); break; case 9: seg7.S2 = ( i & 0x01 ); seg7.S7 = ( i & 0x02 ); seg7.S3 = ( i & 0x04 ); seg7.S4 = ( i & 0x08 ); reading.dig[ 3 ] = seg2digit( &seg7 ); break; case 10: reading.diode = ( i & 0x01 ); reading.kilo = ( i & 0x02 ); reading.nano = ( i & 0x04 ); reading.micro = ( i & 0x08 ); break; case 11: reading.beeper = ( i & 0x01 ); reading.mega = ( i & 0x02 ); reading.percent = ( i & 0x04 ); reading.milli = ( i & 0x08 ); break; case 12: reading.hold = ( i & 0x01 ); reading.delta = ( i & 0x02 ); reading.ohm = ( i & 0x04 ); reading.farad = ( i & 0x08 ); break; case 13: reading.battery = ( i & 0x01 ); reading.hertz = ( i & 0x02 ); reading.volt = ( i & 0x04 ); reading.amp = ( i & 0x08 ); break; case 14: if( real_numbers ) { double d; d = reading.dig[ 0 ] - '0'; d *= 10; d += reading.dig[ 1 ] - '0'; d *= 10; d += reading.dig[ 2 ] - '0'; d *= 10; d += reading.dig[ 3 ] - '0'; if( reading.dp1 ) d *= 0.001; else if( reading.dp2 ) d *= 0.01; else if( reading.dp3 ) d *= 0.1; if( reading.mega ) d *= 1000000; else if( reading.kilo ) d *= 1000; else if( reading.milli ) d *= 0.001; else if( reading.micro ) d *= 0.000001; else if( reading.nano ) d *= 0.000000001; if( reading.negative ) d = -d; printf( "%g", d ); } else { /* I give up wtf are these bits for? */ if( reading.negative ) printf( "-" ); printf( "%c", reading.dig[ 0 ]); if( reading.dp1 ) printf( "." ); printf( "%c", reading.dig[ 1 ]); if( reading.dp2 ) printf( "." ); printf( "%c", reading.dig[ 2 ]); if( reading.dp3 ) printf( "." ); printf( "%c", reading.dig[ 3 ]); if( reading.mega ) printf( "M" ); if( reading.kilo ) printf( "k" ); if( reading.milli ) printf( "m" ); if( reading.micro ) printf( "u" ); if( reading.nano ) printf( "n" ); } if( reading.percent ) printf( "%" ); if( reading.ac ) printf( " AC" ); if( reading.dc ) printf( " DC" ); if( reading.amp ) printf( " Amp" ); if( reading.farad ) printf( " Farad" ); if( reading.hertz ) printf( " Hertz" ); if( reading.volt ) printf( " Volt" ); /* * Dunno how many of the other flags are useful * battery seems the most important to me */ printf( " (" ); if( reading.autorange ) printf( " auto" ); if( reading.battery ) printf( " battery" ); if( reading.delta ) printf( " delta" ); if( reading.hold ) printf( " hold" ); printf( ")\n" ); break; } /* * printf( "%02X\n", 0x00FF & buf[ 0 ]); */ } }