ds18b20.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * ds18b20.c:
  3. * Extend wiringPi with the DS18B20 1-Wire temperature sensor.
  4. * This is used in the Pi Weather Station and many other places.
  5. * Copyright (c) 2016 Gordon Henderson
  6. ***********************************************************************
  7. * This file is part of wiringPi:
  8. * https://projects.drogon.net/raspberry-pi/wiringpi/
  9. *
  10. * wiringPi is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * wiringPi is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with wiringPi.
  22. * If not, see <http://www.gnu.org/licenses/>.
  23. ***********************************************************************
  24. */
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29. #include <stdint.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <malloc.h>
  33. #include <ctype.h>
  34. #include "wiringPi.h"
  35. #include "ds18b20.h"
  36. #define W1_PREFIX "/sys/bus/w1/devices/28-"
  37. #define W1_POSTFIX "/w1_slave"
  38. /*
  39. * myAnalogRead:
  40. *********************************************************************************
  41. */
  42. static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
  43. {
  44. int chan = pin - node->pinBase ;
  45. int fd = node->fd ;
  46. char buffer [4096] ;
  47. char *p ;
  48. int temp, sign ;
  49. if (chan != 0)
  50. return -9999 ;
  51. // Rewind the file - we're keeping it open to keep things going
  52. // smoothly
  53. lseek (fd, 0, SEEK_SET) ;
  54. // Read the file - we know it's only a couple of lines, so this ought to be
  55. // more than enough
  56. if (read (fd, buffer, 4096) <= 0) // Read nothing, or it failed in some odd way
  57. return -9998 ;
  58. // Look for YES, then t=
  59. if (strstr (buffer, "YES") == NULL)
  60. return -9997 ;
  61. if ((p = strstr (buffer, "t=")) == NULL)
  62. return -9996 ;
  63. // p points to the 't', so we skip over it...
  64. p += 2 ;
  65. // and extract the number
  66. // (without caring about overflow)
  67. if (*p == '-') // Negative number?
  68. {
  69. sign = -1 ;
  70. ++p ;
  71. }
  72. else
  73. sign = 1 ;
  74. temp = 0 ;
  75. while (isdigit (*p))
  76. {
  77. temp = temp * 10 + (*p - '0') ;
  78. ++p ;
  79. }
  80. // We know it returns temp * 1000, but we only really want temp * 10, so
  81. // do a bit of rounding...
  82. temp = (temp + 50) / 100 ;
  83. return temp * sign ;
  84. }
  85. /*
  86. * ds18b20Setup:
  87. * Create a new instance of a DS18B20 temperature sensor.
  88. *********************************************************************************
  89. */
  90. int ds18b20Setup (const int pinBase, const char *deviceId)
  91. {
  92. int fd ;
  93. struct wiringPiNodeStruct *node ;
  94. char *fileName ;
  95. // Allocate space for the filename
  96. if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL)
  97. return FALSE ;
  98. sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ;
  99. fd = open (fileName, O_RDONLY) ;
  100. free (fileName) ;
  101. if (fd < 0)
  102. return FALSE ;
  103. // We'll keep the file open, to make access a little faster
  104. // although it's very slow reading these things anyway )-:
  105. node = wiringPiNewNode (pinBase, 1) ;
  106. node->fd = fd ;
  107. node->analogRead = myAnalogRead ;
  108. return TRUE ;
  109. }