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

Ergebnis 1 bis 10 von 10

Thema: kann libnodave - Zeiten / Zähler (Timer / Counter) schreiben ?

  1. #1
    Registriert seit
    10.01.2014
    Beiträge
    5
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo zusammen,

    ich habe libnodave schon seit längerer Zeit mit verschiedenen Sprachen (VB, C#, Delphi) ohne Probleme im Einsatz.
    Ich wollte jetzt zum ersten mal einen Zähler in die SPS schreiben, hier gibt es Probleme ich bekomme die Fehlermeldung
    "Write data size error".
    Ich habe das ganze dann mit Prodave 6 getestet, hier hat es geklappt.

    Als Test CPU verwende ich ein 417H System das ich über ISO over TCP anspreche.

    Vielleicht kann mir ja jemand Helfen.
    Zitieren Zitieren kann libnodave - Zeiten / Zähler (Timer / Counter) schreiben ?  

  2. #2
    Registriert seit
    29.03.2004
    Beiträge
    5.793
    Danke
    144
    Erhielt 1.706 Danke für 1.238 Beiträge

    Standard

    Habs grad mal getestet. Das Lesen von Timern und Zählern geht, aber das Schreiben funktioniert wirklich nicht, zumindest nicht mit daveWriteBytes().

    Wenn man einen Timer oder Zähler lesen will, kommt als Antwort im Datenteil die Transportgröße Octet String, also 0x09 zurück. Das kann libnodave auch verarbeiten.
    Beim Schreiben muss aber ebenfalls diese Transportgröße 0x09 angegeben werden (zumindest macht WinCC flex das so, und da funktioniert es), und das macht libnodave momentan (0.8.5) nicht.
    Das kannst du selber aber nicht so einfach beheben, das müsste am Besten Zottel in der lib anpassen.

    Man müsste in der Funktion daveAddVarToWriteRequest() eine Weiche in Abhängigkeit von "area" einbauen, und dann das Array "da" anders beschreiben.

  3. #3
    Registriert seit
    29.03.2004
    Beiträge
    5.793
    Danke
    144
    Erhielt 1.706 Danke für 1.238 Beiträge

    Standard

    Meiner Meinung nach müssten folgende Änderungen in der nodave.c gemacht werden:
    Code:
    @@ -588,7 +588,15 @@
         FLUSH;
     #endif
     
    -    if ((area==daveTimer) || (area==daveCounter)||(area==daveTimer200) || (area==daveCounter200)) {    
    +	if ((area==daveTimer) || (area==daveCounter)) {     /* TWI: Fix for S7 timer/counters */
    +	pa[3]=area;
    +	pa[4]=byteCount / 0x100;
    +	pa[5]=byteCount & 0xff;
    +	/* with timer/counters the byteCount parameter gives the number of t/c to write.
    +	 * each timer/counter value needs 2 Bytes, adjust byteCount to number of bytes for _daveAddValue() 
    +	 */
    +	byteCount *= 2;										
    +	} else if ((area==daveTimer200) || (area==daveCounter200)) {  
     	pa[3]=area;
     	pa[4]=((byteCount+1)/2) / 0x100;
     	pa[5]=((byteCount+1)/2) & 0xff;
    @@ -652,8 +660,13 @@
     	p, daveAreaName(area), DBnum, start, byteCount, buffer);
         FLUSH;	
     #endif	    	
    -		
    -    daveAddToWriteRequest(p, area, DBnum, 8*start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));
    +	/* TWI: Fix for S7 timer/counters */
    +	if (area == daveCounter || area == daveTimer) {
    +		da[1] = 0x09;	/* Transport-size Octet-String */
    +		daveAddToWriteRequest(p, area, DBnum,   start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));
    +	} else {
    +		daveAddToWriteRequest(p, area, DBnum, 8*start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));
    +	}
     }
    Ob man das so machen muss sei dahingestellt, an einer S7-300 funktioniert es zumindest.

    Bei der Funktion daveWriteBytes wird dann im Parameter "len" die Anzahl der Timer / Counter angegeben die geschrieben werden sollen, und nicht die Anzahl der Bytes in "buffer". Man muss dafür sorgen dass der Buffer pro Timer/Counter einen 2-Byte großen Wert beinhaltet.
    So scheint mir das konsistent mit den Lese-Funktionen, denn bei denen wird ebenfalls die Anzahl der Timer/Counter angegeben und nicht die Anzahl an Bytes (im Gegensatz dazu wenn andere Datenbereiche gelesen/geschrieben werden).

    Es lassen sich auch mehrere Timer / Counter in einem Rutsch schreiben, z.B. T2, T3 oder C10, C11. Da wusste ich bisher garnicht dass das funktioniert.

    Ob das mit den Aufrufen um Timer/Counter einer S7-200 zu lesen zusammenpasst kann ich nicht testen, das sieht mir nochmal speizell anders aus.

  4. #4
    powerfacer ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    10.01.2014
    Beiträge
    5
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo,

    Danke für die schnelle Hilfe, hab die lib mal mit den vorgeschlagenen Änderungen übersetzt, und es hat funktioniert !
    Es hakt allerdings noch mit dem Rückgabewert der Funktion, es kommt immer noch der Fehler "Write data size error",
    obwohl der Timer, Counter in die SPS geschrieben wurde.
    Hier komme ich nicht weiter, kann mir evtl. auch hierfür noch jemand einen Tipp geben ?

    Danke

  5. #5
    Registriert seit
    29.03.2004
    Beiträge
    5.793
    Danke
    144
    Erhielt 1.706 Danke für 1.238 Beiträge

    Standard

    Komisch, welche Funktionen verwendest du denn um einen Zähler zu schreiben?

    Mit meiner Änderung kann ich folgendermaßen Zähler Z3 auf 0 setzen:

    a = 0;
    res = daveWriteBytes(dc, daveCounter, 0, 3 ,1 ,&a);

    Die Variable "a" sollte eine Variable mit einem 2-Byte Datentyp sein.

    Mich verwundert auch dass angeblich der Zähler trotzdem geschrieben wird, obwohl es von der SPS einen Fehler zurückgibt. Das kenne ich eigentlich so, dass wenn die SPS ein Fehler zurückmeldet auch nichts geschrieben wurde.
    Verwendest du libnodave als dll, oder linkst du statisch? Vielleicht ist da irgendwas nicht aktuell.

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

    Standard

    Ich verwende libnodave als dll,

    Aufruf z.B. so

    mPLCError = daveWriteBytes(dc, daveCounter, 0, 3 ,1 ,&PLCData);

    ich bekomme im mPLCError den Wert 7 -> "Write Data Size error" zurück, der Zähler wird aber in der Steuerung übernommen, ich
    vermute das die Funktion daveExecWriteRequest mir anhand der PLC Rückmeldung das so auswertet.

    } else if (q[0]==0xFF) {
    c2->error=daveResOK;
    } else if (q[0]==0x07) {
    c2->error=daveWriteDataSizeMismatch;

  7. #7
    Registriert seit
    29.03.2004
    Beiträge
    5.793
    Danke
    144
    Erhielt 1.706 Danke für 1.238 Beiträge

    Standard

    Ein 0x07 kommt von der SPS zurück wenn bei Timer/Zählern in da[1] kein 0x09 steht, oder andere Werte die nicht zusammenpassen. So verhält sich zumindest die S7-300 die ich hier stehen habe.

    Hast du die libnodave.dll denn neu übersetzt?

    Pack doch mal hinter die Zeile mit:
    da[1] = 0x09;

    ein printf um zu prüfen ob die Funktion überhaupt aufgerufen wird, bzw. ob dein Programm überhaupt die richtige (neue) dll verwendet.

  8. #8
    powerfacer ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    10.01.2014
    Beiträge
    5
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hab mal in daveWriteBytes beim Aufruf von

    res=_daveTestWriteResult(&p2);

    einen Screenshot von _daveDumpPDU gemacht, so wie es aussieht ist da in p->data[0] tatsächlich der wert 0x07.

    PDU.gif

    Das Programm verwendet meine neu übersetzte dll.

  9. #9
    Registriert seit
    29.03.2004
    Beiträge
    5.793
    Danke
    144
    Erhielt 1.706 Danke für 1.238 Beiträge

    Standard

    Laut deinem Screenshot versuchst du in der SPS auf zwei Datenbereiche mit einem Auftrag zu schreiben, die aber beide nicht ausgeführt werden konnten.
    Bereich 1 kommt mit Fehler 0x07 (Typ inkonsistent), und Bereich 2 mit Fehler 0x0a (Bereich nicht verfügbar) aus der SPS zurück.

    Zeig doch mal ein PDU Dump von den Anfragen die du schickst.

    Welche libnodave Quellen verwendest du denn als Basis? Ich habe die letzte 0.8.5, und da funktioniert meine Änderung einwandfrei.

  10. #10
    powerfacer ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    10.01.2014
    Beiträge
    5
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    Asche über mein Haupt, ich hab in daveAddVarToWriteRequest den alten Aufruf von daveAddToWriteRequest bei der Programmänderung für die Timer/Counter nicht
    versehentlich noch mit drinnen gehabt, Mann oh Mann, so ein sch... !

    Jetzt klappt es perfekt, Danke für deine Spitzenmäßig gute Hilfe !!

    Hier noch der Fehler:

    daveAddToWriteRequest(p, area, DBnum, 8*start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));


    /* TWI: Fix for S7 timer/counters */
    if (area == daveCounter || area == daveTimer) {
    da[1] = 0x09; /* Transport-size Octet-String */
    daveAddToWriteRequest(p, area, DBnum, start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));
    } else {
    daveAddToWriteRequest(p, area, DBnum, 8*start, byteCount,buffer,da,sizeof(da),pa,sizeof(pa));
    }

Ähnliche Themen

  1. libnodave-java-0.1 Counter und timer
    Von bresner1 im Forum Hochsprachen - OPC
    Antworten: 0
    Letzter Beitrag: 16.09.2011, 10:41
  2. Libnodave Timer und Counter
    Von Paul.Juergen im Forum Hochsprachen - OPC
    Antworten: 16
    Letzter Beitrag: 03.07.2010, 11:47
  3. Zähler CTU-Counter
    Von Spoon im Forum CODESYS und IEC61131
    Antworten: 2
    Letzter Beitrag: 06.02.2010, 16:50
  4. libnodave timer/counter schreiben
    Von b0den im Forum Hochsprachen - OPC
    Antworten: 7
    Letzter Beitrag: 16.05.2008, 10:59
  5. Libnodave Timer Counter
    Von lorenz2512 im Forum Hochsprachen - OPC
    Antworten: 7
    Letzter Beitrag: 30.10.2005, 15:15

Stichworte

Lesezeichen

Berechtigungen

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