Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Mitutoyo-messgeräte ansteuern

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
27.07.2003, 12:46 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Hi, ich habe mir ne klasse geschrieben mit der ich mir die werte von einem Messschieber und ner messuhr über die serielle schnittstelle einlesen kann.

header file

C++:
#ifndef MESSGERAETE_H
#define MESSGERAETE_H

#include "windows.h"

class Messgeraete{

    public:

        Messgeraete();
        ~Messgeraete();

        void takeValues();
        double getValue(int value);
        void stopThread();
        
        //-1: Messung wurde abgerochen, 0 keine gütligen Werte, 1 gültige Werte wurden gelesen
        int getMessflag();
        
        static DWORD messenThread(LPVOID);

    private:

        HANDLE h_com;
        HANDLE h_messThread;
        
        double value1, value2;
        int messflag;

};
#endif



cpp-file

C++:
#include "stdafx.h"
#include "Messgeraete.h"
#include "stdio.h"

Messgeraete::Messgeraete(){
    
    messflag=0;

    h_com = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0 , NULL);


    DCB dcb;
    COMMTIMEOUTS cto;

    GetCommState(h_com, &dcb);

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

    GetCommTimeouts(h_com,&cto);

    cto.ReadTotalTimeoutConstant=0;
    cto.ReadTotalTimeoutMultiplier=0;

    SetCommTimeouts(h_com,&cto);


}


Messgeraete::~Messgeraete(){

    CloseHandle(h_com);

}

DWORD Messgeraete::messenThread(LPVOID lparam){

    DWORD dw;
    
    int i;
    unsigned long nBytesRead1,nBytesRead2;
    char inbuffer1[13];
    char inbuffer2[13];
    
    char temp[9];
    temp[8]=0;

    ReadFile(((Messgeraete*)lparam)->h_com, &inbuffer1, 13, &nBytesRead1, NULL);
    ReadFile(((Messgeraete*)lparam)->h_com, &inbuffer2, 13, &nBytesRead2, NULL);

    for(i=0;i<8;i++) temp[i]=inbuffer1[i+4];
    ((Messgeraete*)lparam)->value1=atof(temp);

    for(i=0;i<8;i++) temp[i]=inbuffer2[i+4];
    ((Messgeraete*)lparam)->value2=atof(temp);

    ((Messgeraete*)lparam)->messflag=1;

    GetExitCodeThread(((Messgeraete*)lparam)->h_messThread, &dw);

    ExitThread(dw);

    return 0;

}


void Messgeraete::takeValues(){

    messflag=0;
    h_messThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)messenThread, (LPVOID)this, 0, NULL);    
    
}

double Messgeraete::getValue(int value){

    if (value==1) return value1;
    else return value2;

}

void Messgeraete::stopThread(){
    
    DWORD dw;
    GetExitCodeThread(h_messThread, &dw);
    TerminateThread(h_messThread, dw);
    value1=value2=-1;
    messflag=-1;
    
}

int Messgeraete::getMessflag(){ return messflag; }



mein problem liegt hier

C++:
TerminateThread(h_messThread, dw);


manchmal (ca. jedes 100. mal wird der thread nicht richtig beendet. checken kann ich das irgendwie auch nicht, weil terminatethread mir immer true zurückliefert, hab ich ausprobiert. Habt ihr ne Idee wie ich den Readfile anders abbrechen kann. Es darf auf keine Fall mit timeout sein, weil es sonst passieren kann das der user auf werte übertragen klickt während die schnittstelle nicht empfangsbereit ist.

ich hoffe ich habe das verständlich genug erklärt
wenn nicht fragen

Über brauchbare Anregungen würde ich mich freuen

Danke Heiko

Ach so, gut wäre es wenn man einen dummy-datensatz an die com1 schicken könnte. Allerdings blockiert mir der readfile die komplette schnittstelle so lange bis der von aussen beendet ist. Gibts da vielleicht ne möglichkeit den empfangspuffer einen datenempfang "zu verkaufen" der nicht von aussen kommt.
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 27.07.2003 um 12:48 Uhr von Heiko editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.07.2003, 14:20 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Wenn dir TerminateThread den Thread "killt" gibt es true zurück... festzustellen, ob der thread noch existiert mit GetExitCodeThread...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.07.2003, 17:18 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


das problem war ja das der immer true zurückgibt egal ob er ihn gekillt hat oder nicht.
Das mit dem GetExitCodeThread werd ich noch mal probieren problem dabei ist das das extrem langwierig ist, da der fehler total zufällig ist und nur ca. jedes 100 mal auftritt.
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 27.07.2003 um 17:24 Uhr von Heiko editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
28.07.2003, 14:04 Uhr
ao

(Operator)


Ich verstehe nicht ganz, wozu du den Thread hast. Im Konstruktur hast du die COMMTIMEOUTS so eingestellt, daß du völlig ohne Timeout arbeitest, d.h. wenn die Schnittstelle bereits Daten empfangen hat, bekommst du sie. Wenn nicht, kehrt der Thread sofort und ohne Daten zurück. Ist das so? Das könntest du auch direkt in der takeValues-Methode synchron erledigen.

Ein Problem sehe ich darin, daß der Thread sich selber terminiert (mit ExitThread am Ende von messenThread) UND danach noch stopThread gemacht wird, was denselben Thread noch mal killt. Eventuell gibts da ne Race-Condition und einen Hänger. Und der Thread-Handle wird nicht geschlossen (CloseHandle (h_messThread)

Oder ich hab das alles falsch verstanden. Wann und von wem werden die Methoden von Messgeraete denn aufgerufen?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.07.2003, 14:42 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@ao
jupp das mit dem selbst terminieren ist schon draussen. Ist auch nicht das problem.

Das mit dem Timeout hast du richtig erkannt. Gibst nicht. allerdings wartet Readfile in dieser configuration so lange bis er was bekommt. (bis in alle ewigkeit)so soll es auch sein es sei denn ich will das von hand abbrechen.
an sonsten wird auf werte der Messgeräte gewartet.

das ganze muss in nem Thread laufen, damit das programm auch noch was anderes machen kann während es auf die daten von der seriellen schnittstelle wartet. Nur wenn der User von hand abbricht soll der Readfile weiterlaufen bzw sich beenden.

und noch ne idee?


Gruss Heiko
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 28.07.2003 um 15:02 Uhr von Heiko editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.07.2003, 15:20 Uhr
ao

(Operator)


Ach so. Zum Abbrechen des endlos wartenden ReadFile: hast du schon mal CancelIo() versucht?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.07.2003, 15:52 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


jupp
CancelIo geht leider nicht weil hierfür FILE_FLAG_OVERLAPPED gesetzt sein muss. Das ist es leider nicht.

noch ne gute Idee?

Gruss Heiko
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
28.07.2003, 16:02 Uhr
ao

(Operator)



Zitat:
Heiko postete
weil hierfür FILE_FLAG_OVERLAPPED gesetzt sein muss. Das ist es leider nicht.


Und warum nicht? Setz es doch, im Messgeraete-Konstruktor bei CreateFile().

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
28.07.2003, 16:06 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


das ist doch irgendwie für asynchrone übertragung.
Damit hatte ich mal angefangen rumzuspielen, das hatte aber nicht richtig funktioniert (wahrscheinlich war ich zu blöd oder das geht nicht mit den messgeräten) und da habe ich das wieder verworfen

Kannst du mir nen Beispielcode dafür geben.

also das mit dem Createfile flag setzten bekomme ich viellleicht noch hin, aber wie muss die struktur aussehen die ich dem readfile übergeben muss?

Gruss Heiko
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.07.2003, 16:52 Uhr
ao

(Operator)


Beispielcode nur ganz grob, fuer die Feinheiten fehlt mir die Zeit. Lies die Details in der MSDN-Hilfe nach, Stichworte OVERLAPPED, ReadFile, CreateEvent, WaitForSingleObject.


C++:
/* Event erzeugen; Windows wird diesen Event setzen, wenn Daten da sind */
HANDLE hEvent = CreateEvent ( /* irgendwie richtig ausfuellen */);

/* Overlapped-Struktur. Event eintragen */
OVERLAPPED ovl;
ovl.hEvent = hEvent;

/* ReadFile aufrufen, dabei über ovl den Event in Windows hineinreichen */
BOOL bResult = ReadFile (h_Com, Buffer, NumBytesToRead, NumBytesRead ,&ovl);

/* Windows wartet auf Daten -> wir warten auch. */
if (!bResult && GetLastError () == ERROR_IO_PENDING)
{
    WaitForSingleObject (hEvent /* , .... */);

    /* Wenn der Event gesetzt wird, sind Daten da und wir machen weiter. */
}

/* Hier Daten abholen und verwursten. */

/* Nicht vergessen: */
CloseHandle (hEvent); /* Event zerlegen */



Was noch fehlt, ist das Abfangen von Katastrophen (Fehler bei CreateEvent, bei ReadFile oder bei Wait).

Aufpassen: Das CancelIo muß durch den Thread gemacht werden, der auch das ReadFile angestoßen hat. Der Code oben sieht also richtigerweise so aus:


C++:
/* Windows wartet auf Daten -> wir warten auch. *)
if (!bResult && GetLastError () == ERROR_IO_PENDING)
{
    while (!bCancel && (WaitForSingleObject (hEvent, 1000) == WAIT_TIMEOUT);)
}


und die Cancel-Anforderung wird von außen etwa so angezeigt:

C++:
void Messgeraete::stopThread()
{
    bCancel = true;
}



Diese Geschichte mit Overlapped ist übrigens eine reine Windows-Angelegenheit und hat mit dem angeschlossenen Meßgerät garnix zu tun.

ao
ao

Dieser Post wurde am 28.07.2003 um 16:52 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: