On Sunday 30 September 2001 14:30, Mike Meyer wrote: > It looks like you've already got a solution to this problem, and this > won't be very useful if the 40kHz figure is right, but I figured I > might mention it anyway. Have you thought about using the feature of > the callin device of the "open" call blocking until it gets CD? You > should then get a SIGHUP when CD drops.
This sounded like a really good idea when I first read it, so I wrote a test. The first thing I noticed is that SIGHUP was *NOT* being generated (any idea why?) on CD transition to low. I then realized that I could use write() and it would fail when CD==low. So I used that technique for detecting CD==low, and after setting "dtrwait" to 0 using comcontrol, things seemed to be going well. However, I pressed the same button on the remote multiple times and I noticed a very high variance in the time-deltas between high/low states. In fact, sometimes 7 transitions are reported, sometimes 9. The variance for some time-deltas is sometimes as high as a factor of 10 (note: I'm not using the statistical definition of variance - I simply mean that a +edge -> -edge time can be 100us and then 1000us on the next press of the same button). Sadly, this seemingly good mechanism doesn't perform well enough to produce the kind of data I'd need for pattern matching. Perhaps actually managing to generate a SIGHUP would cut down on this variance? I've attached the source for the test program for your reading enjoyment. :) Don't feel obligated to open it. --Bart
/* Cow & Chicken rule! * * IRBaboon Copyright (C) Bart Kus, 2001. */ /* NOTE: * Be SURE to do a: comcontrol /dev/irbaboon dtrwait 0 * Prior to running this program! */ #include <stdio.h> #include <fcntl.h> #include <termios.h> #include <signal.h> #include <sys/time.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> int i; unsigned int dt[256]; void handler_sighup(int data) { printf("Got SIGHUP\n"); return; } void handler_sigint(int data) { int i2; for(i2=0; i2 < i; i2++) printf("DT: %010dus\n", dt[i2]); return; } int main(int argc, char **argv) { int fd; struct termios t; struct timeval high, low; /* Configure our CD->low SIGHUP handler */ signal(SIGHUP, handler_sighup); signal(SIGINT, handler_sigint); /* Configure the port */ cfsetspeed(&t, B115200); t.c_iflag = 0; t.c_oflag = 0; t.c_cflag = CSIZE|CS6|CREAD|HUPCL; t.c_lflag = 0; for(i=0; i < NCCS; i++) t.c_cc[i] = '\0'; i=0; while(1) { /* Open callin device - blocks until CD->high */ fd = open("/dev/irbaboon", O_RDWR, 0); gettimeofday(&high, NULL); if(tcsetattr(fd, TCSANOW, &t)) { perror("tcsetattr()"); exit(1); } while(write(fd, "X", 1) != -1); gettimeofday(&low, NULL); close(fd); /* printf("HIGH: %09d.%09ds\n", high.tv_sec, high.tv_usec); printf(" LOW: %09d.%09ds\n", low.tv_sec, low.tv_usec); printf(" DT: %010dus\n", (low.tv_sec-high.tv_sec)*1000000 + (low.tv_usec - high.tv_usec));*/ dt[i++] = (low.tv_sec-high.tv_sec)*1000000 + (low.tv_usec - high.tv_usec); } return 0; }