Temperaturen am PC auslesen

  • Hi Tom,
    Wie viele Messungen/Zeiteinheit gemacht werden ist meinem Darstellungsmodul egal.
    Der Temperaturbereich (z.B. -10 - +50 / -30 - +90/ ...) kann auch frei vorgegeben werden.
    Bei Verwendung meines "Temperaturmessung mit Linux"-Projektes kann man frei vorgeben, wann Messungen erfolgen sollen (auch nicht-linear).


    Man gibt den Start- und Endtag des Bereiches an, den man sehen möchte.
    Es holt sich dann alle nötigen Daten und baut die Graphen auf.


    Damit die Darstellung einigermaßen einheitlich bleibt, habe ich mich entschlossen, das es bei Zeiträumen <= 1Tag die Tagesdarstellung, <=1 Woche die Wochendarstellung usw. verwendet und nicht genau den definierten Bereich.
    Kann aber den Wünschen der Mehrheit angepasst werden.


    Ich baue das Modul mit den in der ersten Version gesammelten Erfahrungen gerade komplett neu zusammen. Dann sollte auch der Quellcode wesentlich überschaubarer sein :)


    Habt noch ein wenig Geduld, ich denke, in ca. einer Woche habe ich das Ding so, wie es ein soll.


    Anbei noch die Skizzen der 4 Ansichten:


    WePP

  • Hallo anbei das extrakt zur programmierung der seriellen Schnittstelle eines
    Linux PC´s.


    Da dieses eine Spezialanwendung ist sollte es sicherlich zuvor auf Deine Belange modifiziert werden.


    Aber es gibt sicherlich einen Eindruch und beinhaltet alles was zur Programmierung der seriellen Schnittstelle benötigt wird.


    Wenn Du willst kann ich Dir auch eine einfachers Programm zukommen lassen. Dabei mußt Du dann aber im Linux die serielle Schnittstelle konfigurieren (Baudrate etc.) und dann mittels meines Programmes darauf zugreifen.


    Viel Spaß
    Andreas


    /// Includes


    #include <stdio.h>
    #ifdef __linux__


    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <termios.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>


    #else /* __linux__ */


    #include <windows.h>


    #endif /* __linux__ */


    // Defines


    #define ESC_TMOUT 1
    #define ESC_STRING 2
    #define ESC_ERROR 3
    #define ESC_OVERRUN 4


    #ifdef __linux__
    #define DEV_COM1 "/dev/ttySA0"
    #endif /* __linux__ */


    // Function prototypes


    #ifndef __linux__
    void CounterThread (void); // CounterThread
    #endif /* !__linux__ */
    int main (int, char **); // The one and only main function


    // Any other globals


    int iCount; // Increment by CounterThread...


    #ifdef __linux__


    // Help-function


    char * strupr (char * p)
    {
    char * begin = p;
    while (*p) {
    if (*p >= 'a' && *p <= 'z')
    *p -= 'a'-'A';
    p++;
    }
    return (begin);
    }
    #else /* __linux__ */


    ////////////////////////////////////////////////////////////////////////////////
    // CounterThread


    void CounterThread (void)
    {
    // Update counter and sleep for the next 100 msec...


    while (1) {
    iCount++;
    Sleep (100);
    }
    }
    #endif /* __linux__ */


    ////////////////////////////////////////////////////////////////////////////////
    // main


    int main (int argc, char* argv[])
    {
    #ifdef __linux__
    int hComPort; // COM port handle
    int lCount; // Contains TX byte count after return
    int value; // Argument for ioctrl
    struct termios termios; // New port setting
    const char *envr; // EnvironmentVariable
    #else /* __linux__ */
    HANDLE hComPort, // COM port handle
    hThread; // CounterThread handle
    DCB dcb; // COM port device control
    COMMTIMEOUTS timeouts; // COM port timeout values
    DWORD lCount, // Contains TX byte count after return
    lThreadID; // CounterThread ID
    #endif /* __linux__ */
    char szBuffer[128]; // Buffer for TX and RX
    int iRet, iLoop, iEscCode = -1,
    i,
    iCharCount;


    // This is a CGI program...


    printf ("Content-type: text/plain\r\n");
    printf ("\r\n");


    // Check QUERY_STRING for parameter...


    #ifdef __linux__
    envr = getenv("QUERY_STRING");
    if (!envr) {
    printf ("Error. No Parameter (QUERY_STRING).\r\n");
    return (0);
    }
    strncpy (szBuffer, envr, sizeof (szBuffer)-1);
    #else /* __linux__ */


    szBuffer[0]= 0x00;
    GetEnvironmentVariable ("QUERY_STRING", szBuffer, 128);
    if (szBuffer[0] == 0x00) {
    printf ("Error. No Parameter (QUERY_STRING).\r\n");
    return (0);
    }
    #endif /* __linux__ */


    #ifndef __linux__
    // Create background counter thread...


    hThread= CreateThread (0, 0, (LPTHREAD_START_ROUTINE) CounterThread,
    0, 0, &lThreadID);


    // Check for errors...


    if (hThread == 0) {
    printf ("Error. Can not create thread.\r\n");
    return (0);
    }
    #endif /* !__linux__ */


    // Open COM1 port...


    #ifdef __linux__
    hComPort = open (DEV_COM1, O_RDWR | O_NONBLOCK);


    // Check for errors...


    if (hComPort == -1) {
    printf ("Error. Can not open COM1 serial port.\r\n");
    return (0);
    }


    // Get the current COM1 settings...


    tcgetattr (hComPort, &termios); // get attribute
    cfsetospeed (&termios, B19200);
    cfmakeraw (&termios);
    tcsetattr (hComPort, TCSANOW, &termios); // set attribute


    // Set DTR and RTS activ...


    value = TIOCM_DTR | TIOCM_RTS;
    if (ioctl (hComPort, TIOCMBIS, &value)) {
    printf ("Can't set COM1 DTR & RTS\n");
    return (0);
    } /* endif ioctl */


    #else /* __linux__ */
    hComPort= CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    // Check for errors...


    if (hComPort == INVALID_HANDLE_VALUE) {
    printf ("Error. Can not open COM1 serial port.\r\n");
    return (0);
    }


    // Get the current COM1 settings...


    GetCommState (hComPort, &dcb);


    // Set COM1 to 19.200 bps, 8 data bits, 1 stop bit, no parity...


    dcb.BaudRate= 19200;
    dcb.ByteSize= 8;
    dcb.Parity= NOPARITY;
    dcb.StopBits= ONESTOPBIT;
    SetCommState (hComPort, &dcb);


    // Set COM1 timeouts...


    timeouts.ReadIntervalTimeout= MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier= 0;
    timeouts.ReadTotalTimeoutConstant= 0;
    timeouts.WriteTotalTimeoutMultiplier= 0;
    timeouts.WriteTotalTimeoutConstant= 0;
    SetCommTimeouts (hComPort, &timeouts);


    // Set DTR and RTS activ...


    EscapeCommFunction (hComPort, SETDTR);
    EscapeCommFunction (hComPort, SETRTS);


    #endif /* __linux__ */
    // Setup request token, TX this message...


    printf ("COM1: Tx Request Token: \"%s\\r\"\r\n", szBuffer);
    strcat (szBuffer, "\r");
    #ifdef __linux__
    // flushes data received but not read.
    tcflush (hComPort, TCIFLUSH);


    lCount= write (hComPort, szBuffer, strlen (szBuffer));
    if (lCount == strlen (szBuffer))
    iRet= 1; /* OK */
    else
    iRet= 0; /* Fail */


    // Send all buffered chars


    tcdrain (hComPort);
    #else /* __linux__ */
    iRet= WriteFile (hComPort, szBuffer, strlen (szBuffer), &lCount, 0);
    #endif /* __linux__ */


    // Check for errors...


    if (!iRet) {
    printf ("Error. Can not TX request token (COM1 TX ERROR).\r\n");


    #ifdef __linux__
    // Set DTR and RTS deactiv...
    value = TIOCM_DTR | TIOCM_RTS;
    if (ioctl (hComPort, TIOCMBIC, &value)) {
    printf ("Can't clear COM1 DTR & RTS\n");
    } /* endif ioctl */


    // Close COM1 port and exit program...


    close (hComPort);
    #else /* __linux__ */


    // Set DTR and RTS deactiv...


    EscapeCommFunction (hComPort, CLRDTR);
    EscapeCommFunction (hComPort, CLRRTS);


    // Close COM1 port and exit program...


    CloseHandle (hComPort);
    #endif /* __linux__ */


    return (0);
    }


    #ifdef __linux__


    // Send all buffered chars


    tcdrain (hComPort);


    // Flushes both data received but not read, and data written but not transmitted.


    #else /* __linux__ */
    PurgeComm (hComPort, PURGE_RXCLEAR); // Clear COM1 RX buffer
    #endif /* __linux__ */


    // Wait in loop for response token, RX error or timeout...


    iLoop= 1;
    iCount= 0; // Increment by CounterThread
    iCharCount= 0;
    while (iLoop) {


    // RX response token, update total char counter...


    #ifdef __linux__
    lCount = 0;
    iRet= read (hComPort, &szBuffer[iCharCount], sizeof (szBuffer)-iCharCount);
    #if 0


    // Full trace


    printf ("iRet=%d [%s] ", iRet, &szBuffer[iCharCount]); fflush (stdout);
    #endif
    if (iRet >= 0) {
    /* Normal. No Errors */
    lCount= iRet;
    iRet = 1;
    } else {

    // Normal, no chars (Timeout). Wait 35*100ms

    usleep (100000);
    iCount++;
    lCount= 0;
    iRet = 1;
    }


    #else /* __linux__ */
    iRet= ReadFile (hComPort, &szBuffer[iCharCount], 128, &lCount, 0);
    #endif /* __linux__ */
    iCharCount += (int) lCount;


    // Check for RX errors...

    if (!iRet) {
    iLoop= 0;
    iEscCode= ESC_ERROR;
    }


    // Check for timeout...


    if (iCount > 35) {
    iLoop= 0;
    iEscCode= ESC_TMOUT;
    }


    // Check for RX buffer overrun...


    if (iCharCount > 128-1) {
    iLoop= 0;
    iEscCode= ESC_OVERRUN;
    }


    // Check for response token end char. Windows received '\r'.
    // Linux received '\n'


    i = szBuffer[iCharCount-1] & 0x7f;
    if (i == '\r' || i == '\n') {
    iLoop= 0;
    iEscCode= ESC_STRING;
    szBuffer[iCharCount-1]= 0x00;
    strupr (szBuffer);
    }
    }

    // Check loop exit condition...


    if (iEscCode == ESC_TMOUT)
    printf ("Error. Can not RX response token (RX TIMEOUT)\r\n");


    if (iEscCode == ESC_ERROR)
    printf ("Error. Can not RX response token (RX ERROR)\r\n");


    if (iEscCode == ESC_OVERRUN)
    printf ("Error. Can not RX response token (RX BUFFER OVERRUN)\r\n");

    if (iEscCode == ESC_STRING)
    printf ("RX Response Token. %s.\r\n", szBuffer);


    #ifdef __linux__


    // Set DTR and RTS deactiv...


    value = TIOCM_DTR | TIOCM_RTS;
    if (ioctl (hComPort, TIOCMBIC, &value)) {
    printf ("Can't clear COM1 DTR & RTS\n");
    } /* endif ioctl */


    // Close COM1 port and exit program...


    close (hComPort);
    #else /* __linux__ */


    // Set DTR and RTS deactiv...


    EscapeCommFunction (hComPort, CLRDTR);
    EscapeCommFunction (hComPort, CLRRTS);


    // Close COM1 port and exit program...


    CloseHandle (hComPort);
    #endif /* __linux__ */
    return (1);
    }

  • Hallo miteinander,


    das hört sich alles klasse an - aber was macht man wenn man die Daten des Dachses haben will und kein Linux - AVR - DNP - XYZ kann??


    Gibt es sowas auch für Nichtcomputerspezialisten zu bezahlbaren Preisen zu kaufen? bzw. ist beim Dachs (ich bekomm meinen erst nächste Woche - und er steht nicht bei mir im Keller sondern ca. 5km weg) nicht ein Modem dabei, das man anrufen kann und die Daten abrufen??



    Grüße Guido

  • Hallo Andreas,


    ist das der Code den Du auf dem emb. Linux Board im Moment am laufen hast?


    Gruss
    Werner

    -- Die Sonne ist die Quelle unserer Energie, die es richtig anzuzapfen gilt ! ---
    „Nicht alles, was zählt, ist zählbar!“ „Nicht alles, was zählbar ist, zählt!“ Albert Einstein

  • gab
    Sieh dir die OnlineLösungen von Tom und mir an.
    Allerdings sind die momentan nur für MSR1.
    Beim MSR2 fehlen momentan noch die Unterlagen.


    Diese Lösung läuft momentan auf Windows, dazu kommt
    Software IPSYMCON ca. 99 Euro
    ein serielles Kabel


    Eine Internetflatrate sollte vorhanden sein, sonst muß man sich immer einwählen.
    Auf dem Rechner kannst du dann auch die Software von Senertec installieren um einstellungen zu verändern, dazu muss dan kurz das erfassen vin IPSYMCON gestoppt werden.


    Erweiterungen die geplant sind, Wärmemengenzähler von Allmess per M-Bus einzubinden, ebenso die Liefer- und Bezugszähler Strom.
    Ferner kannst du endlos viele Temperaturmessstellen einbinden.
    Was das alles kostet ist noch nich so ganz sicher, für M-Bus gibts da fertige Hardware für ca. 300Euro netto, Selbstbau ist in der mache.
    Temperaturen werden wohl per 1-Wire gelöst, Kostenpunkt ca. 100 Euro + 5 Euro je Meßstelle.


    Alles beides jeweils zuzüglich Kable für die Anbindung.


    Bernd

    Wer einmal fragt, wirkt für einen Moment dumm, wer es nie tut, bleib es sein Leben lang

    Einmal editiert, zuletzt von Bernd der Dachsausbeuter ()

  • Hallo Spornrad,


    das ist ein Beispiel für WePP um seine serielle Schnittstelle über Linux anzusprechen.


    Meine derzeitigen Code für den Dachs möchte ich hier nicht herausgeben, da ich nicht hinterher für irgendwelche Fehler im Programm oder Umprogrammierungen/Portierungen im Dachs verantwortlich gemacht werden will.


    Es sollte hier vermerkt werden, daß es anscheinend auch schon Dachser gab, die etwas programmiert hatten und dann wahrscheinlich den Datenbereich des Dachs ungewollterweise überschrieben habe und dann
    eine neue Steuerung brauchten. Da wir nichts über Memory Layout oder EEPROM oder non-volatile Speicher kennen wäre ich prinizipell vorsichtig. Wir leben ja von den Findings und der Zuverlässigkeit aller Bastler hier im Netz.


    Auch ist die H/W eine von mir angefertigte wire wrap lösung die im auch im addressbereich bzgl. UARTS sicherlich mit den kommerziellen Boards nichts zu tun hat.


    Ich habe mir aber ein komerzielles Board ausgesucht welches ich mit S/W bestücke und dann zum laufen bringe. Ich halte Euch auf dem laufenden. Jedoch bin ich beruflich sehr im Druck so daß dieses 2te Priorität hat.
    Gruß Andreas

  • gab


    Ruuuuhig, Brauner!
    =)


    Der Hardwareteil der Doku ist fertig, jetzt folgt noch der Config-Teil für Linux.
    Und das dauert ein wenig damit, auch Leute wie du ohne große Programmier- oder Systemerfahrung das einrichten können. :]


    Viel Tipparbeit, viel Recherche, aber es wird so langsam.


    Erstmal mache ich dieses Projekt hier fertig (Temperatumessung) und dann geht´s weiter mit dem Auslesen des Dachses, was dank Andreas nun in greifbare Nähe gerückt ist.


    Wenn das dann erledigt ist führen wir das Ganze in einen kompletten Linuxserver mit Inst.-Anleitung/Image/... zusammen.


    Da das ´ne Menge Arbeit ist: einfach geduldig warten.
    Als grobe Zeitmarke schwebt mir für den Abschluss dieser drei Teilprojekte das Ende dieses Jahre vor....


    Aber Kopf hoch, bis auf 3 Sachen, die mir noch nicht 100%ig gefallen ist das Darstellungsmodul fertig.
    Es geht also voran.



    WePP


    PS: Diesen Thread bitte nur für das Temperaturmess-Projekt verwenden, sonst steigt man hinterher gar nicht mehr durch... ;)

  • So ihr Lieben,
    dieser Teil ist vollbracht:
    Auch das Anzeigemodul ist fertig!


    Was haben wir also:
    - preiswerte Sensoren (ca. 6€/Stück)
    - Linux-Scripte zum Auslesen und Schreiben in eine MySQL Datenbank
    - flexibles Darstellungsmodul der Temperaturdaten


    Ich bin ab morgen früh (Sa) leider erst mal eine Woche im Urlaub, sobald ich wieder da bin werde ich mit Hochdruck daran arbeiten, euch die Anleitung und Software für all das zur Verfügung zu stellen.


    Doku Bearbeitungsstand:
    - Aufbau Hardware : 100%
    - Software Digitemp : 60%
    - Einbindung in eigenen Server : 0%


    Nur noch ein klitzekleines bischen Geduld!


    WePP

  • Hallo,


    Kannst du mir vielleicht einen Tipp geben wie ich mit Digitemp die Temperatur über Webinterface abfragen kann?


    Gruß und Danke


    SKY
    ?( ?( ?(

  • Hallo WePP,


    gibt es mittlerweile was Neues?


    Gruss
    Spornrad

    -- Die Sonne ist die Quelle unserer Energie, die es richtig anzuzapfen gilt ! ---
    „Nicht alles, was zählt, ist zählbar!“ „Nicht alles, was zählbar ist, zählt!“ Albert Einstein

  • Hallo WePP,


    habe schon lange nichts mehr von Dir gehört. Gibt es mittlerweile was Neues zu dem Thema Temperaturen? Wir warten brennend darauf.


    Gruss
    Spornrad

    -- Die Sonne ist die Quelle unserer Energie, die es richtig anzuzapfen gilt ! ---
    „Nicht alles, was zählt, ist zählbar!“ „Nicht alles, was zählbar ist, zählt!“ Albert Einstein

  • Hallo,


    Ich habe mir nun auch die Bauteile zur Temperaturmessung besorgt.
    Es gibt auch eine Software die unter Windows XP lauffähig ist (DOS-Basis).


    Bin noch am Basteln, wird aber, hoffe ich :D.


    Gruss, Udo.

  • Hallo,


    hier kann man übrigens Details zu dem Temperatur Messpojekt sehen:


    Temperatur messen


    Dafür gibt es wie MaUdo sagt auch DOS Programme aber alles noch ungetestet.


    MaUdo : Welches Programm hast Du gefunden?


    Gruss
    Spornrad

    -- Die Sonne ist die Quelle unserer Energie, die es richtig anzuzapfen gilt ! ---
    „Nicht alles, was zählt, ist zählbar!“ „Nicht alles, was zählbar ist, zählt!“ Albert Einstein

  • Ich habe Digitemp in der Version 1.7 genommen. Hatte Anfangs eine ältere Version die zwar ROM-Daten gelesen hatte aber als Temperatur 85° ausgab.


    Gruss, Udo.