#include #include #include #include #include #include #include #include #include #include // Nathan's new header include #include #define BAUDRATE B9600 #define MODEMDEVICE "/dev/ttyUSB0" // deprecated - now as a parameter #define _POSIX_SOURCE 1 // POSIX compliant source #define FALSE 0 #define TRUE 1 // Nathan's exit code constants. #define E_GOOD 0 #define E_WARN 1 #define E_CRIT 2 #define E_UNKN 3 volatile int STOP=FALSE; char m_CHic; int fd; void Delay(int msec) { usleep(10 * msec); } void DTR(int set) { int status = 0; ioctl(fd, TIOCMGET, &status); if (set) { status |= TIOCM_DTR; } else { status &= ~TIOCM_DTR; } if (ioctl(fd, TIOCMSET, &status) < 0) { perror("ioctl"); exit(1); } } void RTS(int set) { int status = 0; if (ioctl(fd, TIOCMGET, &status) < 0) { perror("ioctl"); exit(1); } if (set) { status |= TIOCM_RTS; } else { status &= ~TIOCM_RTS; } if (ioctl(fd, TIOCMSET, &status) < 0) { perror("ioctl"); exit(1); } } int CTS(void) { int status = 0; ioctl(fd, TIOCMGET, &status); return (status & TIOCM_CTS); } void Sclk(int a) { if (m_CHic == 'T') { DTR(a == 0); } else if (m_CHic == 'R') { DTR(a == 1); } } void SDout(int ad01) { if (m_CHic == 'T') { if (ad01 == 0) { RTS(1); } else if (ad01 == 1) { RTS(0); } } if (m_CHic == 'R') { if (ad01 == 0) { RTS(0); } else if (ad01 == 1) { RTS(1); } } } int SDin(void) { SDout(1); Delay(100); int a = CTS(); if (m_CHic != 'R') { return m_CHic == 'T' && !a; } else { return a > 0; } } void HiLowSCLK(void) { Delay(10); Sclk(1); Delay(20); Sclk(0); Delay(20); } void Start_IIC(void) { SDout(1); Delay(4); Sclk(1); Delay(40); SDout(0); Delay(30); Sclk(0); } void Stop_IIC(void) { SDout(0); Delay(50); Sclk(1); Delay(50); SDout(1); Delay(50); } void WriteP1P0(int P0123, const char *dataS) { Stop_IIC(); Delay(100); Start_IIC(); SDout(1); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(0); HiLowSCLK(); Delay(100); Sclk(1); Delay(100); SDin(); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); // Do we even need this comparison? if (P0123 > -1 && P0123 < 4) { SDout(P0123 & 2); HiLowSCLK(); SDout(P0123 & 1); HiLowSCLK(); } Delay(100); Sclk(1); Delay(100); SDin(); HiLowSCLK(); while (*dataS != '\0') { SDout(*dataS == '1'); HiLowSCLK(); Delay(100); dataS++; } Sclk(1); Delay(100); Delay(100); SDin(); HiLowSCLK(); SDout(0); HiLowSCLK(); Stop_IIC(); } void Init(void) { m_CHic = 'T'; WriteP1P0(1, "0110000"); WriteP1P0(0, "00000000"); } double Bin2Dec(const char *s) { double lDec = 0.0; if (s == NULL || strlen(s) == 0) { s = "0"; } while (*s != '\0') { if (*s == '1') { lDec += pow(2.0, strlen(s) - 1); } s++; } return lDec; } double ReadTEMP(void) { static char buf[16]; double temperature; SDout(1); SDin(); SDout(0); SDin(); Start_IIC(); SDout(1); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(0); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); SDout(1); HiLowSCLK(); Sclk(1); Delay(100); int tt = SDin(); HiLowSCLK(); if (tt == 1) { m_CHic ^= 6; } if (tt == 1) { return -1000.0; } memset(buf, '\0', sizeof(buf)); int i; for (i = 0; i < 16; i++) { int s = SDin(); buf[i] = (s == 0 ? '0' : '1'); HiLowSCLK(); if (i == 7) { tt = SDin(); Delay(100); HiLowSCLK(); } } Sclk(0); Delay(1); SDout(0); HiLowSCLK(); Stop_IIC(); char str_msb[4]; char str_lsb[9]; char FuHao = buf[0]; memcpy(str_msb, buf, 3); str_msb[3] = '\0'; memcpy(str_lsb, buf+3, 8); str_lsb[8] = '\0'; double msb = Bin2Dec(str_msb); double lsb = Bin2Dec(str_lsb); double tempdata = (msb * 256.0) + lsb; switch (FuHao) { case '0': temperature = tempdata * 0.125; break; case '1': temperature = -(2048.0 - tempdata) * 0.125; break; } return temperature; } // Nathan's custom integer conversion function int intval(char* number, int* error) { int i = 0; if (number[0] == '-' || number[0] == '+') { i++; } while (number[i] != '\0') { if (!isdigit(number[i])) { printf("%.3s is not a number\n", number); *error = 1; return 0; } i++; } *error = 0; return atoi(number); } int main(int argc, char **argv) { if (argc != 4) { printf("ERROR: Wrong number of parameters.\nUsage: check_temper \n"); return E_UNKN; } int conv_err; int warn = intval(argv[2], &conv_err); if (conv_err == 1) { printf("ERROR: Warning parameter is not a valid integer. Value given: '%s'\n", argv[2]); return E_UNKN; } int crit = intval(argv[3], &conv_err); if (conv_err == 1) { printf("ERROR: Error parameter is not a valid integer. Value given: '%s'\n", argv[3]); return E_UNKN; } fd = open(argv[1], O_RDWR | O_NOCTTY ); if (fd < 0) { perror(argv[1]); return E_UNKN; } struct termios oldtio, newtio; Init(); tcgetattr(fd,&oldtio); /* save current port settings */ memcpy(&newtio, &oldtio, sizeof(newtio)); newtio.c_cflag |= (CLOCAL | CREAD); newtio.c_cflag &= ~PARENB; newtio.c_cflag &= ~CSTOPB; newtio.c_cflag &= ~CSIZE; newtio.c_cflag |= CS8; cfsetispeed(&newtio, BAUDRATE); cfsetospeed(&newtio, BAUDRATE); newtio.c_cflag |= CRTSCTS; newtio.c_iflag |= IGNPAR; newtio.c_oflag &= ~OPOST; /* set input mode (non-canonical, no echo,...) */ newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); newtio.c_cc[VTIME] = 1; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 5 chars received */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); // Have to invoke ReadTEMP twice to get reasonable output. // What the bloody hell is that all about??? If only I wasn't // too lazy to find out. If only. ReadTEMP(); usleep(50000); double foo = ReadTEMP(); int floored_temp = (int) floor(foo); if (floored_temp < warn) { printf("OK: Ambient temperature %.1f C | temperature=%.1f;%d;%d\n", foo, foo, warn, crit); return E_GOOD; } else if ((floored_temp >= warn) && (floored_temp < crit)) { printf("WARNING: Ambient temperature %.1f C | temperature=%.1f;%d;%d\n", foo, foo, warn, crit); return E_WARN; } else if (floored_temp >= crit) { printf("CRITICAL: Ambient temperature %.1f C | temperature=%.1f;%d;%d\n", foo, foo, warn, crit); return E_CRIT; } else { // I don't think that it is possible to get here... printf("UNKNOWN"); } return E_UNKN; }