/* Ausleseprogram für Voltcraft VC820 & VC840 Reverse-Engineered von Georg Acher, Nov. 2001 WWW: http://www.acher.org e-mail: georg at acher dot org Das VC820/840 sendet 14 Bytes mit 2400Baud 8N1 Das High-Nibble der Bytes entspricht der Position (1...e) Nur das Low-Nibble ist interessant! Die Low-Nibbles codieren LCD-Segmente: Nibble 0: AUTO|AC|TRUE_RMS|RS232 Nibble 1-2: Minus, Digit 0 Nibble 3-4: Dot, Digit 1 Nibble 5-6: Dot, Digit 2 Nibble 7-8: Dot, Digit 3 Nibble 8-14: numkM A V Hz F Ohm °C % Rel Diode Beep Hold */ #include #include #include #include #include #include #include #include #include #include #include #define STD_FLG (CS8|CREAD|HUPCL) int fd; unsigned int get_time() { struct timeval ti; struct timezone tzp; gettimeofday(&ti,&tzp); return ti.tv_usec+1000000*ti.tv_sec; } /*---------------------------------------------------------------------*/ int open_serial(char* out_dev, int baudrate) { int fd; int bdflag; struct termios tty; int x; char device[]="/dev/ttyS0"; fprintf(stderr,"Using serial output to %s, baudrate %i\n", device,baudrate); if (baudrate==19200) bdflag=B19200; else if (baudrate==9600) bdflag=B9600; else if (baudrate==4800) bdflag=B4800; else if (baudrate==2400) bdflag=B2400; else if (baudrate==1200) bdflag=B1200; else if (baudrate==38400) bdflag=B38400; else if (baudrate==57600) bdflag=B57600; else if (baudrate==115200) bdflag=B115200; else if (baudrate==230400) bdflag=B230400; else { fprintf(stderr,"Unsupported baudrate %i\n",baudrate); exit(-1); } fd=open(out_dev,O_RDWR); // ttyS1 = COM2 if (fd==-1) { perror("open failed"); exit(-1); } tcgetattr(fd, &tty); tty.c_iflag = IGNBRK | IGNPAR; tty.c_oflag = 0; tty.c_lflag = 0; tty.c_line = 0; tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 1; tty.c_cflag =STD_FLG; cfsetispeed(&tty,bdflag); cfsetospeed(&tty,bdflag); tcsetattr(fd, TCSAFLUSH, &tty); return fd; } /*---------------------------------------------------------------------*/ void close_serial(int fd) { close(fd); } /*---------------------------------------------------------------------*/ void set_rts_dtr(int fd) { int arg; arg=TIOCM_RTS|TIOCM_DTR; ioctl(fd,TIOCMBIS,&arg); arg=TIOCM_RTS; ioctl(fd,TIOCMBIC,&arg); } /*---------------------------------------------------------------------*/ int digit(int x) { int dig[10]={0xd7,0x05,0x5b,0x1f,0x27,0x3e, 0x7e,0x15,0x7f, 0x3f}; int n; x=x&0x7f; for(n=0;n<10;n++) if (x==dig[n]) return n; return 0; } /*---------------------------------------------------------------------*/ char *dvm_unit(int y, int x, char *s) { char *prefix=""; char *unit=""; char *ext=""; char *ext1=""; if (x&0x2000) ext="delta"; else if (x&0x100000) ext="Diode"; else if (x&0x10000) ext="Beep"; if (x&0x080000) prefix="m"; else if (x&0x800000) prefix="u"; else if (x&0x400000) prefix="n"; else if (x&0x020000) prefix="M"; else if (x&0x200000) prefix="k"; if (x&0x0800) unit="A"; else if (x&0x0200) unit="Hz"; else if (x&0x40000) unit="%"; else if (x&0x10) unit="°C"; else if (x&0x4000) unit="Ohm"; else if (x&0x0400) unit="V"; else if (x&0x8000) unit="F"; sprintf(s,"%s%s %s (%s)",prefix, unit, (y&0x8?"AC":""), ext); } /*---------------------------------------------------------------------*/ int main(int argc,char **argv) { unsigned char data; unsigned char buffer[100]; unsigned char buffer1[9]; char units[20]; int n; float it; unsigned int t,tf; fd=open_serial("/dev/ttyS0", 2400); set_rts_dtr(fd); // DTR/RTS setzen t=get_time(NULL); while(1) { n=0; memset(buffer,0,20); while(1) { read(fd,&buffer[n],1); if ((buffer[n]&0xf0)==0xe0 || (n==16)) break; n++; } #if 0 // Raw output for(n=0;n<16;n++) printf("%02x ",buffer[n]); #endif buffer1[0]=buffer[0]&15; for(n=0;n<8;n++) buffer1[1+n]=((buffer[2*n+1]&15)<<4)|(buffer[2*n+2]&15); #if 0 // Nibble compacted data for(n=0;n<8;n++) printf("%02x ",buffer1[n]); printf("%i%i%i%i\n",digit(buffer1[1]),digit(buffer1[2]), digit(buffer1[3]),digit(buffer1[4])); #endif if ((buffer1[3]&0x7f)==0x68) it=9999999; else it=1000.0*digit(buffer1[1])+100.0*digit(buffer1[2]) +10*digit(buffer1[3])+1*digit(buffer1[4]); if (buffer1[4]&0x80) it=it/10.0; if (buffer1[3]&0x80) it=it/100.0; if (buffer1[2]&0x80) it=it/1000.0; if (buffer1[1]&0x80) it=-it; tf=(int)((get_time(NULL)-t)/100000.0); dvm_unit(buffer1[0], (buffer1[5]<<16)|(buffer1[6]<<8)|buffer1[7],units); printf("%0.1f %0.3f %s\n",tf/10.0,it, units); fflush(stdout); } }