/* $Id: tsl.c,v 1.12 2004/01/26 06:58:50 james Exp james $ tsl, temperature sensor data logger Copyright (C) 2000 James Cameron (quozl@us.netrek.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef lint static char vcid[] = "$Id: tsl.c,v 1.12 2004/01/26 06:58:50 james Exp james $"; #endif /* lint */ #include #include #include #include #include #include #include #include #include #include #define MAXSENSOR 4 #define MAXFILENAME 256 #include #include static int sfd; static int cancel; static char *device; static void serial_open() { struct termios termios; sfd = open(device, O_RDONLY); if (sfd < 0) { char buffer[1024]; snprintf(buffer, 1024, "open: %s", device); perror(buffer); exit(1); } /* set the serial port characteristics */ if (tcgetattr(sfd, &termios) < 0) { perror("tcgetattr"); exit(1); } if (cfsetospeed(&termios, B2400) < 0) { perror("cfsetospeed"); exit(1); } if (cfsetispeed(&termios, B2400) < 0) { perror("cfsetispeed"); exit(1); } if (tcsetattr(sfd, TCSANOW, &termios) < 0) { perror("tcsetattr"); exit(1); } } static void serial_close() { close(sfd); } static char *serial_read(char *buffer, int size) { char *p; int s; cancel = 0; alarm(5); p = buffer; s = size; while (1) { int n = read(sfd, p, 1); if (cancel) { serial_close(); sleep(10); serial_open(); break; } if (n == 0) { sleep(1); continue; } if (n < 0) { perror("read"); break; } if (*p == '\r' || *p == '\n') break; p++; s--; if (s == 1) break; } *p = '\0'; alarm(0); return buffer; } static void sigalrm(int signal) { fprintf(stderr, "timeout cancel\n"); cancel = 1; } int main ( int argc, char *argv[] ) { char *p, buffer[128]; char *name = "%Y-%j.log"; FILE *output = NULL; int i, number, sample, seen[MAXSENSOR]; time_t now; struct tm *tm; float datum[MAXSENSOR]; int breaker = 0; /* handle SIGALRM */ { struct sigaction *sa = calloc(1, sizeof(struct sigaction)); sa->sa_handler = sigalrm; sigaction(SIGALRM, sa, NULL); free(sa); } /* reset sensor result array */ for (i=0; i 1) { device = argv[1]; } /* allow user to specify sample recording rate */ sample = 30; if (argc > 2) { sample = atoi(argv[2]); } /* allow user to specify recording file name */ if (argc > 3) { name = argv[3]; } /* open the serial port, causing DTR to be raised and the sensor to run */ serial_open(); /* infinite loop */ for(;;) { p = serial_read(buffer, 128); p = buffer + strlen(buffer) - 1; while (*p == '\r' || *p == '\n') { *p-- = '\0'; if (p < buffer) break; } p = buffer; while (*p == '\r' || *p == '\n') p++; if (*p == 'R') { continue; } if (!isdigit(*p)) continue; number = atoi(p)-1; if (number < 0 || number > MAXSENSOR-1) continue; p++; if (*p != ' ') continue; if (strlen(p) > 9) p += 11; now = time(NULL); tm = localtime(&now); p++; sscanf(p, "%f", &datum[number]); seen[number]++; if (number != 0) { /* is not first sensor, so go back for more */ continue; } if (seen[number] < 2) { /* is first sensor, but it is first time we saw it, try more */ continue; } char new[MAXFILENAME]; char old[MAXFILENAME]; /* create a file name */ strftime(new, MAXFILENAME-1, name, tm); if (output == NULL) { output = fopen(new, "a"); if (output == NULL) { perror(new); exit(1); } strcpy(old, new); } else { if (strcmp(old, new)) { fprintf(stderr, "\n\nnew file, new=%s, old=%s\n\n", new, old); fclose(output); output = fopen(new, "a"); if (output == NULL) { perror(new); exit(1); } strcpy(old, new); } } /* gnuplot deserves a blank line for a new sample range, aka run */ if (!breaker) { fprintf(output, "\n"); breaker++; } char ts[80]; strftime(ts, 79, "%s", tm); fprintf(output, "%s", ts); for (i=0; i (sample * 2)) breaker = 0; serial_open(device); for (i=0; i