Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 21

Thema: String durchsuchen nach festen Zeichen

  1. #1
    Registriert seit
    22.11.2013
    Beiträge
    9
    Danke
    9
    Erhielt 0 Danke für 0 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    ich hoffe mir kann jemand helfen!? Ich bin leider nicht sehr Erfahren in der Programmierung.
    Ich habe über eine Serielle Schnittstelle eine Waage an meine Wago 750-880 geschlossen, welche dauerhaft das aktuelle Gewicht sendet.
    Das Signal kommt bei mir an. Das Problem ist nun, dass wenn der Buffer voll ist und wieder gelöscht wird, fängt die Karte irgendwo im String an zu empfangen. Da ich das nicht richtig erklären kann, habe ich ein Screenshot vom laufenden Programm gemacht.
    Ich habe erst versucht nur nach Zahlen in dem String zu suchen oder immer nach der ersten Nummer. Die Position des Gewichts ändert sich jedoch immer.
    Wie kann ich einen String nach einer festen Zeichenkette durchsuchen und dann nur die Werte vor dieser Kette lesen?
    Ich hoffe ihr könnt mein Problem verstehen!?
    Angehängte Grafiken Angehängte Grafiken
    Zitieren Zitieren String durchsuchen nach festen Zeichen  

  2. #2
    Registriert seit
    22.11.2007
    Beiträge
    731
    Danke
    6
    Erhielt 89 Danke für 62 Beiträge

    Standard

    serielle kommunikation ist ein stream d.h. du brauchst irgendwo eine Länge oder Ende-Kennung in dem Protokoll (oder fixe Größe der Werte) - wie sieht das Protokoll aus?
    im Normalfall darfst du den seriellen Puffer nicht löschen, da du sonst nicht mehr sinnvoll den Anfang findest

    ansonsten kannst du dich auch mal direkt mit Hercules http://new.hwg.cz/download/sw/versio...ules_3-2-6.exe an die serielle-Schnittstelle hängen und die "unverfälschte" Kommunikation hier Posten
    HTErm wäre auch ok http://www.der-hammer.info/terminal/index.htm

  3. #3
    mschierer ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    22.11.2013
    Beiträge
    9
    Danke
    9
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Über Hercules habe ich schon einmal kommuniziert. Das Ergebnis war wie auch über Codesys: XX.XXX_Kg_$R$N. Ich finde den Screenshot gerade aber nicht.
    Dabei ist der hintere Teil (_Kg_$R$N) immer gleich. Das ist immer das Ende. Ich weiß aber nicht wie ich das Ende festhalten kann, damit ich den String bestimmen kann.

  4. #4
    Registriert seit
    22.11.2007
    Beiträge
    731
    Danke
    6
    Erhielt 89 Danke für 62 Beiträge

    Standard

    Ich weiß aber nicht wie ich das Ende festhalten kann, damit ich den String bestimmen kann.
    keine Ahnung was du meinst - steck die empfangenen Happen (die nicht unbedingt ein vollständigen Wert enthalten muessen - wegen seriell) in einen Puffer und durchsuch diesen nach x Vorkommen von \r\n (es könnten ja
    schon ein paar Werte vorher gekommen sein - oder ein halber ist jetzt vollständig...

    deine Reveices könnten so Ablaufen (abhängig von Geschwindigkeit deiner seriellen Verbindung)

    "11.22 Kg \r\n"
    --> nach kopie in deinen Puffer steht da jetzt "11.22 Kg \r\n"
    --> suchen nach \r\n -> ein Treffer - konvertieren und Treffer aus dem Puffer entfernen
    "11.33 Kg"
    --> nach kopie in deinen Puffer steht da jetzt "11.33 Kg"
    --> suchen nach \r\n -> kein Treffer
    " \r\n 22.33"
    --> nach kopie in deinen Puffer steht da jetzt "11.33 Kg \r\n22.33"
    --> suchen nach \r\n -> ein Treffer - konvertieren und Treffer aus dem Puffer entfernen
    " Kg \r\n 44.33 Kg \r\n"
    --> nach kopie in deinen Puffer steht da jetzt "22.33 Kg\r\n 44.33 Kg \r\n"
    --> suchen nach \r\n ->2 Treffer - konvertieren und Treffer aus dem Puffer entfernen
    usw.

    und immer daran denke seriell ist kein Bus mit festen Paketgrößen sondern eher wie TCP/IP ist - du bekommst deine Daten in Happen zerlegt die
    nicht unbedingt an den logischen Grenzen des Protokolls liegen (also anstatt [11.22 Kg\r\n] auch mal [11][.22 K][g\r\n] daher die Notwendigkeit des häppchenweise Verarbeitens
    wird zu oft vergessen (oder ignoriert weils doch richtig aussieht) und dann heulen alle das RS232 soooo schwer ist - fiese ist nur wenn der Anfang der Kommunikation nicht sauber ist - also noch irgendwelche alten Daten reintröpfeln
    Geändert von LowLevelMahn (26.11.2013 um 12:59 Uhr)

  5. Folgender Benutzer sagt Danke zu LowLevelMahn für den nützlichen Beitrag:

    mschierer (26.11.2013)

  6. #5
    mschierer ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    22.11.2013
    Beiträge
    9
    Danke
    9
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Danke, ich werde das mal versuchen zu realisieren...

  7. #6
    Registriert seit
    22.11.2007
    Beiträge
    731
    Danke
    6
    Erhielt 89 Danke für 62 Beiträge

    Standard

    hatte noch ein passendes C-Beispiel - auch seriell mit Trennung nach \r\n als funktionierendes Beispiel
    sollte aber nicht schwer sein zu adaptieren

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>    
    
    //fake daten für den seriellen empfang
    const int SERIELL_HAPPEN = 5;
    //diese pakete werden nacheinander "empfangen"
    char* seriell_happen[SERIELL_HAPPEN]=
    {
      "11.22 Kg\r\n",
      "11.33 Kg",
      "\r\n22.33",
      " Kg\r\n44.33 Kg\r\n",
      "55.66 Kg\r\n11.23 Kg\r\n",
    };
    
    //buffer fuer die eingangsdaten
    const int BUFFER_CAPACITY = 1024;
    char buffer[BUFFER_CAPACITY] = {0};
    int buffer_size = 0; // wir fangen bei 0 an
    
    int main()
    {
      //------------------------------------
      //fake des seriellen empfangs
      for(int t = 0; t < SERIELL_HAPPEN; ++t)
      {
        char* happen_daten = seriell_happen[t];
        int happen_laenge = strlen(happen_daten);
    
        //-------------------------------------
        //ist der buffer schon zu voll?
        assert(buffer_size+happen_laenge < BUFFER_CAPACITY); //--> fehler
    
        //seriellen daten an das ende des buffers kopieren
        ::memcpy(buffer+buffer_size, happen_daten, happen_laenge);
        buffer_size = buffer_size + happen_laenge;
    
        //-------------------------------------
        //dann fertige pakete suchen
    
        int begin = 0;
        int ende = 0;
    
        int i = 0;
        while(i < buffer_size-1)
        {
          // stehen wir auf einem abschluss \r\n
          if( buffer[i]=='\r' && buffer[i+1]=='\n' )
          {
            ende = i; // hier faengt das \r\n an
    
            //ausgabe - hier dann den wert nochmal parsen nach "XX.YYYY Kg"
            for(int c = begin; c < ende; ++c){ printf("%c", buffer[c]); } printf("\n");
            //...[11.22 Kg[\r\n22.33
    
            begin = i+2; // der naechste start liegt hinter \r\n
          }
          ++i;
        }
    
        //wert(e) gefunden?
        if( ende != 0 )
        {
          //buffer verkuerzen
          int vorne_abschneiden_laenge = ende + 2; // mit \r\n
    
          //den verarbeiteten teil mit den daten dahinter ueberschreiben
          int rest_size = buffer_size - vorne_abschneiden_laenge;
          ::memcpy(buffer,buffer+vorne_abschneiden_laenge, rest_size);
    
          //buffer hinter den kopierten daten "bereinigen" - nicht unbedingt noetig
          ::memset(buffer+rest_size, 0, vorne_abschneiden_laenge);
    
          buffer_size = rest_size;
        }
        //-------------------------------------
      }
      return 0;
    }
    liefert dann die Werte

    11.22 Kg
    11.33 Kg
    22.33 Kg
    44.33 Kg
    55.66 Kg
    11.23 Kg
    Geändert von LowLevelMahn (26.11.2013 um 16:47 Uhr)

  8. Folgende 2 Benutzer sagen Danke zu LowLevelMahn für den nützlichen Beitrag:

    KingHelmer (27.11.2013),mschierer (26.11.2013)

  9. #7
    Registriert seit
    15.02.2011
    Ort
    Stromness, Scotland, UK
    Beiträge
    339
    Danke
    25
    Erhielt 34 Danke für 33 Beiträge

    Standard

    Ich habe vor kurzem mal eine Grafik gemacht, ist zwar fuer serielle Kommunikation ueber EtherCAT, ich denke jedoch das Prinzip ist sehr aehnlich zu Wago:
    Wichtig ist hier wie schon erwaeht, dass du einen 'grossen' Buffer voll mit Bytes (einzelne Zeichen) hast, und daraus deine Werte herausfiltern musst.
    SerialCom over EtherCAT.jpg

  10. Folgender Benutzer sagt Danke zu gloeru für den nützlichen Beitrag:

    mschierer (28.11.2013)

  11. #8
    Registriert seit
    22.11.2007
    Beiträge
    731
    Danke
    6
    Erhielt 89 Danke für 62 Beiträge

    Standard

    dass du einen 'grossen' Buffer voll mit Bytes
    ist ein wenig unklar Formuliert - du hast einen grossen Buffer der ständig mit Empfangshäppchen erweitert wird
    und jeweils nach dem Anhängen von vorne nach vollständigen Paketen durchsucht und davon bereinigt wird
    man hat also immer 2 Buffer der erste mit dem gerade empfangenden Datenpakte von der Schnittstelle und ein zweiter in
    dem man diese Empfangspakete sammelt und die fertigen Pakete verarbeitet - also immer schön, einstellen, schauen, einstellen, schauen, ...

  12. Folgender Benutzer sagt Danke zu LowLevelMahn für den nützlichen Beitrag:

    mschierer (28.11.2013)

  13. #9
    Registriert seit
    15.02.2011
    Ort
    Stromness, Scotland, UK
    Beiträge
    339
    Danke
    25
    Erhielt 34 Danke für 33 Beiträge

    Standard

    Ok, aber mit dem kleinen Buffer has du eigentlich nichts zu tun. Und ganz genau genommen ist es einen Ringbuffer (der grosse), so dass keine Daten geloescht werden, es wird nur der 'Pointer darauf verschoben'

    Den Begriff Buffer habe ich einfach mal vorausgesetzt gehabt...
    http://en.wikipedia.org/wiki/Circular_buffer

  14. Folgender Benutzer sagt Danke zu gloeru für den nützlichen Beitrag:

    mschierer (28.11.2013)

  15. #10
    Registriert seit
    22.11.2007
    Beiträge
    731
    Danke
    6
    Erhielt 89 Danke für 62 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    den kleinen Buffer bekommt man vom System - SPS, Windows, whatever... und der ist meistens ein Ringpuffer also selbstüberschreibend wenn man nicht schnell genug ist

    den grossen Buffer habe ich in meinem Beispiel als "normalen" (leichter zu implementieren aber mehr copy) Linear-Buffer gemacht weil ich nicht wusste
    ob Codesys schon einen Ringbuffer anbietet - in diesem Falle aber für das Problem-Verständnis unrelevant ob Linear oder Circular

    Buffer != Circular_Buffer

    der Ringpuffer hat auch gefühlt den Nachteil des 0-Durchgangs und Start == Ende könnte Voll oder Leer bedeuten - das war mir dann hier zu viel
    noch dazu ist die Kopieraktion bestimmt (in diesem Fall) weniger böse

    aber du darfst mich aber gerne Überzeugen
    Geändert von LowLevelMahn (27.11.2013 um 13:59 Uhr)

  16. Folgender Benutzer sagt Danke zu LowLevelMahn für den nützlichen Beitrag:

    mschierer (28.11.2013)

Ähnliche Themen

  1. String ab bestimmten Zeichen löschen
    Von Roos im Forum Hochsprachen - OPC
    Antworten: 6
    Letzter Beitrag: 01.07.2011, 17:17
  2. Zeichen aus String auslesen
    Von Ötzwurst im Forum Simatic
    Antworten: 11
    Letzter Beitrag: 02.03.2010, 22:32
  3. 9 Zeichen werden von String abgezogen
    Von Bensen83 im Forum Simatic
    Antworten: 19
    Letzter Beitrag: 01.12.2009, 16:19
  4. Antworten: 9
    Letzter Beitrag: 23.10.2007, 00:46
  5. [Frage] - String mit mehr als 254 Zeichen?
    Von marcengbarth im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 27.07.2007, 10:39

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •