Work to move dht userspace code to kernel module.

Sat, 23 Mar 2024 20:28:17 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 23 Mar 2024 20:28:17 +0100
changeset 647
fcd85176ea2e
parent 646
e3edc783006b
child 648
62c5ed1b9cfd

Work to move dht userspace code to kernel module.

thermferm/devices.c file | annotate | diff | comparison | revisions
--- 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<MAXTIMINGS; i++) {
-	    counter = 0;
-	    /* 10 uS */
-	    ts.tv_sec = 0;
-	    ts.tv_nsec = 10 * 1000;
-//	    nanosleep(&ts, NULL);
-	    delayMicroseconds(10);
-	    while (sizecvt(digitalRead(dht11_pin)) == laststate) {
-		counter++;
-		/* 1 uS */
-		ts.tv_sec = 0;
-		ts.tv_nsec = 1000;
-//		nanosleep(&ts, NULL);
-		delayMicroseconds(1);
-		if (counter == 255) {
-		    break;
-		}
-	    }
-	    laststate = sizecvt(digitalRead(dht11_pin));
-
-	    if (counter == 255) 
-		break;
-
-	    /*
-	     * ignore first 3 transitions
-	     */
-	    if ((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]);

mercurial