Gordons Projects

--> Projects Top-Level GIT

Updating for various stuff and bugs. CM3+ and PiA3+
[wiringPi] / wiringPi / ds18b20.c
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
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29
30 #include <unistd.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <malloc.h>
35 #include <ctype.h>
36
37 #include "wiringPi.h"
38
39 #include "ds18b20.h"
40
41 #define W1_PREFIX       "/sys/bus/w1/devices/28-"
42 #define W1_POSTFIX      "/w1_slave"
43
44
45 /*
46  * myAnalogRead:
47  *********************************************************************************
48  */
49
50 static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
51 {
52   int  chan = pin - node->pinBase ;
53   int  fd = node->fd ;
54   char buffer [4096] ;
55   char *p ;
56   int  temp, sign ;
57
58   if (chan != 0)
59     return -9999 ;
60
61 // Rewind the file - we're keeping it open to keep things going
62 //      smoothly
63
64   lseek (fd, 0, SEEK_SET) ;
65
66 // Read the file - we know it's only a couple of lines, so this ought to be
67 //      more than enough
68
69   if (read (fd, buffer, 4096) <= 0)     // Read nothing, or it failed in some odd way
70     return -9998 ;
71
72 // Look for YES, then t=
73
74   if (strstr (buffer, "YES") == NULL)
75     return -9997 ;
76
77   if ((p = strstr (buffer, "t=")) == NULL)
78     return -9996 ;
79
80 // p points to the 't', so we skip over it...
81
82   p += 2 ;
83
84 // and extract the number
85 //      (without caring about overflow)
86
87
88   if (*p == '-')        // Negative number?
89   {
90     sign = -1 ;
91     ++p ;
92   }
93   else
94     sign = 1 ;
95
96   temp = 0 ;
97   while (isdigit (*p))
98   {
99     temp = temp * 10 + (*p - '0') ;
100     ++p ;
101   }
102
103 // We know it returns temp * 1000, but we only really want temp * 10, so
104 //      do a bit of rounding...
105
106   temp = (temp + 50) / 100 ;
107   return temp * sign ;
108 }
109
110
111 /*
112  * ds18b20Setup:
113  *      Create a new instance of a DS18B20 temperature sensor.
114  *********************************************************************************
115  */
116
117 int ds18b20Setup (const int pinBase, const char *deviceId)
118 {
119   int fd ;
120   struct wiringPiNodeStruct *node ;
121   char *fileName ;
122
123 // Allocate space for the filename
124
125   if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL)
126     return FALSE ;
127
128   sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ;
129
130   fd = open (fileName, O_RDONLY) ;
131
132   free (fileName) ;
133
134   if (fd < 0)
135     return FALSE ;
136
137 // We'll keep the file open, to make access a little faster
138 //      although it's very slow reading these things anyway )-:
139
140   node = wiringPiNewNode (pinBase, 1) ;
141
142   node->fd         = fd ;
143   node->analogRead = myAnalogRead ;
144
145   return TRUE ;
146 }