thermferm/devices.c

changeset 650
0b215e4b814e
parent 649
64cfc01ec024
child 652
16d3d4b58b5b
equal deleted inserted replaced
649:64cfc01ec024 650:0b215e4b814e
48 * temperature and humidity can simply read from the /sys filesystem. 48 * temperature and humidity can simply read from the /sys filesystem.
49 */ 49 */
50 int dht11_temperature = -1; 50 int dht11_temperature = -1;
51 int dht11_humidity = -1; 51 int dht11_humidity = -1;
52 int dht11_state = DEVPRESENT_UNDEF; 52 int dht11_state = DEVPRESENT_UNDEF;
53 time_t dht11_last = (time_t)0; 53 time_t dht11_next;
54 54
55 55
56 56
57 /* 57 /*
58 * DHT11 sensor read. 58 * DHT11 sensor read.
59 * Called at 30 seconds interval if all is well.
60 * If last read was an error, the interval is 2 seconds.
59 */ 61 */
60 void dht11Read(char *address) 62 void dht11Read(char *address)
61 { 63 {
62 int tries = 5, temp, hum; 64 int temp, hum;
63 int fd, rc, err; 65 int fd, rc, err;
64 char buffer[25], *dhtpath = NULL; 66 char buffer[25], *dhtpath = NULL;
65 67
66 while (tries) { 68 dht11_temperature = -1;
67 69 dht11_humidity = -1;
68 dht11_temperature = -1; 70 dht11_state = DEVPRESENT_UNDEF;
69 dht11_humidity = -1; 71 dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
70 dht11_state = DEVPRESENT_UNDEF; 72 dhtpath = xstrcat(dhtpath, address);
73 dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input");
74
75 fd = open(dhtpath, O_RDONLY);
76 if (fd < 0) {
77 /*
78 * The sensor is gone.
79 */
80 err = errno;
81 syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err));
82 free(dhtpath);
83 dht11_state = DEVPRESENT_NO;
84 return;
85 }
86
87 rc = read(fd, buffer, 25);
88 if (rc == -1) {
89 err = errno;
90 if (err == 110) {
91 dht11_state = DEVPRESENT_NO; /* Device is gone */
92 } else {
93 dht11_state = DEVPRESENT_ERROR;
94 }
95 syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err));
96 } else {
97 sscanf(buffer, "%d", &temp);
98 dht11_temperature = temp;
99 dht11_state = DEVPRESENT_YES;
100 }
101 close(fd);
102 free(dhtpath);
103 dhtpath = NULL;
104
105 /*
106 * Only read humidity if state is DEVPRESENT_YES
107 */
108 if (dht11_state == DEVPRESENT_YES) {
71 dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/"); 109 dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
72 dhtpath = xstrcat(dhtpath, address); 110 dhtpath = xstrcat(dhtpath, address);
73 dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input"); 111 dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input");
74 112
75 fd = open(dhtpath, O_RDONLY); 113 fd = open(dhtpath, O_RDONLY);
76 if (fd < 0) {
77 /*
78 * The sensor is gone.
79 */
80 err = errno;
81 syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err));
82 free(dhtpath);
83 dht11_state = DEVPRESENT_NO;
84 goto retry;
85 // break;
86 }
87 rc = read(fd, buffer, 25); 114 rc = read(fd, buffer, 25);
88 if (rc == -1) { 115 if (rc == -1) {
89 err = errno; 116 err = errno;
90 if (err == 110) { 117 if (err == 110) {
91 dht11_state = DEVPRESENT_NO; /* Device is gone */ 118 dht11_state = DEVPRESENT_NO;
92 break;
93 } else { 119 } else {
94 dht11_state = DEVPRESENT_ERROR; 120 dht11_state = DEVPRESENT_ERROR;
95 } 121 }
96 syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); 122 syslog(LOG_NOTICE, "DHT11 read humidity: %d %s", err, strerror(err));
97 dht11_temperature = -1; 123 dht11_temperature = -1; /* Make invalid */
98 } else { 124 } else {
99 sscanf(buffer, "%d", &temp); 125 sscanf(buffer, "%d", &hum);
100 dht11_temperature = temp; 126 dht11_humidity = hum;
101 dht11_state = DEVPRESENT_YES; 127 dht11_state = DEVPRESENT_YES;
102 } 128 }
103 close(fd); 129 close(fd);
104 free(dhtpath); 130 free(dhtpath);
105 dhtpath = NULL; 131 dhtpath = NULL;
106 132 }
107 /* 133
108 * Only read humidity if state is DEVPRESENT_YES 134 syslog(LOG_NOTICE, "dht11 t:%d h:%d state:%d", dht11_temperature, dht11_humidity, dht11_state);
109 */
110 if (dht11_state == DEVPRESENT_YES) {
111 dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
112 dhtpath = xstrcat(dhtpath, address);
113 dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input");
114
115 fd = open(dhtpath, O_RDONLY);
116 rc = read(fd, buffer, 25);
117 if (rc == -1) {
118 err = errno;
119 if (err == 110) {
120 dht11_state = DEVPRESENT_NO;
121 break;
122 } else {
123 dht11_state = DEVPRESENT_ERROR;
124 }
125 syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err));
126 dht11_humidity = -1;
127 } else {
128 sscanf(buffer, "%d", &hum);
129 dht11_humidity = hum;
130 dht11_state = DEVPRESENT_YES;
131 }
132 close(fd);
133 free(dhtpath);
134 dhtpath = NULL;
135 }
136
137 if (dht11_state == DEVPRESENT_YES) {
138 break;
139 }
140 retry:
141 if (tries > 0) {
142 tries--;
143 usleep(400000);
144 }
145 }
146
147 syslog(LOG_NOTICE, "dht11 t:%d h:%d tries:%d state:%d", dht11_temperature, dht11_humidity, 6-tries, dht11_state);
148 } 135 }
149 136
150 137
151 138
152 /* 139 /*
760 #ifdef HAVE_WIRINGPI_H 747 #ifdef HAVE_WIRINGPI_H
761 if ((rc = piHiPri(50))) 748 if ((rc = piHiPri(50)))
762 syslog(LOG_NOTICE, "my_devices_loop: piHiPri(50) rc=%d", rc); 749 syslog(LOG_NOTICE, "my_devices_loop: piHiPri(50) rc=%d", rc);
763 #endif 750 #endif
764 751
752 dht11_next = time(NULL);
753
765 /* 754 /*
766 * Set the temperature sensors to 12 bits resolution and write it in EEPROM 755 * Set the temperature sensors to 12 bits resolution and write it in EEPROM
767 */ 756 */
768 for (device = Config.devices; device; device = device->next) { 757 for (device = Config.devices; device; device = device->next) {
769 if ((device->type == DEVTYPE_W1) && 758 if ((device->type == DEVTYPE_W1) &&
930 break; 919 break;
931 920
932 case DEVTYPE_DHT: 921 case DEVTYPE_DHT:
933 /* 922 /*
934 * Don't read these to often, 2 seconds minimum delay. 923 * Don't read these to often, 2 seconds minimum delay.
935 * But we use 30 seconds interval. 924 * Delay 30 seconds if last update was successfull,
925 * else delay 2 seconds.
936 */ 926 */
937 now = time(NULL); 927 now = time(NULL);
938 if ((int)(now - dht11_last) > 30) { 928 if ((int)(now >= dht11_next)) {
939 if (device->subdevice == 0) { 929 if (device->subdevice == 0) {
940 /* Read once during subdevice 0 */ 930 /* Read once during subdevice 0 */
941 dht11Read(device->address); 931 dht11Read(device->address);
942 pthread_mutex_lock(&mutexes[LOCK_DEVICES]); 932 pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
943 device->present = dht11_state; 933 device->present = dht11_state;
945 device->value = dht11_temperature; 935 device->value = dht11_temperature;
946 device->timestamp = time(NULL); 936 device->timestamp = time(NULL);
947 } 937 }
948 pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); 938 pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
949 } else if (device->subdevice == 1) { 939 } else if (device->subdevice == 1) {
950 /* Data already present */ 940 /* Data already present, valid or not. */
951 pthread_mutex_lock(&mutexes[LOCK_DEVICES]); 941 pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
952 device->present = dht11_state; 942 device->present = dht11_state;
953 if (dht11_state == DEVPRESENT_YES) { 943 if (dht11_state == DEVPRESENT_YES) {
954 device->value = dht11_humidity; 944 device->value = dht11_humidity;
955 device->timestamp = time(NULL); 945 device->timestamp = time(NULL);
956 } 946 dht11_next = now + 29;
947 } else {
948 dht11_next = now + 1;
949 }
957 pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); 950 pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
958 dht11_last = now; /* Okay for a new reading. */
959 } 951 }
960 } 952 }
961 break; 953 break;
962 954
963 #ifdef HAVE_WIRINGPI_H 955 #ifdef HAVE_WIRINGPI_H

mercurial