# HG changeset patch # User Michiel Broek # Date 1711222097 -3600 # Node ID fcd85176ea2e0367c37ad9e266326487350ce963 # Parent e3edc783006b88a30794b636ac2177410987ce23 Work to move dht userspace code to kernel module. diff -r e3edc783006b -r fcd85176ea2e thermferm/devices.c --- a/thermferm/devices.c Sat Mar 23 16:01:24 2024 +0100 +++ b/thermferm/devices.c Sat Mar 23 20:28:17 2024 +0100 @@ -43,8 +43,6 @@ #endif -#ifdef HAVE_WIRINGPI_H - #define MAXTIMINGS 100 /* @@ -54,146 +52,80 @@ * that here. */ -int dht11_pin = -1; int dht11_temperature = -1; int dht11_humidity = -1; int dht11_valid = FALSE; +int dht11_present = FALSE; time_t dht11_last = (time_t)0; -static uint8_t sizecvt(const int read_value) { - /* - * digitalRead() and friends from wiringpi are defined as returning a value - * < 256. However, they are returned as int() types. This is a safety function - */ - if (read_value > 255 || read_value < 0) { - syslog(LOG_NOTICE, "invalid data from wiringPi library"); - } - - return (uint8_t)read_value; -} - - /* * DHT11 sensor read. */ -void dht11Read(void) { - int tries = 5; - unsigned short got_correct_data = 0; - struct timespec ts; +void dht11Read(void) +{ + int tries, temp, hum; + int fd, rc, err; + char buffer[25]; - if (dht11_pin == -1) - return; - - while (tries && !got_correct_data) { - uint8_t laststate = HIGH; - uint8_t counter = 0; - uint8_t j = 0, i = 0; - int dht11_dat[5] = {0,0,0,0,0}; + dht11_valid = FALSE; + dht11_present = FALSE; + dht11_temperature = -1; + dht11_humidity = -1; - /* - * Select output mode to send the start signal. - */ - pinMode(dht11_pin, OUTPUT); - digitalWrite(dht11_pin, HIGH); - /* 1 mSec */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, &ts); + /* + * Read DHT11 name. This only means the kernel module is loaded, + * it doesn't show if the chip is really present. + */ + fd = open("/sys/bus/iio/devices/iio:device0/name", O_RDONLY); + if (fd == -1) { + syslog(LOG_NOTICE, "no DHT11 device"); + return; + } - /* - * Low for at least 18 milliseconds - */ - digitalWrite(dht11_pin, LOW); - /* 20 mSec */ - ts.tv_sec = 0; - ts.tv_nsec = 20 * 1000000; - nanosleep(&ts, &ts); - digitalWrite(dht11_pin, HIGH); - pinMode(dht11_pin, INPUT); + memset(&buffer, 0, 25); + read(fd, buffer, 25); + close(fd); + buffer[strlen(buffer) - 1] = '\0'; + syslog(LOG_NOTICE, "dht11 name %s", buffer); + + tries = 5; + while (tries) { - /* - * Detect change and read data - */ - for (i=0; i= 4) && (i%2 == 0)) { - - // shove each bit into the storage bytes - dht11_dat[(int)((double)j/8)] <<= 1; - if (counter > 16) - dht11_dat[(int)((double)j/8)] |= 1; - j++; - } + fd = open("/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDONLY); + rc = read(fd, buffer, 25); + if (rc == -1) { + err = errno; + syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); + dht11_temperature = -1; + } else { + sscanf(buffer, "%d", &temp); + syslog(LOG_NOTICE, "read temp rc=%d %f", rc, temp / 1000.0); + dht11_temperature = temp; } + close(fd); - /* - * If there is no sensor, j = 0 - */ - if ((counter == 255) && (j == 0)) { - if (dht11_temperature != -1) { - syslog(LOG_NOTICE, "dht11 sensor disappeared"); - } else { - syslog(LOG_NOTICE, "dht11 sensor not present"); - } - dht11_temperature = -1; + fd = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDONLY); + rc = read(fd, buffer, 25); + if (rc == -1) { + err = errno; + syslog(LOG_NOTICE, "DHT11 read temperature: %d %s", err, strerror(err)); dht11_humidity = -1; - dht11_valid = FALSE; - return; - } + } else { + sscanf(buffer, "%d", &hum); + syslog(LOG_NOTICE, "read hum rc=%d %f", rc, hum / 1000.0); + dht11_humidity = hum; + } + close(fd); - /* - * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte - * print it out if data is good - */ - if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF))) { - got_correct_data = 1; - - int h = dht11_dat[0] + dht11_dat[1]; - int t = (dht11_dat[2] & 0x7F) + dht11_dat[3]; + tries = 0; + } - if ((dht11_dat[2] & 0x80) != 0) - t *= -1; - - dht11_temperature = t; - dht11_humidity = h; - dht11_valid = TRUE; - syslog(LOG_NOTICE, "dht11 t:%d h:%d tries:%d", t, h, 6-tries); - } else { - tries--; - if (tries == 0) - syslog(LOG_NOTICE, "dht11 data checksum was wrong 5 times"); - usleep(100000); - } - } + dht11_valid = TRUE; + syslog(LOG_NOTICE, "dht11 t:%d h:%d tries:%d", dht11_temperature, dht11_humidity, 6-tries); } -#endif /* @@ -452,6 +384,7 @@ { struct dirent *de; DIR *fd; + int fi; devices_list *device, *ndev; int found, subdevices, ival, i, rc = 0; char buf[40]; @@ -479,7 +412,12 @@ buf[2] = '\0'; sscanf(buf, "%02x", &ival); syslog(LOG_NOTICE, "Scan 1-wire %02x %d", ival, ival); - subdevices = 1; + subdevices = 0; + /* + * ival is zero when a ghost sensor is detected. + */ + if (ival > 0) + subdevices = 1; if (strcmp(buf, (char *)"29") == 0) subdevices = 8; if (strcmp(buf, (char *)"3a") == 0) @@ -545,6 +483,57 @@ /* * DHT11 as kernel module. */ + if ((fi = open((char *)"/sys/bus/iio/devices/iio:device0/name", O_RDONLY))) { + char buffer[25]; + + memset(&buffer, 0, 25); + read(fi, buffer, 25); + close(fi); + buffer[strlen(buffer) - 1] = '\0'; + + found = FALSE; + for (device = Config.devices; device; device = device->next) { + if (strcmp(device->address, buffer) == 0) { + found = TRUE; + break; + } + } + + if (found == FALSE) { + for (i = 0; i < 2; i++) { + ndev = (devices_list *)malloc(sizeof(devices_list)); + ndev->next = NULL; + ndev->uuid = malloc(37); + uuid_generate(uu); + uuid_unparse(uu, ndev->uuid); + ndev->type = DEVTYPE_DHT; + ndev->direction = DEVDIR_IN_ANALOG; + if (i == 0) + ndev->description = xstrcpy((char *)"DHT11 temperature sensor"); + else + ndev->description = xstrcpy((char *)"DHT11 humidity sensor"); + ndev->value = ndev->offset = ndev->inuse = 0; + ndev->present = DEVPRESENT_YES; + ndev->address = xstrcpy(buffer); + ndev->subdevice = i; + ndev->gpiopin = -1; + ndev->comment = xstrcpy((char *)"Auto detected device"); + ndev->timestamp = time(NULL); + + if (Config.devices == NULL) { + Config.devices = ndev; + } else { + for (device = Config.devices; device; device = device->next) { + if (device->next == NULL) { + device->next = ndev; + break; + } + } + } + rc++; + } + } + } #ifdef HAVE_WIRINGPI_H if (piBoardRev() == 2) { @@ -728,9 +717,7 @@ char *addr = NULL, line1[60], line2[60], *p = NULL; FILE *fp; int temp, rc; -#ifdef HAVE_WIRINGPI_H time_t now; -#endif my_devices_state = 1; syslog(LOG_NOTICE, "Thread my_devices_loop started"); @@ -907,7 +894,6 @@ break; -#ifdef HAVE_WIRINGPI_H case DEVTYPE_DHT: /* * Make sure we don't read the sensor within 2 seconds. @@ -917,11 +903,10 @@ if ((int)(now - dht11_last) > 30) { if (device->subdevice == 0) { /* Read once during subdevice 0 */ - dht11_pin = device->gpiopin; dht11Read(); pthread_mutex_lock(&mutexes[LOCK_DEVICES]); if (dht11_valid) { - device->value = dht11_temperature * 1000; + device->value = dht11_temperature; device->timestamp = time(NULL); device->present = DEVPRESENT_YES; } else { @@ -932,7 +917,7 @@ /* Data already present */ pthread_mutex_lock(&mutexes[LOCK_DEVICES]); if (dht11_valid) { - device->value = dht11_humidity * 1000; + device->value = dht11_humidity; device->timestamp = time(NULL); device->present = DEVPRESENT_YES; } else { @@ -944,6 +929,7 @@ } break; +#ifdef HAVE_WIRINGPI_H case DEVTYPE_GPIO: if (device->direction == DEVDIR_IN_BIN) { pthread_mutex_lock(&mutexes[LOCK_DEVICES]);