/* $Id: tc100.c,v 1.5 2013/07/04 14:13:26 tsubai Exp $ */ /* * NetBSD で TC100S からデータを読む。 * これを動かしておいて、 * * 線量率: * % printf '\x0201\x0301' > /dev/dtyU0 * 積算線量: * % printf '\x0202\x0302' > /dev/dtyU0 * スペクトル: * % printf '\x02080\x0338' > /dev/dtyU0 * スペクトルのリセット: * % printf '\x02880\x0330' > /dev/dtyU0 * * とかする。 */ #include #include #include #include #include #include #include #include #include int fd; int readtc(buf, len) void *buf; int len; { int n; n = read(fd, buf, len); if (n < 0) err(0, "read"); if (n == 0) { printf("EOF\n"); exit(0); } return n; } int readtc2(buf, len) void *buf; int len; { char *p = buf; struct pollfd set[1]; int n; set[0].fd = fd; set[0].events = POLLIN; while (len > 0) { if (poll(set, 1, 5000) != 1) { printf("read timeout\n"); exit(0); } n = read(fd, p, len); if (n < 0) err(0, "read"); if (n == 0) { printf("EOF\n"); exit(0); } p += n; len -= n; } return 0; } int cksum(buf, len) void *buf; int len; { u_char *p = buf; u_int sum = 0; while (len-- > 0) sum ^= *p++; return sum & 0xff; } void displine(p, n) char *p; int n; { printf("n = %d, ", n); while (n-- > 0) printf("%02x ", *p++); printf("\n"); } char *logfile = "log"; char *device = "/dev/dtyU0"; int main(argc, argv) int argc; char *argv[]; { struct termios t; int c; int debug = 0; while ((c = getopt(argc, argv, "Df:")) != -1) { switch (c) { case 'D': debug = 1; break; case 'f': logfile = optarg; break; default: printf("unknown option\n"); exit(0); } } argc -= optind; argv += optind; if (argc > 0) device = argv[0]; fd = open(device, 2); if (fd < 0) err(0, "open"); tcgetattr(fd, &t); cfmakeraw(&t); t.c_cflag |= CLOCAL; tcsetattr(fd, TCSANOW, &t); tcsetattr(fd, TCSANOW, &t); /* XXX 2回やらないと動かない */ write(fd, "\n\n", 2); tcdrain(fd); sleep(1); tcflush(fd, TCIFLUSH); if (debug == 0) { if (freopen(logfile, "a", stdout) == NULL) err(0, "freopen"); if (daemon(1, 1)) err(0, "daemon"); } for (;;) { parse_line(); fflush(stdout); } } /* * unknown command 15 * (or checksum error) * disconnected 0a * ack 06 * 線量率 02 30 31 xx xx xx xx xx xx xx xx 03 ss ss * 積算線量 02 30 32 xx xx xx xx xx xx xx xx 03 ss ss * スペクトル 02 30 37 (2048バイト) 03 ss ss */ int parse_line() { u_int reply, x; char rbuf[16]; readtc(rbuf, 1); /* displine(rbuf, 1); */ if (rbuf[0] == 0x15) { /* unknown command */ printf("ERROR\n"); return 0; } if (rbuf[0] == 0x0a) { /* unplug or shutdown */ printf("DISCONNECTED\n"); return 0; } if (rbuf[0] == 6) { printf("ACK\n"); return 0; } if (rbuf[0] != 2) { displine(rbuf, 1); return -1; } readtc2(rbuf + 1, 2); reply = rbuf[1] << 8 | rbuf[2]; if (reply == 0x3031) { /* 線量率 */ readtc2(rbuf + 3, 11); sscanf(rbuf + 3, "%x", &x); printf("線量率 %d.%03d μSv/h\n", x / 1000, x % 1000); sscanf(rbuf + 12, "%2x", &x); if (cksum(rbuf + 1, 10) != x) { printf("cksum error\n"); displine(rbuf, 14); } return 0; } if (reply == 0x3032) { /* 積算線量 */ readtc2(rbuf + 3, 11); sscanf(rbuf + 3, "%x", &x); printf("積算線量 %d.%d μSv/h\n", x / 10, x % 10); sscanf(rbuf + 12, "%2x", &x); if (cksum(rbuf + 1, 10) != x) { printf("cksum error\n"); displine(rbuf, 14); } return 0; } if (reply == 0x3037) { time_t t; time(&t); printf("BEGIN spectrum %.20s\n", ctime(&t) + 4); read_spectrum(); return 0; } displine(rbuf, 3); return -1; } int read_spectrum() { int sum, i; u_int x; u_short spectrum_data[512]; u_char rbuf[2048]; bzero(rbuf, sizeof rbuf); readtc2(rbuf, 2048); for (i = 0; i < 512; i++) { if (sscanf(rbuf + i * 4, "%4x", &x) != 1) { printf("format error\n"); printf(" i = %d\n", i); dump(rbuf, 2048); sleep(1); tcflush(fd, TCIOFLUSH); return -1; } spectrum_data[i] = x; } sum = cksum(rbuf, 2048); sum ^= 0x30; /* BEGIN ... */ sum ^= 0x37; /* checksum */ readtc2(rbuf, 3); if (rbuf[0] != 3) { printf("data error\n"); return -1; } sscanf(rbuf + 1, "%2x", &x); if (x != sum) { printf("cksum mismatch\n"); return -1; } for (i = 0; i < 512; i++) { printf("%d", spectrum_data[i]); printf((i % 16 == 15) ? "\n" : " "); } printf("END spectrum\n"); return 0; } int dump(v, n) void *v; int n; { FILE *fp; time_t t; char *p = v; int i, addr = 0; fp = fopen("dumpfile", "a"); time(&t); fprintf(fp, "DUMP %.20s\n", ctime(&t) + 4); fprintf(fp, "n = %d\n", n); while (n > 0) { fprintf(fp, "%04x", addr); for (i = 0; i < 16; i++) fprintf(fp, " %02x", *p++); fprintf(fp, "\n"); addr += 16; n -= 16; } fprintf(fp, "\n"); fclose(fp); return 0; }