Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.40 KB | None | 0 0
  1.  
  2. #include <fcntl.h>
  3. #include <getopt.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/select.h>
  8. #include <sys/stat.h>
  9. #include <sys/types.h>
  10. #include <termios.h>
  11. #include <time.h>
  12. #include <unistd.h>
  13.  
  14. #define TIMEOUT 1
  15. #define DS18X20_ROM_SIZE 8
  16. #define DS18X20_SP_SIZE 9
  17. #define DS18X20_GENERATOR 0x8c
  18.  
  19. static char* ut_msgs[] = {
  20. "",
  21. "Error, could not get baud rate!",
  22. "Error, could not set baud rate!",
  23. "Error, serial port does not exist!",
  24. "Error, you don't have rw permission to access serial port!",
  25. "Error, failed to open serial port device!",
  26. "Error, sensor not found!", /* 6 */
  27. "Error, sensor CRC mismatch!",
  28. "Warining, not expected sensor response!",
  29. "Error, could not send data"
  30. };
  31.  
  32. int ut_errno;
  33.  
  34. enum {
  35. HELP,
  36. ACQUIRE_TEMP,
  37. READ_ROM
  38. };
  39.  
  40. /*
  41. Signals taken from:
  42. https://www.maximintegrated.com/en/app-notes/index.mvp/id/214
  43. */
  44.  
  45. char *ut_errmsg(void)
  46. {
  47. return ut_msgs[ut_errno];
  48. }
  49.  
  50. static unsigned char lsb_crc8(unsigned char *data_in, unsigned int len, const unsigned char generator)
  51. {
  52. unsigned char i, bit_counter;
  53. unsigned char crc = 0;
  54.  
  55. for (i = 0; i < len; i++) {
  56. crc ^= *(data_in + i);
  57. bit_counter = 8;
  58. do {
  59. if (crc & 0x01)
  60. crc = (((crc >> 1) & 0x7f) ^ generator);
  61. else
  62. crc = (crc >> 1) & 0x7f;
  63. bit_counter--;
  64. } while (bit_counter > 0);
  65. }
  66. return crc;
  67. }
  68.  
  69. static int owReset(int fd)
  70. {
  71. int rv;
  72. int wbytes, rbytes;
  73. unsigned char wbuff, rbuff;
  74. fd_set readset;
  75. struct timeval timeout_tv;
  76. struct termios term;
  77.  
  78. tcflush(fd, TCIOFLUSH);
  79.  
  80. if (tcgetattr(fd, &term) < 0) {
  81. ut_errno = 1;
  82. return -1;
  83. }
  84. term.c_cflag &= ~CSIZE | CS8;
  85. cfsetispeed(&term, B9600);
  86. cfsetospeed(&term, B9600);
  87. tcsetattr(fd, TCSANOW, &term);
  88.  
  89. /* Send the reset pulse. */
  90. wbuff = 0xf0;
  91. wbytes = write(fd, &wbuff, 1);
  92. if (wbytes != 1) {
  93. ut_errno = 9;
  94. return -1;
  95. }
  96.  
  97. timeout_tv.tv_usec = 0;
  98. timeout_tv.tv_sec = TIMEOUT;
  99.  
  100. FD_ZERO(&readset);
  101. FD_SET(fd, &readset);
  102.  
  103. if (select(fd + 1, &readset, NULL, NULL, &timeout_tv) > 0) {
  104.  
  105. if (FD_ISSET(fd, &readset)) {
  106. rbytes = read(fd, &rbuff, 1);
  107. if (rbytes != 1)
  108. return -1;
  109. switch (rbuff) {
  110. case 0:
  111. /* Ground. */
  112. case 0xf0:
  113. /* No response. */
  114. rv = -1; break;
  115. default:
  116. /* Got a response */
  117. rv = 0;
  118. }
  119. }
  120. else {
  121. rv = -1;
  122. }
  123. }
  124. else {
  125. rv = -1; /* Timed out or interrupt. */
  126. }
  127.  
  128. term.c_cflag &= ~CSIZE | CS6;
  129. cfsetispeed(&term, B115200);
  130. cfsetospeed(&term, B115200);
  131.  
  132. tcsetattr(fd, TCSANOW, &term);
  133.  
  134. return rv;
  135. }
  136.  
  137. static unsigned char owWriteByte(int fd, unsigned char wbuff)
  138. {
  139. char buf[8];
  140. int wbytes;
  141. unsigned char rbuff, i;
  142. size_t remaining, rbytes;
  143. fd_set readset;
  144. struct timeval timeout_tv;
  145.  
  146. tcflush(fd, TCIOFLUSH);
  147.  
  148. for (i = 0; i < 8; i++)
  149. buf[i] = (wbuff & (1 << (i & 0x7))) ? 0xff : 0x00;
  150. wbytes = write(fd, buf, 8);
  151. if (wbytes != 8) {
  152. ut_errno = 9;
  153. return -1;
  154. }
  155.  
  156. timeout_tv.tv_usec = 0;
  157. timeout_tv.tv_sec = 1;
  158.  
  159. FD_ZERO(&readset);
  160. FD_SET(fd, &readset);
  161.  
  162. rbuff = 0;
  163. remaining = 8;
  164. while (remaining > 0) {
  165.  
  166. if (select(fd + 1, &readset, NULL, NULL, &timeout_tv) > 0) {
  167.  
  168. if (FD_ISSET(fd, &readset)) {
  169. rbytes = read(fd, &buf, remaining);
  170. for (i = 0; i < rbytes; i++) {
  171. rbuff >>= 1;
  172. rbuff |= (buf[i] & 0x01) ? 0x80 : 0x00;
  173. remaining--;
  174. }
  175. }
  176. else
  177. return 0xff;
  178. }
  179. else {
  180. /* At last timeout will terminate while-loop. */
  181. return 0xff;
  182. }
  183. }
  184. return rbuff;
  185. }
  186.  
  187. static unsigned char owReadByte(int fd)
  188. {
  189. return owWriteByte(fd, 0xff);
  190. }
  191.  
  192. /* *********** */
  193.  
  194. int warn_owWriteByte(int fd, unsigned char wbuff)
  195. {
  196. if (owWriteByte(fd, wbuff) != wbuff)
  197. return -1;
  198. return 0;
  199. }
  200.  
  201. static int file_exists(const char *filename)
  202. {
  203. struct stat st;
  204. return (stat(filename, &st) == 0);
  205. }
  206.  
  207. int serial_init(const char *serial_port)
  208. {
  209. int fd;
  210. struct termios term;
  211.  
  212. if (!file_exists(serial_port)) {
  213. ut_errno = 3;
  214. return -1;
  215. }
  216.  
  217. if (access(serial_port, R_OK|W_OK) < 0) {
  218. ut_errno = 4;
  219. return -1;
  220. }
  221.  
  222. fd = open(serial_port, O_RDWR);
  223. if (fd < 0) {
  224. ut_errno = 5;
  225. return -1;
  226. }
  227.  
  228. memset(&term, 0, sizeof(term));
  229.  
  230. term.c_cc[VMIN] = 1;
  231. term.c_cc[VTIME] = 0;
  232. term.c_cflag |= CS6 | CREAD | HUPCL | CLOCAL;
  233.  
  234. cfsetispeed(&term, B115200);
  235. cfsetospeed(&term, B115200);
  236.  
  237. if (tcsetattr(fd, TCSANOW, &term) < 0) {
  238. close(fd);
  239. ut_errno = 0;
  240. return -1;
  241. }
  242.  
  243. tcflush(fd, TCIOFLUSH);
  244.  
  245. return fd;
  246. }
  247.  
  248. int DS18B20_measure(int fd)
  249. {
  250. if (owReset(fd) < 0) {
  251. ut_errno = 6;
  252. return -1;
  253. }
  254. if (warn_owWriteByte(fd, 0xcc) < 0) {
  255. ut_errno = 8;
  256. return -1;
  257. }
  258. if (warn_owWriteByte(fd, 0x44) < 0) {
  259. ut_errno = 8;
  260. return -1;
  261. }
  262. return 0;
  263. }
  264.  
  265. int DS18B20_acquire(int fd)
  266. {
  267. time_t now;
  268. struct tm *timeptr;
  269. char timebuf[40];
  270. unsigned short T;
  271. float temperature;
  272. unsigned char i, crc, sp_sensor[DS18X20_SP_SIZE];
  273.  
  274. if (owReset(fd) < 0) {
  275. ut_errno = 6;
  276. return -1;
  277. }
  278. if (warn_owWriteByte(fd, 0xcc) < 0) {
  279. ut_errno = 8;
  280. return -1;
  281. }
  282. if (warn_owWriteByte(fd, 0xbe) < 0) {
  283. ut_errno = 8;
  284. return -1;
  285. }
  286.  
  287. for (i = 0; i < DS18X20_SP_SIZE; i++)
  288. sp_sensor[i] = owReadByte(fd);
  289.  
  290. if ((sp_sensor[4] & 0x9f) != 0x1f) {
  291. ut_errno = 6;
  292. return -1;
  293. }
  294.  
  295. crc = lsb_crc8(&sp_sensor[0], DS18X20_SP_SIZE - 1, DS18X20_GENERATOR);
  296. if (sp_sensor[DS18X20_SP_SIZE - 1] != crc) {
  297. ut_errno = 7;
  298. return -1;
  299. }
  300.  
  301. T = (sp_sensor[1] << 8) + (sp_sensor[0] & 0xff);
  302. if ((T >> 15) & 0x01) {
  303. T--;
  304. T ^= 0xffff;
  305. T *= -1;
  306. }
  307. temperature = (float)T / 16;
  308.  
  309. time(&now);
  310. timeptr = localtime(&now);
  311. strftime(timebuf, sizeof(timebuf), "%b %d %H:%M:%S", timeptr);
  312.  
  313. printf("%s Sensor C: %.2f\n", timebuf, temperature);
  314. return 0;
  315. }
  316.  
  317. int DS18B20_rom(int fd)
  318. {
  319. unsigned char i, crc, rom[DS18X20_ROM_SIZE];
  320.  
  321. if (owReset(fd) < 0) {
  322. ut_errno = 6;
  323. return -1;
  324. }
  325. if (warn_owWriteByte(fd, 0x33) < 0) {
  326. ut_errno = 8;
  327. return -1;
  328. }
  329.  
  330. for (i = 0; i < DS18X20_ROM_SIZE; i++)
  331. rom[i] = owReadByte(fd);
  332.  
  333. crc = lsb_crc8(&rom[0], DS18X20_ROM_SIZE - 1, DS18X20_GENERATOR);
  334. if (rom[DS18X20_ROM_SIZE - 1] != crc) {
  335. ut_errno = 7;
  336. return -1;
  337. }
  338.  
  339. printf("ROM: ");
  340. for (i = 0; i < DS18X20_ROM_SIZE; i++)
  341. printf("%02x", rom[i]);
  342. printf("\n");
  343. return 0;
  344. }
  345.  
  346. int main(int argc, char **argv)
  347. {
  348. struct timeval wait_tv;
  349. char c;
  350. int fd;
  351. char *serial_port = NULL;
  352. int verbose = 1;
  353. int rv = 0;
  354. int action = ACQUIRE_TEMP;
  355.  
  356. while ((c = getopt(argc, argv, "hrqs:")) != -1) {
  357. switch (c) {
  358. case 'h':
  359. action = HELP;
  360. break;
  361. case 'r':
  362. action = READ_ROM;
  363. break;
  364. case 'q':
  365. verbose = 0;
  366. break;
  367. case 's':
  368. serial_port = optarg;
  369. break;
  370. case '?':
  371. return -1;
  372. }
  373. }
  374.  
  375. if (action == HELP)
  376. verbose = 1;
  377.  
  378. if (verbose)
  379. printf("USB Thermometer CLI v1 Copyright 2017 jaka\n");
  380.  
  381. if (action == HELP) {
  382. printf("\t-r\tPrint ROM\n");
  383. printf("\t-q\tQuiet mode\n");
  384. printf("\t-s\tSet serial port\n");
  385. return 0;
  386. }
  387.  
  388. if (!serial_port)
  389. serial_port = "/dev/ttyUSB0";
  390. if (verbose)
  391. printf("Using serial port: %s\n", serial_port);
  392.  
  393. fd = serial_init(serial_port);
  394. if (fd > 0) {
  395.  
  396. switch (action) {
  397.  
  398. case ACQUIRE_TEMP:
  399.  
  400. if (DS18B20_measure(fd) < 0) {
  401. fprintf(stderr, "%s\n", ut_errmsg());
  402. close(fd);
  403. return -1;
  404. }
  405. wait_tv.tv_usec = 0;
  406. wait_tv.tv_sec = 1;
  407. if (verbose)
  408. printf("Waiting for response ...\n");
  409. select(0, NULL, NULL, NULL, &wait_tv);
  410. if (DS18B20_acquire(fd) < 0) {
  411. fprintf(stderr, "%s\n", ut_errmsg());
  412. rv = -1;
  413. }
  414. break;
  415.  
  416. case READ_ROM:
  417.  
  418. if (DS18B20_rom(fd) < 0) {
  419. fprintf(stderr, "%s\n", ut_errmsg());
  420. rv = -1;
  421. }
  422. break;
  423.  
  424. }
  425.  
  426. close(fd);
  427. return rv;
  428.  
  429. }
  430. else {
  431. fprintf(stderr, "%s\n", ut_errmsg());
  432. }
  433.  
  434. return -1;
  435. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement