# Libnodave Problem beim Beschreiben eines DB



## Rados (12 Dezember 2018)

Hallo Profis,

gestern habe ich LIBNODAVE entdeckt und bereits Daten aus der SPS empfangen, wobei ich C# nutze. Vielleicht freut sich der Entwickler über ein kleines Kompliment: Ich bin begeistert über die Möglichkeit, auf diesem Weg Daten austauschen zu können und dies von Seiten des Entwicklers absolut selbstlos, ohne eine finanzielle Vergütung zu verlangen. Ganz großes Dankeschön für diese tolle Lösung!

Die Beispieldatei habe ich erweitert, so dass auch zusätzliche Daten eingelesen werden konnten.
Somit funktioniert der Verbindungsaufbau zur SPS, einer VIPA 315-4PN12.

Nun wollte ich den umgekehrten Weg austesten und etwas an die SPS senden.  
Der Code,...

----------------------------------------------------
using System;


class test
{
    static libnodave.daveOSserialType fds;
    static libnodave.daveInterface di;
    static libnodave.daveConnection dc;
    static int rack = 0;
    static int slot = 2;
    public static int Main(string[] args)
    {
        int i, a = 0, j, res, b = 0, c = 0, f = 1; 
        float d = 0, e = 0;
        int saveDebug = libnodave.daveGetDebug();


        fds.rfd = libnodave.openSocket(102, args[0]);
        fds.wfd = fds.rfd;
        if (fds.rfd > 0)
        {
            di = new libnodave.daveInterface(fds, "TCP_315-4PN12", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k);
            di.setTimeout(1000000);
            //        res=di.initAdapter();    // does nothing in ISO_TCP. But call it to keep your programs indpendent of protocols
            //        if(res==0) {
            dc = new libnodave.daveConnection(di, 0, rack, slot);
            if (0 == dc.connectPLC())
            {
              res = dc.writeBytes(libnodave.daveDB, 6, 0, 2, BitConverter.GetBytes(libnodave.daveSwapIed_32(f)));
                if (res == 0)
                { 
                    Console.WriteLine("DB - Eintrag geschrieben?:" + res + "=" + libnodave.daveStrerror(res));
                }
                else
                    Console.WriteLine("error " + res + " " + libnodave.daveStrerror(res));
            }
            dc.disconnectPLC();
            //        }        
            //        di.disconnectAdapter();    // does nothing in ISO_TCP. But call it to keep your programs indpendent of protocols
            libnodave.closeSocket(fds.rfd);
        }
        else
        {
            Console.WriteLine("Couldn't open TCP connection to " + args[0]);
            return -1;
        }
        return 0;
    }
}


/*
Version 0.8.4.5    
07/10/09      Added closeSocket()
*/


----------------------------------------------------

... aufgerufen über die Eingabeaufforderung, läuft durch und gibt mir keinen Fehler zurück, sondern eine 0 / ein OK. 
Jedoch wird im DB6.DBW0 keine 1 hinterlegt (auch im Bitmuster bleibt alles auf 0).

 Der zweite Versuch mit

res = dc.writeBytes(libnodave.daveFlags, 6, 0, 2, BitConverter.GetBytes(libnodave.daveSwapIed_32(f)));

hat nichts gebracht, also habe ich vermutlich irgendetwas Grundsätzliches nicht verstanden oder aus Unwissenheit vergessen.

Ich wäre Euch für Hinweise sehr dankbar, die mir an dieser Stelle weiterhelfen, damit ich zur Lösung komme. 
Die rudimentäre Anleitung im Netz habe ich mir schon angesehen, leider hilft die mir nicht wirklich weiter, denn aus dieser und einem Beispiel habe ich die obere res-Programmzeile abgeleitet, die nicht wie gewünscht funktioniert.

Vielen Dank vorweg,
Ralf


----------



## PN/DP (12 Dezember 2018)

Hallo

Was liefert BitConverter.GetBytes(libnodave.daveSwapIed_32(f))?

writeBytes erwartet die Adresse des Puffers wo die zu schreibenden Bytes liegen.
Man kann diesen Ausgabepuffer irgendwie mit Daten füllen oder auch die Libnodave-Funktionen Put8/Put16/Put32 nutzen, um nacheinander Werte in den Ausgabepuffer zu legen, der dann mit writeBytes an die S7-PLC gesendet wird.

Harald


----------



## Thomas_v2.1 (12 Dezember 2018)

Bei:

dc.writeBytes(libnodave.daveDB, 6, 0, *2*, BitConverter.GetBytes(libnodave.daveSwapIed_32(f)));

schreibst du nur 2 Bytes. Bei .Net ist ein "int" aber ein 32 Bit breiter Ganzzahldatentyp, also 4 Bytes.
Wenn f den Wert 1 besitzt und dann durch daveSwapIed_32() die Bytereihenfolge auf das Siemens-Format angepasst wird, dann steht die 1 in den 4 Bytes welche von GetBytes() zurückgegeben werden im letzten (4.) Byte. Wenn du von diesen 4 Bytes nur die ersten 2 Bytes an die SPS schickst, dann wird dort nur eine 0 geschrieben.

Wenn du in DB6.DBW0 z.B. über eine Variablentabelle eine 12345 schreibst und dann dein Programm aufrufst, dann sollte dort anschließend der Wert auf 0 geschrieben werden.

Um in der S7 einen INT zu schreiben, wäre der 16 Bit Ganzzahl Datentyp in .Net dann short, oder Int16, und dann musst du auch die 16 Bit Swap Funktion von libnodave verwenden.


----------



## Rados (13 Dezember 2018)

Hallo Harald und Thomas:

SUUUPER - Eure Hinweise haben mich zur Lösung geführt (  => Int16 sowie daveSwapIed_16()  ).

Ich bedanke mich 

BG Ralf


----------

