Seriell gelesene Werte konvertieren!



  • Hallo Community!

    Ich bin eigentlich vb.netler, ich muss eine kurze DLL verfassen um eine selbstgebastelte i/o Hardware mit einem Programm zu verbinden bzw. eine serielle Kommunikation dazwischen herzustellen. Zu Testzwecken versuch ich es erst in der Konsole! Keine Sorge keine Frage zum leidigen Thema ComPort. Das funktioniert soweit problemlos.
    Ich möchte jetzt die empfangenen Daten mit Werten in einer Text-, CSV,-Datei
    vergleichen und diese ans Programm übermitteln.
    .
    .
    .

    HANDLE hSeriell;
    	DWORD dwCommEvent;
    	DWORD dwLesen;
    	char chLesen;
            int werteaddieren;
            string wertesammeln;
    

    .
    .
    .

    if (WaitCommEvent(hComm, &dwCommEvent, NULL)) {
    
    		if(!(dwCommEvent & EV_RXCHAR))
    			continue;
    
    		printf("Ich warte noch");
    
    		do{
    
    				if (ReadFile(hSeriell, &chLesen, 1, &dwLesen, NULL)){
    					if(dwLesen < 1)
    					{
    						printf("\nA timeout Ereignis.\n");
    						break;
    					}
    
    					if (dwLesen > 0){
    
                         //   y += chRead; //das klappt aber bringt nichts, addiert nur die Werte!
    
                            stringstream ein;  //einzelne Chars an String anhängen
                            ein << chLesen;
                          wertesammeln+=ein.str();
    
                             printf("%d",chLesen); // ergibt richtige gesendete Werte
    
    					if(chLesen == 10)
    							break;
                      }
    				}
    				else
    				{
    					printf("ReadFile error.");
    					break;
    				}
    		 }while(dwLesen);
    	 }
    

    .
    .
    .

    int z;
                   stringstream aus;
                   aus << wertesammeln;
                    aus >> z;
    
                      int a,b,c;
                      ifstream datei("APIliste.txt"); //hier werden die Vergleichswerte geladen
                      string zeile;
                       while (getline(datei,zeile)){
                      stringstream zeilenwert(zeile);
    
                      zeilenwert >> a >> b;
    
                       if (z == a){
                            c = b;
    			printf("%d",b);
                       }}
    

    Ich habe nun sämtliche Varianten die mir einfielen oder die ich im Netz gefunden habe ausprobiert, ich bekomme aber keinen String zustande der die
    Werte verbindet somit wird der Vergleich auch nie durchlaufen. Ich habe die str.append, mit stringstream, atoi und was weiß ich noch alles versucht.
    Es wird z.B. eine 9 und eine 2 empfangen, das sehe ich auch im Konsolenausgabebefehl, aber ich kriege keinen String der 92 enthält hin?! der dann in die Integervariable umgewandelt würde und verglichen werden kann.
    Mache ich da grundlegendes falsch? Achja, ich verwende keinen C++11 Compiler.
    Ich wäre für etwas Hilfe wirklich sehr dankbar



  • Kannst du dein Problem nochmal genauer erklären? Was soll passieren und was passiert stattdessen? Zeichen zusammen hängen und zu einem int konvertieren ist jedenfalls kein Hexenwerk:

    string wertesammeln;
    wertesammeln += '9';
    wertesammeln += '2';
    
    int z;
    stringstream aus;
    aus << wertesammeln;
    aus >> z;
    
    cout << z << endl;  // Gibt 92 aus
    


  • Im Prinzip genau das, das es nicht schwer sein sollte dachte ich auch! Ich empfange seriell geweils zwei Werte, also z.B. eben
    eine 9 und eine 2. Damit ich diese außerhalb des Readfile Events verwenden kann und es sich dabei um jeweils ein char handelt, diese jeweils nach dem Empfang an einen String anzuhängen, damit ich '92' erhalte und dann den String wieder in
    einen Integer, damit ich diesen mit den Werten aus der Textdatei vergleichen kann, also eine Zeile der Datei lautet dann '92' '25', die 25 verwende ich dann weiter. Aber ich erhielt nie einen Integer mit dem Value '92', und somit wird die If (z==a) Routine nie durchlaufen. Je nach Variante die ich in meiner Verzweiflung ausprobierte minus Werte, Herzchen, Smilie oder wie in dem Beispiel verwendet mit dem stringstream, erhalte ich eine Null.


  • Mod

    Mika B schrieb:

    Damit ich diese außerhalb des Readfile Events verwenden kann und es sich dabei um jeweils ein char handelt, diese jeweils nach dem Empfang an einen String anzuhängen, damit ich '92' erhalte und dann den String wieder in
    einen Integer, damit ich diesen mit den Werten aus der Textdatei vergleichen kann, also eine Zeile der Datei lautet dann '92' '25', die 25 verwende ich dann weiter.

    Verstehe ich das richtig? Du empfängst Zeichen. Du hast eine Datei, in der stehen Zeichen. Du willst die empfangenen Zeichen mit den Zeichen in der Datei vergleichen. Wo und wieso möchtest du dabei Integer benutzen?



  • Hallo Mika,

    Grundsätzlich sollte man die einzelnen Problemstellungen trennen. Dann fällt auch eine eventuelle Fehlersuche leichter.
    Punkt 1 wäre der Input von einer seriellen Schnittstelle.
    In- und Output löst man in C++ gemeinhin mit einer Kombination aus streambuf und stream. Für die serielle Schnittstelle empfehle ich Dir einen Streambuf, der in etwa so aussehen könnte:

    #include <streambuf>
    #include <cassert>
    #include <Windows.h>
    
    class SerialIn : public std::streambuf
    {
    public:
        SerialIn()  // ### hier den Code einfügen, um hSeriell & hComm zu initialisieren
            : hSeriell()
            , hComm()
        {}
    
        SerialIn( const SerialIn& ) = delete;
        SerialIn& operator=( const SerialIn& ) = delete;
    
    protected:
        int_type underflow() override
        {
            assert( !gptr() || gptr() >= egptr() );
            for( DWORD dwCommEvent;; )
            {
                if( !WaitCommEvent( hComm, &dwCommEvent, NULL) )
                    return traits_type::eof();  // Fehler
                if( dwCommEvent & EV_RXCHAR )
                    break;  // ein Zeichen empfangen
            }
            DWORD dwLesen;
            if (!ReadFile(hSeriell, &chLesen, 1, &dwLesen, NULL) || dwLesen < 1 )
                return traits_type::eof();  // Timeout oder Lesefehler
            setg( &chLesen, &chLesen, &chLesen + 1 );
            return traits_type::to_int_type( chLesen );
        }
    
    private:
        HANDLE hSeriell;
        HANDLE hComm;
        char chLesen;
    };
    

    in den Konstruktor musst Du noch den Code einfügen, der die Member hSeriell und hComm initialisiert.

    dann schreibe ein sehr einfaches Testprogramm:

    #include <iostream>
    // include SerialIn usw.
    
    int main()
    {
        using namespace std;
        SerialIn serialSB; // Serielle Verbindung initialisieren
        cout << &serialSB;
    }
    

    Nun prüfe, ob da tatsächlich '92 ...' auf deiner Konsole erscheint.

    Falls ja, käme im nächsten Schritt die Integer einzulesen. Zweites Testprogramm:

    #include <iostream>
    // include SerialIn usw.
    
    int main()
    {
        using namespace std;
        SerialIn serialSB; // Serielle Verbindung initialisieren
        istream serial( &serialSB );
        for( int z; serial >> z; )
            cout << z << endl;
    }
    

    .. und wenn das funktioniert, kannst Du mit dem eigentlichen Vergleich weiter machen, das sähe dann so aus:

    #include <fstream>
    // weitere includes
    
    int main()
    {
        using namespace std;
        SerialIn serialSB; // Serielle Verbindung initialisieren
        istream serial( &serialSB );
    
        ifstream datei("APIliste.txt"); //hier werden die Vergleichswerte geladen
        if( !datei.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return 0;
        }
        for( int a,b; datei >> a >> b; datei.ignore(999, '\n') ) // ignore(999,'\n') überliest alles bis Zeilenende
        {
            int z;
            if( (serial >> z).fail() )
                break;  // Serielle Verbindung abgebrochen
            if( z == a )
            {
                int c = b;
                cout << b << endl;
            }
        }
        return 0;
    }
    

    Tipp: falls bereits der erste Test nur unsinnige Zeichen liefert, dann mache den zweiten mit

    for( char c; serial >> c; )
            cout << hex << unsigned(c) << endl;
    

    evt. empfängst Du Binärcode.

    Gruß
    Werner



  • Nunja, es sind Zahlen, Zahlenwerte die verglichen werden sollen, es sind keine
    Dezimalzahlen, also Integer, ich lasse mich gerne verbessern, aber um Zahlenwerte zu vergleichen muss ich sie doch als Integer verwenden?!
    Wenn ich die Datei Zeilenweise auslese und mit stringstream an die int Variablen
    zuweise Habe ich Integers. Nun sind die gelesenen Werte Chars, ich könnte die ja ohne Konvertierung vergleichen, dann habe ich aber nur jeweils einen einzelnen Wert, um aber eben alle gesendeten Werte zusammen zu erlangen, dachte ich eben muss ich einen string daraus bilden, also 9 und 2, können aber auch mehr sein, der Wert '92' aus dem String entspricht ja nicht dem Wert eines Integer '92'.
    Ich bin mir dessen bewusst, dass da der Fehler begraben sein wird, aber ich seh es nicht.



  • Hallo Mika,

    versuche das mal mit den Streambuf und mache den ersten Test (s.o.). Anschließend dann evt. nochmal mit dem Code-Schnipsel ganz unten in meinem Beitrag. Und poste dann den Output, den Du dort erhältst.

    Gruß
    Werner



  • Hallo Werner!

    Wow, herzlichen Dank für die umfangreiche Arbeit die du Dir gemacht hast!
    Ich fürchte das wird noch etwas dauern bis ich das testen kann, dazu muss ich
    mich erstmal versuchen damit vertraut zu machen, von Klassen habe ich bislang keine Ahnung, und wie die Initialisierung diesbezüglich auszusehen hat bzw. welche Parameter wie übergeben werden müssen. Außerdem ist da noch viel neues
    drinn, das ich nicht verstehe.
    Ich melde mich wenn ich es begriffen habe.

    Grüße
    Mika


Log in to reply