#include #include #include #include "/home/jeblack3/libusblinux300/ownet.h" #include "/home/jeblack3/libusblinux300/findtype.h" #define MATCH_ROM 0x55 #define CONVERT_T 0x44 #define READ_SCRATCHPAD 0xBE #define SN_LEN 8 #define SCRATCHPAD_LEN 9 #define MAX_LINE 256 #define MAX_BUFFER 256 #define MAXDEVICES 256 void echoReadBlock (unsigned char *buf, SMALLINT len); void echoWriteBlock (unsigned char *buf, SMALLINT len); void msg (char *s); void msgHex (unsigned char c); int portnum, doOutputToFile; char printline[MAX_LINE]; FILE *outputFile; int main (int argc, char *argv[]) { char portname[] = "DS2490-1"; unsigned char SN[MAXDEVICES][SN_LEN], command, scratchpad[SCRATCHPAD_LEN]; int i, j, anyData, numTherms, dev; struct timespec delay; time_t currTime, prevTime; signed long tempInt; float temp; unsigned short inputBit, crc; delay.tv_sec = 1; delay.tv_nsec = 0; // Acquire adapter portnum = owAcquireEx (portname); if (portnum < 0) { printf ("ERROR: Adapter not found\n"); return 0; } // Find thermometers numTherms = FindDevices (portnum, SN, 0x10, MAXDEVICES); if (numTherms == 0) { printf ("ERROR: No thermometers found\n"); return 0; } // Open output file if (argc >= 2) { doOutputToFile = 1; outputFile = fopen (argv[1], "a"); if (outputFile == NULL) { printf ("ERROR: Output file '%s' could not be created\n", argv[1]); } } else { doOutputToFile = 0; } prevTime = time (NULL); while (1) { // Convert Temperature commands for (dev = 0; dev < numTherms; dev++) { printline[0] = '\0'; if ( !owTouchReset(portnum) ) { msg ("ERROR: No one-wire devices present on network\n"); } command = MATCH_ROM; echoWriteBlock (&command, 1); echoWriteBlock (SN[dev], SN_LEN); command = CONVERT_T; echoWriteBlock (&command, 1); if ( owTouchBit(portnum, 1) ) { sprintf (printline + strlen(printline), "1"); msg ("ERROR: No response to CONVERT T command\n"); } else { sprintf (printline + strlen(printline), "0"); } sprintf (printline + strlen(printline), "\n"); msg (printline); } // Sleep 1 second if ( nanosleep(&delay, NULL) != 0) { msg ("ERROR: Sleep interrupted\n"); } // Check time currTime = time (NULL); if (currTime != prevTime + 1 && currTime != prevTime + 2) { msg ("ERROR: Unexpected delay\n"); } prevTime = currTime; for (dev = 0; dev < numTherms; dev++) { // Clear print line printline[0] = '\0'; // Read Scratchpad command if ( !owTouchReset(portnum) ) { msg ("ERROR: No one-wire devices present on network\n"); } command = MATCH_ROM; echoWriteBlock (&command, 1); echoWriteBlock (SN[dev], SN_LEN); command = READ_SCRATCHPAD; echoWriteBlock (&command, 1); echoReadBlock (scratchpad, SCRATCHPAD_LEN); sprintf (printline + strlen(printline), " "); // Get time currTime = time (NULL); sprintf (printline + strlen(printline), "%10lu ", currTime); if (currTime != prevTime && currTime != prevTime + 1) { msg ("ERROR: Unexpected delay\n"); } // Check whether any data was read anyData = 0; for (i = 0; i < SCRATCHPAD_LEN && !anyData; i++) { if (scratchpad[i] != 0xFF) { anyData = 1; } } if (!anyData) { msg ("ERROR: All ones read from device\n"); } else { // Check consistency of temperature sign if (scratchpad[1] != 0x00 && scratchpad[1] != 0xFF) { msg ("ERROR: Sign bits inconsistent\n"); } // Check whether extended precision bits are in range if (scratchpad[6] == 0 || scratchpad[6] > 16) { msg ("ERROR: COUNT REMAIN out of range\n"); } else { // Check consistency of extended-precision temperature with last bit of temperature if ( (scratchpad[6] < 9) != (scratchpad[0] & 1) ) { msg ("ERROR: COUNT REMAIN and Temperature inconsistent\n"); } } // Check cyclic redundancy code crc = 0; for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { inputBit = ( (scratchpad[i] & (1 << j)) != 0 ); inputBit ^= (crc & 1); crc >>= 1; if (inputBit) { crc ^= 0x8C; } } } if (scratchpad[8] != crc) { msg ("ERROR: CRC received = "); msgHex (scratchpad[8]); msg (" but CRC calculated = "); msgHex ((unsigned char) crc); msg ("\n"); } // Check bytes 4 and 5 if (scratchpad[4] != 0xFF) { msg ("ERROR: Scratchpad byte 4 is not FF\n"); } if (scratchpad[5] != 0xFF) { msg ("ERROR: Scratchpad byte 4 is not FF\n"); } // Check COUNT PER deg C if (scratchpad[7] != 16) { msg ("ERROR: COUNT PER deg C is not 16\n"); } } // Convert temperature to human-readable format tempInt = scratchpad[1]; tempInt <<= 7; tempInt += (scratchpad[0] >> 1); if (tempInt >= 0x4000) { tempInt -= 0x8000; } temp = tempInt - 0.25 + ((float) (16 - scratchpad[6])) / 16; if (temp < -55 || temp > 125) { msg ("ERROR: Temperature out of range\n"); } sprintf (printline + strlen(printline), "%9.4f\n", temp); // Print data msg (printline); } } } void echoWriteBlock (unsigned char *buf, SMALLINT len) { int i, silent; unsigned char buf2[MAX_BUFFER]; for (i = 0; i < len; i++) { buf2[i] = buf[i]; sprintf (printline + strlen(printline), "%02X", buf[i]); } sprintf (printline + strlen(printline), " "); owBlock (portnum, FALSE, buf2, len); silent = 1; for (i = 0; i < len && silent; i++) { if (buf2[i] != buf[i]) { silent = 0; } } if (!silent) { msg ("ERROR: Wrote "); for (i = 0; i < len; i++) { msgHex (buf[i]); } msg (" but read "); for (i = 0; i < len; i++) { msgHex (buf2[i]); } msg ("\n"); } return; } void echoReadBlock (unsigned char *buf, SMALLINT len) { int i; for (i = 0; i < len; i++) { buf[i] = 0xFF; } owBlock (portnum, FALSE, buf, len); for (i = 0; i < len; i++) { sprintf (printline + strlen(printline), "%02X", buf[i]); } sprintf (printline + strlen(printline), " "); return; } void msg (char *s) { printf ("%s", s); if (doOutputToFile) { fprintf (outputFile, "%s", s); fflush (outputFile); } return; } void msgHex (unsigned char c) { printf ("%02X", c); if (doOutputToFile) { fprintf (outputFile, "%02X", c); fflush (outputFile); } return; }