// // compap.exe - Data logger for Medusa DC Power Analyzer Plus (PAP). // // Reads PC RS-232 serial COM port, time stamps, and logs data to disk. // // 04-Apr-2005 /tvb // #include #include #include #include #include "comlib.h" #include "loglib.h" #define PACKET_SIZE 21 int debug = 0; #define FPRINTF debug && fprintf unsigned char checksum (unsigned char buf[]) { int i, sum; sum = 0; for (i = 0 + 1; i < PACKET_SIZE - 1; i += 1) { sum += buf[i]; } return sum & 0xFF; } void main (int argc, char *argv[]) { long lines; time_t now, then; int once = 1; struct { int port, seconds, stamp, limit; } opt; struct { double volts, amps, watts, amp_hr, watt_hr, count; } sum; opt.port = (argc > 1) ? atoi(argv[1]) : 1; opt.seconds = (argc > 2) ? atoi(argv[2]) : 10; opt.stamp = (argc > 3) ? atoi(argv[3]) : 0; opt.limit = (argc > 4) ? atoi(argv[4]) : 0; debug = (argc > 5) ? atoi(argv[5]) : 0; fprintf(stderr, "port=%d seconds=%d stamp=%d limit=%d debug=%d\n", opt.port, opt.seconds, opt.stamp, opt.limit, debug); CommOpen(opt.port, 19200, 0, 0); CommTimeout(100, 0, 5000); LogOpen("pap%d.txt"); lines = 0; memset(&sum, 0x0, sizeof sum); then = 0; do { int bytes; unsigned char data[PACKET_SIZE + 1]; // // The size and time delimited data packet is valid if: // - packet arrives in burst with 100+ ms dead time // - size is exactly 21 bytes // - first byte is STX // - second byte is 'B' // - last byte has valid checksum // bytes = CommRead(data, sizeof data); if (bytes == 0) { FPRINTF(stderr, "timeout - no data received\n"); continue; } if (bytes < PACKET_SIZE) { FPRINTF(stderr, "short packet (%d)\n", bytes); continue; } if (bytes > PACKET_SIZE) { FPRINTF(stderr, "long packet (%d)\n", bytes); continue; } if (data[0] != 0x02) { FPRINTF(stderr, "missing STX\n"); continue; } if (data[1] != 'B') { FPRINTF(stderr, "packet version mismatch\n"); continue; } if (data[PACKET_SIZE - 1] != checksum(data)) { FPRINTF(stderr, "packet checksum error\n"); continue; } if (once) { fprintf(stderr, "** Receiving good data...\n"); once = 0; } // // Extract fields, scale data, and sum toward mean. // #define DATA16(i,j) (data[i] + data[j] * 256) #define DATA24(i,j,k) (data[i] + data[j] * 256 + data[k] * 65536) sum.volts += DATA16(2, 3) / 100.0; sum.amps += DATA16(4, 5) / 100.0; sum.amp_hr += DATA24(6, 7, 8) / 1000.0; sum.watts += DATA16(9, 10) / 1.0; sum.watt_hr += DATA24(11, 12, 13) / 10.0; sum.count += 1; // // Display mean values at the top of every N seconds. // time(&now); if (opt.seconds == 0 || ((now % opt.seconds) == 0 && now > then)) { char str[100]; sprintf(str, "%s%5.2f V %6.3f A %8.4f Ah %5.1f W %7.2f Wh\n", LogTimeStamp(opt.stamp), sum.volts / sum.count, sum.amps / sum.count, sum.amp_hr / sum.count, sum.watts / sum.count, sum.watt_hr / sum.count); LogWrite(str, strlen(str)); lines += 1; memset(&sum, 0x0, sizeof sum); then = now; } } while (opt.limit == 0 || lines < opt.limit) ; LogClose(); CommClose(); } // Or use a makefile... #include "comlib.c" #include "loglib.c"