ComPort zu langsam!



  • Wie ließt du denn vom ComPort??


  • Mod

    Hallo

    ich habe mal MSComm32 zum lesen der Com-SS verwendet
    Ich vermute mal bei deiner Komponente kann man irgendwo einstellen,
    das bei jedem Zeichen, das ankommt eine Methode der Komponente aufgerufen wird
    und sofort ist dein Problem weg

    Mfg
    Klaus



  • Also alles was ich gemacht habe ist eine Methode zu schreiben für das Ereignis OnRxChar - d.h. wenn etwas empfangen wurde:

    void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
    {
    int a;
    for(int i=0; i<Count; i++) {
            ComPort1->Read(&a,1);
            Puffer[z] = StrToInt(a);
            z++;
            if (z==231 && connect == 1) {
                    int l=0;
                    do {
                    BPuffer[l] = Puffer[l];
                    l++;
                    } while (l<256);
                    Datenverarbeitung();
                    z=0;
            }
        }
    }
    

    Count gibt dabei an, wieviele Zeichen im Eingangspuffer liegen. "a" wird eingelesen vom ComPort und unter Puffer abgespeichert. Dann folgt nur noch Verarbeitung...aber selbst wenn ich die weglasse und einen Breakpoint setze, sehe ich dass ich nicht das empfange, was ich sende! ...doch besagtes Terminal Programm empfängt alles! 😞 Ich schaue mir deinen Tipp mal an. Danke



  • Sorry, aber wenn du byteweise daran knabberst
    ComPort1->Read(&a,1);
    darfst du keine Wunder bei der Geschwindigkeit erwarten.

    Des Weiteren

    dann erfolgen noch eine Schleife und eine weitere Funktion?

    Besser wäre doch, den gesamten "Empfang" in eine Buffer zu lesen und dann zu bearbeiten. U.U. in einen Thread



  • schon auf die idee gekommen die mitgelieferten beispiele anzuschauen und die hilfe zu lesen?



  • Hallo Christian und Co.!
    Ziel ist es in erster Linie sehr schnell ankommende Daten abzuspeichern. Angenommen ich würde nun den Befehl

    ComPort1->Read(&a,Count);
    

    verwenden, wie könnte ich denn dann die im Empfangspuffer vorliegenden Daten gezielt in ein Array schreiben? Soll heißen: erstes empfangenes Byte in Puffer[0], zweites in Puffer[1], etc.??? Oder gibt es da andere Möglichkeiten? Danke für Tipps!!!
    P.S. Für die Auswertung der dann gespeicherten Daten könnte ich dann ja ein extra Programm schreiben!?



  • Wenn du einen buffer in der Größe von Count reservierst, stehen die Bytes dann schon in einem Array

    int *p=new int[Count]

    Dann da rein lesen lassen.
    Geht natürlich auch mit einem anderen Datentyp.



  • benutze doch einfache String-Kopier-Funktionen.. zB strcpy() (da gibts bestimmt noch andere, bessere und schnellere)

    und den resourcenhalber würde ich den Typ char zum auslesen empfehlen, oder erwartet ComPort1->Read(); tatsächlich ein zeiger auf int an erster stelle?

    mfg
    BigNeal



  • Hallo

    benutze doch einfache String-Kopier-Funktionen.. zB strcpy() (da gibts bestimmt noch andere, bessere und schnellere)

    Auf jedenfall ist strncpy() sicherer.

    bis bald
    akari



  • Shit...will nicht so wie ich!
    Zuerst erstelle ich eine Datei:

    FileCreate("Messdaten.txt");
    

    und öffne den ComPort:

    ComPort1->Open();
    

    . Dann sende ich eine Startsequenz

    a=0xAA;
    ComPort1->Write(&a,1);
    

    .
    Nun sendet die Gegenstelle Daten, die ich in meiner Datei "Messdaten.txt" speichern will. Dazu folgende Ereignisprozedur für OnRxChar:

    char a;
    ComPort1->Read(&a, Count);
    AnsiString s = "";
    for(int i=0; i<Count; i++) {
            AppendStr(s,a);
            AppendStr(s,"\r\n");
    }
    FileSeek(b,0,2);
    FileWrite(b, s.c_str(), s.Length());
    FileClose();
    

    Leider ist die Datei hinterher leer und außerdem möchte ich die Werte als dezimal Zahlen abspeichern. Danke für Tipps.
    P.S. Verwende jetzt FileCreate etc., weil LoadList->Add zu lange dauerte.



  • erlich gesagt, habe ich das gefühl du machst dich etwas schwer und suchst an der falschen stelle.
    Versuch doch mal mein Beispiel (ungetestet, da ich keinen BCB zur hand habe) nach zu vollziehen und zu komentieren.

    aber wie gesagt, muss nicht fehlerfrei sein

    char* cpInputBuf = new char[Count]; 
    
    ComPort1->Read(cpInputBuf, Count);
    
       /*        
       AnsiString asBuf;
       for(int x = 0; iCounter < Count; x++)
       {
          asBuf = asBuf + IntToStr((int)cpInputBuf[x]);
       } 
    
       ListBox1->Items->Add(asBuf);*/
    ListBox1->Items->Add(cpInputBuf);
    
    delete[] InputBuf;  
    
    // vor dem Schliessen der Schnittstelle/Applikation
    ListBox1->Items->SaveToFile("meine Daten.log");
    

    mfg
    BigNeal



  • Danke für die schnelle Antwort!
    Noch eine kurze Frage: Wie kann ich den Char in einen Int umwandeln, damit ich nicht diese Hyroglyphen "àÿ' ÿ' ÿE’" bekomme sondern schöne Zahlen?



  • siehe mein Beitrag:

    IntToStr((int)cpInputBuf[x]);
    

    ein char hat die grösse von 1 Byte.
    das heisst es kann den wert von 0 - 255 haben.
    die entsprechenden werten von Buchstaben und sonderzeichen kannst du einer ASCII-Tabelle entnehmen
    zB entspricht der Buchstabe A = dem Wert 65 Dezimal oder 41 hex (0x41)

    char cBuchstabe;
    cBuchstabe = 'A';
    ShowMessage(cBuchstabe);  // gibt "A" aus(ohne "");
    
    cBuchstabe = 0x41;
    ShowMessage(cBuchstabe);  // gibt "A" aus(ohne "");
    
    int i = (int)cBuchstabe;   // mit (int) sagst du, dass cBuchstabe als int angeschaut werden soll (casten) (das sollte aber mit vorsicht gemacht werden!)
    ShowMessage(IntToStr(i)); // gibt "65" aus(ohne "");
    
    oder direkt:
    ShowMessage(IntToStr((int)cBuchstabe));
    

    nimm doch mal die "/" und "/" in meinem Beispiel von vorhin raus und du wirst sehen wie es funktioniert

    ich hoffe ich habe es einigermassen erklährt

    mfg
    BigNeal



  • Danke für die kleine Nachhilfestunde! Das Programm läuft...nur leider reicht es nicht für meine Anwendung! 😞

    ES IST ZU LANGSAM.

    Wenn ich einzelne Bytes empfange läuft alles bestens. Er empfängt sie, zeigt sie im List Fenster an und Speichert sie in der Datei. Doch sende ich viele Daten schnell nacheinander, läuft nix mehr. Der Buffer läuft über und die Daten werden nicht schnell genug ausgelesen und gespeichert! 😞

    Ich sende 231 Byte alle 1,69ms. Das sollte doch eigentlich zu empfangen sein, oder? Gibt es Tipps?? Danke!



  • TobiasP schrieb:

    Ich sende 231 Byte alle 1,69ms. Das sollte doch eigentlich zu empfangen sein, oder? Gibt es Tipps?? Danke!

    das sollte locker zu empfangen sein. normale geschwindigkeit 9600 baud (baud = bit/s)
    wenn das zu langsam ist, sehe ich nur fehlerquellen in 2 orten.
    1. entweder werden die daten einfach nicht richtig abgeholt
    2. oder die datenverarbeitung ist zu langsam

    also mit dem von mir geschriebenem code mit der listbox sehe ich eigentlich keine Geschwindigkeitsprobleme.



  • Leider läuft das ganze nicht...weder mit meinem noch mit deinem Code.
    Kommt es denn darauf an in welchen Packetgrößen ich die Daten sende? Sprich, lohnt ein Versuch mehr Daten auf einmal zu senden und damit zwischen den einzelnen Datenpacketen mehr Zeit zu haben!?
    Ich finde die Sache sehr merkwürdig! ...



  • Was mir gerade noch in den sinn kommt
    Da du ja das Erreignis OnRxChar benützt, wird das ja eigentlich 231mal pro 1.69 sekunden aufgerufen.

    das könnte das problem sein, wenn man es direkt in eine Datei oder in eine Graphische komponente zwischenspeichern will.

    versuch mal

    private:
       AnsiString asReadBuf;
    
    OnRxChar(TObject *Sender, int Count) 
    {   
       char* cpInputBuf = new char[Count];
    
       ComPort1->Read(cpInputBuf, Count);
    
       asReadBuf = asReadBuf + AnsiString(cpInputBuf);
    
       delete[] InputBuf;
    
       if(asReadBuf.Length() >= 231)     
       {
          AnsiString asOut;
          for(int x = 1; x <= asReadBuf.Length(); x++)
          {  
             asOut = asOut + IntToStr((int)asReadBuf[x]);   
          } 
          ListBox1->Items->Add(asOut); 
          asReadBuf = "";
       }    
    }
    

    mfg
    BigNeal

    [edit] Rechtschreibung..



  • Super Einfall!!!!
    Immerhin blockiert jetzt nicht mehr alles. Jedoch erkenne ich meine gesendeten Zahlen bei den empfangen kaum wieder. Es tauchen nun negative Zahlen auf und alle Nullen scheinen weg zu sein... Was kann da denn schon wieder falsch sein?



  • Hier ist die Fortsetzung des Themas Binäre Daten interpretieren


Anmelden zum Antworten