Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste


C - Programmierung am Raspberry  Schaltpläne und Bauteilbeschreibungen  Adapterkabel  Mechanik  EDV-Literatur deutsch 



    FIAN Österreich     Marktplatz Natur    
    Bäckerei Freitag

c_1wiretemp

Temperatur auslesen

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.

1-Wire am RPi aktiviern

CC BY-SA


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.

C Programm

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.

Das Programm Compilieren

 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:~ $

Die neuen Funktionen im Listing

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

c_1wiretemp.txt · Zuletzt geändert: 2020/10/18 18:24 von administrator