# HG changeset patch # User Michiel Broek # Date 1711383296 -3600 # Node ID 0b215e4b814e356d6f103b035f73d2e72d138963 # Parent 64cfc01ec02402815500ffe96c527acbee87bbd1 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. diff -r 64cfc01ec024 -r 0b215e4b814e thermferm/devices.c --- 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;