Letztes Update 2020/10/18 17:10
Mit diesem Programm wird die Temperatur eines am RPI angeschlossenen 18B20 ausgelesen und am Bildschirm als Analogwert mit zwei Nachkommastellen angezeigt. Dieses Programm soll (kann) als Grundlage dienen, um bei zu hoher Temperatur einen Lüfter einzuschalten.
Am RPi 1-Wire einschalten. Dazu raspi-config starten, Punkt5 - Interfacing Options / Punkt P7 - 1-Wire / Enable/Disable one-wire interface
, und die 1-Wire Funktion aktivieren.
Der 18B20
ist am GPIO Port 04 (Pin7) angeschlossen. Das ist meines Wissens der einzige Port, an dem das 1-Wire Protokoll funktioniert.
Das 1-Wire Protokoll aktivieren:
sudo modprobe w1-gpio sudo modprobe w1-therm
Die config.txt wird geöffnet:
sudo nano /boot/config.txt
und am Ende der Datei wird eine Zeile hinzugefügt:
dtoverlay=w1-gpio,gpioin=4,pullup=on
Durch die Eingabe von
lsmod
wird nun überprüft, ob die Module aufgelistet sind. Als Beispiel:
w1_therm 24576 0 w1_gpio 16384 0 wire 40960 2 w1_gpio,w1_therm
Falls die Module nicht aufgelistet sind, kontrollieren, ob der 18B20 an GPIO04 angeschlossen ist.
Damit beim Start die beiden Module geladen werden, diese in die Datei /etc/modules
eintragen:
Datei öffnen:
sudo nano /etc/modules
und am Ende zwei Zeilen einfügen:
w1_gpio w1_therm
Um den Sensor zu identifizieren, muss seine ID herausgefunden werden. Dazu in das devices
-Verzeichnis wechseln:
cd /sys/bus/w1/devices/ ls
Je nach Sensortype beginnen die entsprechenden Dateien mit 10-, 28- oder ähnlich.
Hier lautet die ID 28-000004d90298
.
pi@rpi:/sys/bus/w1/devices $ cd /sys/bus/w1/devices/ pi@rpi:/sys/bus/w1/devices $ ls 28-000004d90298 w1_bus_master1 pi@rpi:/sys/bus/w1/devices $
Zur Kontrolle, ob auf der Hardwareseite alles funktioniert, an der Konsole folgende Eingabe vornehmen:
cat /sys/bus/w1/devices/28-000004d90298/w1_slave
In der Ausgabe sehen wir in der zweiten Zeile in den letzten 5 Stellen die Temperatur in m°C (Milligrad Celsius):
pi@rpi:~ $ cat /sys/bus/w1/devices/28-000004d90298/w1_slave b9 01 4b 46 7f ff 07 10 d1 : crc=d1 YES b9 01 4b 46 7f ff 07 10 d1 t=27562 pi@rpi:~ $
Der Wert durch 1000 geteilt ergibt die Temperatur von 27.562°C.
Zur Anzeige der Temperatur wird nun eine C Routine geschrieben. Dieses Programm soll in weiterer Folge dazu dienen, bei einer zu hohen Temperatur einen Gehäuselüfter einzuschalten.
An der Konsole starten wir den Editor Nano:
sudo nano readtemp.c
Hier geben wir folgendes ein:
/* readtemp.c Die Temperatur aus der Datei "/sys/bus/w1/devices/28-000004d90298/w1_slave" lesen und als Analogwert mit 2 Nachkommastellen am Bildschirm ausgeben. EDE 18.10.2020 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define ZEILENLAENGE 256 int main() { char* device_id = "/sys/bus/w1/devices/28-000004d90298/w1_slave"; // Pfad und S/N 18B20 char* line = malloc(sizeof(char)*ZEILENLAENGE); char string[40]; char *ptr; char tstring[10]; FILE *fp; int i, data, x; double temperatur; // double fan_on = 35.00; // double fan_off = 30.00; fp = fopen( device_id, "r"); //Temporäre Temperatur-Logdatei zum lesen öffnen if(fp == NULL) { printf("Datei nicht vorhanden oder kann nicht geöffnet werden.\n"); return EXIT_FAILURE; } else { for(i=0; i<2; i++) // Zur 2. Zeile gehen { fgets(line, ZEILENLAENGE, fp); } // printf("%s", line); // debug } ptr = strtok(line, "="); // String teilen while( ptr ) { ptr = strtok( NULL, "="); if ( ptr ) { // Gültiger Wert // printf("\n%s\n", ptr); // debug strcpy (tstring, ptr); // printf("tsring = %s\n", tstring); // debug } } temperatur = atof(tstring); printf("Gehäusetemperatur = %.2f°C\n", temperatur/1000); return EXIT_SUCCESS; }
mit Strg+o
den Text speichern und mit Strg+x
den Editor verlassen.
gcc -o readtemp readtemp.c
Ausgeführt wird das Programm, indem folgendes eingegeben wird:
./readtemp
Die Ausgaben an der Konsole könnten dann so aussehen:
pi@rpi:~ $ ./readtemp Gehäusetemperatur = 27.56°C pi@rpi:~ $
malloc()
malloc() reserviert einen Speicherblock in der angegebenen Größe. Der Zeiger auf das erste Byte wird zurückgegeben oder NULL, falls kein Speicher alloziiert werden konnte. Beispiele auf proggen.org
#define var wert
Die Variable var
bekommt einen Wert wert
zugewiesen.
char string[40]
Die Variable string
wird als char
mit einer Länge von 40 Stellen definiert.
strtok()
Zerlegen von Strings anhand eines Trennzeichens. Beispiele auf proggen.org
strcpy()
strcpy() kopiert einen String. Beispiele auf proggen.org
atof()
atof() konvertiert einen ASCII-String in eine Fließkommazahl (ASCII to floatingpoint - atof). Beispiele auf proggen.org