Brought the retry attempts to read the DHT11 sensors to the main devices loop. The actual read function is now very simple. Called every 30 seconds when all is well, or 2 seconds if something is wrong.

Mon, 25 Mar 2024 17:14:56 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 25 Mar 2024 17:14:56 +0100
changeset 650
0b215e4b814e
parent 649
64cfc01ec024
child 651
da166cb8470f

Brought the retry attempts to read the DHT11 sensors to the main devices loop. The actual read function is now very simple. Called every 30 seconds when all is well, or 2 seconds if something is wrong.

thermferm/devices.c file | annotate | diff | comparison | revisions
--- a/thermferm/devices.c	Mon Mar 25 11:44:45 2024 +0100
+++ b/thermferm/devices.c	Mon Mar 25 17:14:56 2024 +0100
@@ -50,101 +50,88 @@
 int             dht11_temperature = -1;
 int             dht11_humidity = -1;
 int		dht11_state = DEVPRESENT_UNDEF;
-time_t		dht11_last = (time_t)0;
+time_t		dht11_next;
 
 
 
 /*
  * DHT11 sensor read.
+ * Called at 30 seconds interval if all is well.
+ * If last read was an error, the interval is 2 seconds.
  */
 void dht11Read(char *address)
 {
-    int         	tries = 5, temp, hum;
-    int			fd, rc, err;
-    char		buffer[25], *dhtpath = NULL;
+    int        	temp, hum;
+    int		fd, rc, err;
+    char	buffer[25], *dhtpath = NULL;
+
+    dht11_temperature = -1;
+    dht11_humidity = -1;
+    dht11_state = DEVPRESENT_UNDEF;
+    dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
+    dhtpath = xstrcat(dhtpath, address);
+    dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input");
+
+    fd = open(dhtpath, O_RDONLY);
+    if (fd < 0) {
+	/*
+	 * The sensor is gone.
+	 */
+	err = errno;
+	syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err));
+	free(dhtpath);
+	dht11_state = DEVPRESENT_NO;
+	return;
+    }
 
-    while (tries) {
+    rc = read(fd, buffer, 25);
+    if (rc == -1) {
+	err = errno;
+	if (err == 110) {
+		dht11_state = DEVPRESENT_NO;	/* Device is gone */
+	} else {
+		dht11_state = DEVPRESENT_ERROR;
+	}
+	syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err));
+    } else {
+	sscanf(buffer, "%d", &temp);
+	dht11_temperature = temp;
+	dht11_state = DEVPRESENT_YES;
+    }
+    close(fd);
+    free(dhtpath);
+    dhtpath = NULL;
 
-	dht11_temperature = -1;
-	dht11_humidity = -1;
-	dht11_state = DEVPRESENT_UNDEF;
+    /*
+     * Only read humidity if state is DEVPRESENT_YES
+     */
+    if (dht11_state == DEVPRESENT_YES) {
 	dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
 	dhtpath = xstrcat(dhtpath, address);
-	dhtpath = xstrcat(dhtpath, (char *)"/in_temp_input");
+	dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input");
 
 	fd = open(dhtpath, O_RDONLY);
-	if (fd < 0) {
-	    /*
-	     * The sensor is gone.
-	     */
-	    err = errno;
-	    syslog(LOG_NOTICE, "DHT11 open temperature: %d %s", err, strerror(err));
-	    free(dhtpath);
-	    dht11_state = DEVPRESENT_NO;
-	    goto retry;
-//	    break;
-	}
 	rc = read(fd, buffer, 25);
 	if (rc == -1) {
 	    err = errno;
 	    if (err == 110) {
-		dht11_state = DEVPRESENT_NO;	/* Device is gone */
-		break;
+		    dht11_state = DEVPRESENT_NO;
 	    } else {
-		dht11_state = DEVPRESENT_ERROR;
+		    dht11_state = DEVPRESENT_ERROR;
 	    }
-	    syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err));
-	    dht11_temperature = -1;
+	    syslog(LOG_NOTICE, "DHT11 read humidity: %d %s", err, strerror(err));
+	    dht11_temperature = -1;	/* Make invalid	*/
 	} else {
-	    sscanf(buffer, "%d", &temp);
-	    dht11_temperature = temp;
+	    sscanf(buffer, "%d", &hum);
+	    dht11_humidity = hum;
 	    dht11_state = DEVPRESENT_YES;
 	}
 	close(fd);
 	free(dhtpath);
 	dhtpath = NULL;
-
-	/*
-	 * Only read humidity if state is DEVPRESENT_YES
-	 */
-	if (dht11_state == DEVPRESENT_YES) {
-	    dhtpath = xstrcpy((char *)"/sys/bus/iio/devices/");
-	    dhtpath = xstrcat(dhtpath, address);
-	    dhtpath = xstrcat(dhtpath, (char *)"/in_humidityrelative_input");
-
-	    fd = open(dhtpath, O_RDONLY);
-	    rc = read(fd, buffer, 25);
-	    if (rc == -1) {
-	    	err = errno;
-		if (err == 110) {
-		    dht11_state = DEVPRESENT_NO;
-		    break;
-		} else {
-		    dht11_state = DEVPRESENT_ERROR;
-		}
-	    	syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err));
-	    	dht11_humidity = -1;
-	    } else {
-	    	sscanf(buffer, "%d", &hum);
-	    	dht11_humidity = hum;
-		dht11_state = DEVPRESENT_YES;
-	    }
-	    close(fd);
-	    free(dhtpath);
-	    dhtpath = NULL;
-	}
-
-	if (dht11_state == DEVPRESENT_YES) {
-	    break;
-	}
-retry:
-	if (tries > 0) {
-	    tries--;
-	    usleep(400000);
-	}
     }
 
-    syslog(LOG_NOTICE, "dht11 t:%d h:%d tries:%d state:%d", dht11_temperature, dht11_humidity, 6-tries, dht11_state);
+    syslog(LOG_NOTICE, "dht11 t:%d h:%d state:%d", dht11_temperature, dht11_humidity, dht11_state);
 }
 
 
@@ -762,6 +749,8 @@
     	syslog(LOG_NOTICE, "my_devices_loop: piHiPri(50) rc=%d", rc);
 #endif
 
+    dht11_next = time(NULL);
+
     /*
      * Set the temperature sensors to 12 bits resolution and write it in EEPROM
      */
@@ -932,10 +921,11 @@
 		case DEVTYPE_DHT:
 			/*
 			 * Don't read these to often, 2 seconds minimum delay.
-			 * But we use 30 seconds interval.
+			 * Delay 30 seconds if last update was successfull,
+			 * else delay 2 seconds.
 			 */
 			now = time(NULL);
-			if ((int)(now - dht11_last) > 30) {
+			if ((int)(now >= dht11_next)) {
 			    if (device->subdevice == 0) {
 				/* Read once during subdevice 0 */
 			    	dht11Read(device->address);
@@ -947,15 +937,17 @@
 			    	}
 				pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
 			    } else if (device->subdevice == 1) {
-				/* Data already present */
+				/* Data already present, valid or not. */
 				pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
 				device->present = dht11_state;
 			    	if (dht11_state == DEVPRESENT_YES) {
 				    device->value = dht11_humidity;
 				    device->timestamp = time(NULL);
-			    	}
+				    dht11_next = now + 29;
+			    	} else {
+				    dht11_next = now + 1;
+				}
 				pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
-				dht11_last = now;	/* Okay for a new reading. */
 			    }
 			}
 			break;

mercurial