TwinCAT 3 - Verbindung zu MySQL-Datenbank

duese1990

Level-1
Beiträge
20
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Moin,

ich habe Probleme bei der Verbindung zu einer MySQL-Datenbank aus TC3.

Ich habe auf dem Rechner, auf dem auch TC3 läuft den Database Server installiert und die Trial-Lizenzen aktiviert.
Auf dem selben Rechner habe ich XAMPP installiert um die MySQL-Datenbank bereitzustellen.

Leider bietet Beckhoff meines Wissens nach kein explizites Beispiel für die Verbindung zu einer MySQL-Datenbank an.

Ich hatte mir vorgenommen dieses Beispiel auf meine Datenbank anzuwenden:
http://infosys.beckhoff.com/index.p...31/tcdbserver/html/TcDBServer_MySQLDB.htm&id=

leider ohne Erfolg.

Ich habe meine Datenbank in der XML-Datei deklariert und über PhpMyAdmin eine Datenbank mit fünf Spalten angelegt.
In dem Beckhoff-Quellcode habe ich dann lediglich meine Datenbank-ID wie in der XML-Datei angepasst.

Der Fehlercode "1048577" hilft mir leider nicht weiter - außer das es ein MySQL-Datenbankfehler ist. Heißt vlt. aber ja auch, dass er nichtmal die Verbindung auf die Reihe bekommt.

Ich habe zuvor auch schon auf eigene Faust mit den Funktionsbausteinen experimentiert - ebenfalls ohne Erfolg.

Ich würde mich sehr freuen, wenn mir jemand verraten kann, wo der Fehler liegen könnte bzw. was es noch zu beachten gibt?
Wenn jemand über ein MySQL-Minimalbeispiel verfügt wäre das natürlich das Optimum...

Ich würde mich sehr über eure Hilfe freuen!

Gruß
duese1990
 
Schau mal nach "SQL4Automation" im Internet. Is grad das einzige was mir für TwinCat in den Sinn kommt. Die Bibliothek is gratis, das einzige was kostet is der Connector, wenn du aber ein wenig Ahnung hast von dem ganzen Zeug solltest du das auch so hinkriegen.

Hast du denn in deinem Baustein einen eigenen Code für die Verbindung zur Datenbank geschrieben? Und könntest du ihn hier reinstellen? Würde das Troubleshooting erleichtern.
 
Hallo,

SQL4Automation klingt wirklich interessant, da es sich allerdings um ein Hochschulprojekt handelt, muss wahrscheinlich erst die Welt untergehen bevor ich so etwas bekommen würde ;).

So wie ich es verstehe, muss es ja mit den TwinCAT Bordmitteln laufen.

Nun mal der Quellcode, aber das ist eben der minimal modifizierte Beckhoff-Code.

XML-Datenbank Deklaration:
Code:
<?xml version="1.0" standalone="yes"?>
<Configuration>
    <StartUp>Manual</StartUp>
    <PwdInfos>tZuYPxhe+G5NKHWLYSZE+NiFAINdlcBgtIUVD+KtAff1ofKFk1lKYuDtaoU9/Zdt4bRYVCajotkS8XxD2QxKZp9c6AggKSjC</PwdInfos>
    <Databases>
        <Database Type="NET_MySQL" ValueType="Bytes">
            <DBId>1</DBId>
            <DBServer>localhost</DBServer>
            <DBDatabase>sps</DBDatabase>
            <DBDriver>
            </DBDriver>
            <DBUserId>sps</DBUserId>
            <DBPort>3306</DBPort>
            <DBProtocol>
            </DBProtocol>
            <DBScheme>
            </DBScheme>
            <DBSequence>
            </DBSequence>
            <DBTable>TestTable</DBTable>
        </Database>
    </Databases>
</Configuration>

Laut Beckhoff wäre die Deklaration damit auch vollständig:
http://infosys.beckhoff.com/index.p...erverce/html/TcDBServer_DBDeclaration.htm&id=

Dann habe ich wie beschrieben unter Add -> DUT -> Structure die eine Struktur angelegt:
Code:
TYPE ST_Record :
STRUCT
    Timestamp : DT;
    PLC_Value1 : REAL;
    PLC_Value2 : REAL;
    PLC_Value3 : REAL;
    PLC_Value4 : T_MaxString;
END_STRUCT
END_TYPE

Dann noch die Enumeration auf selben Weg erstellt:
Code:
TYPE E_SQLStatement :(
    eSQL_INSERT := 0,
    eSQL_SELECT := 1
);
END_TYPE

Und letzt endlich die MAIN:
Kopf:
Code:
(* Declaration *)
PROGRAM MAIN
VAR
    eState: E_SQLStatement;


    NT_GetTime1: NT_GetTime;
    bTimestart: BOOL;
    tTime: TIMESTRUCT;


    FB_FormatStringDateTime: FB_FormatString;
    sDateTimeString: T_MaxString;


    TestValue1: REAL := 123.456;
    TestValue2: REAL := 234.567;
    TestValue3: REAL := 345.678;
    TestValue4: STRING(255) := 'No error occurred';


    FB_FormatString1: FB_FormatString;
    sInsertString: T_MaxString;
    bError: BOOL;
    nErrid: UDINT;


    FB_DBRecordInsert1: FB_DBRecordInsert;
    bStartstopInsert: BOOL;
    bBusyInsert: BOOL;
    bErrInsert: BOOL;
    nErridInsert: UDINT;
    stSQLStateInsert: ST_DBSQLError;


    stRecord: ST_Record;


    FB_DBRecordArraySelect1: FB_DBRecordArraySelect;
    sSelectString: T_MaxString;
    nRecIndex: UDINT := 0;
    bStartstopSelect: BOOL;
    bBusySelect: BOOL;
    bErrorSelect: BOOL;
    nErrIDSelect: UDINT;
    stSQLStateSelect: ST_DBSQLError;
    nRecordCount: UDINT;
    
    Taster AT %I*: BOOL;
END_VAR

und das SPS Programm in der MAIN:
Code:
IF Taster = 1
    THEN
    bStartstopInsert := 1;
END_IF


CASE eState OF
    eSQL_INSERT:
        (*Create the timestamp*)
        NT_GetTime1( START:= bTimestart, TIMESTR=> tTime);
        IF NOT NT_GetTime1.BUSY THEN
            bTimestart := NOT bTimestart;
        END_IF


        FB_FormatStringDateTime(
            sFormat:= '%D-%D-%D %D:%D:%D',
            arg1:= F_WORD(tTime.wYear),
            arg2:= F_WORD(tTime.wMonth),
            arg3:= F_WORD(tTime.wDay),
            arg4:= F_WORD(tTime.wHour),
            arg5:= F_WORD(tTime.wMinute),
            arg6:= F_WORD(tTime.wSecond),
            sOut=> sDateTimeString);
        
        (*-----------------------------------------------------------------------*)
        
        (*Create the SQL-INSERT command*)
        FB_FormatString1(
            sFormat:= 'INSERT INTO tbl_Test VALUES($'%S$',%F,%F,%F,$'%S$')',
            arg1:= F_STRING(sDateTimeString),
            arg2:= F_REAL(TestValue1),
            arg3:= F_REAL(TestValue2),
            arg4:= F_REAL(TestValue3),
            arg5:= F_STRING(TestValue4),
            sOut=> sInsertString,
            bError=> bError,
            nErrId=> nErrid);
        
        (*-------------------------------------------------------------------------*)
        
        (*Write the record to the database*)
        FB_DBRecordInsert1(
            sNetID:=,
            hDBID:= 1,
            sInsertCmd:= sInsertString,
            bExecute:= bStartstopInsert,
            tTimeout:= T#15s,
            bBusy=> bBusyInsert,
            bError=> bErrInsert,
            nErrID=> nErridInsert,
            sSQLState=> stSQLStateInsert);


(*    eSQL_SELECT:
        (*Read one record from the database*)
        sSelectString:= 'SELECT * FROM tbl_Test';
        FB_DBRecordArraySelect1(
            sNetID:= , 
            hDBID:= 1, 
            pCmdAddr:= ADR(sSelectString), 
            cbCmdSize:= SIZEOF(sSelectString), 
            nStartIndex:= nRecIndex, 
            nRecordCount:= 1, 
            pDestAddr:= ADR(stRecord), 
            cbRecordArraySize:= SIZEOF(stRecord), 
            bExecute:= bStartStopSelect, 
            tTimeout:= T#15S, 
            bBusy=> bBusySelect, 
            bError=> bErrorSelect, 
            nErrID=> nErrIDSelect, 
            sSQLState=> stSQLStateSelect, 
            nRecords=> nRecordCount);        *)
END_CASE


bStartstopInsert := 0;

Das Auslesen von Daten habe ich auskommentiert ...

So, und wo ich gerade den Code durchgehe - sehe ich, dass ich "tbl_test" noch durch meine "TestTable" hätte ersetzen müssen :-?

Ob das wohl der (einzige) Fehler ist?

Der Quellcode wird ansonsten vollständig übersetzt und auch der Insert-String wird ordentlich zusammengesetzt.

Bei einem anderen Problem hatte man mir geraten, erstmal das Beckhoffbeispiel zum laufen zu bringen und das wollte ich hierbei auch gerne tun.

Gruß
duese1990
 
SQL4Automation klingt wirklich interessant, da es sich allerdings um ein Hochschulprojekt handelt, muss wahrscheinlich erst die Welt untergehen bevor ich so etwas bekommen würde ;).

Also di Bibliothek kannst du gratis herunterladen. Einfach mal die Demo herunterladen. Wie gesagt, das einzige was dich kosten würde wäre ein Connector der einfach die Verbindung von SPS und Datenbank vereinfacht. Ich denke mal den brauchst du nicht, in anbetracht dessen was du schon geschaffen hast solltest du das auch einfach so schaffen. ;)

Ich werd mir deinen Code morgen mal anschauen. Aber ich seh jetzt schon dass das einiges an Arbeit wird...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich probiere am Donnerstag mal, ob es funktioniert, wenn ich die richtige Tabelle im Quellcode angebe - so konnte es ja nicht laufen.
Vlt. war das ja schon der einzige (blöde) Flüchtigkeitsfehler.

Du darfst Dir mit der Kontrolle also auch ruhig bis Donnerstag/Freitag Zeit lassen - nicht das Du deine Zeit umsonst investierst.

Ich denke der Code sollte an sich OK sein - ist ja bis auf die Taster-Abfrage, Datenbank-ID und die XML-Deklaration original Beckhoff.

Ich gebe Bescheid, ob die Tabellenangabe der Fehler war!

Bis hierher aber schonmal Danke!
duese1990
 
Einfach ein "Danke"-Daumen und ich bin glücklich. ;)

Ne, Spass beiseite, wär natürlich gut wenns das war, hab das gerade im kurzen Überblicken übersehen (Naja, war ja auch schon wieder 22:00 Uhr). Hoffe es funktioniert... :D
 
Da täuschst du dich duese1990. An Hochschulen geben wir kostenlose Lizenzen ab, falls SQL4automation für Ausbildungszwecke verwendet wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Moin,

hab natürlich vergessen mich zurück zu melden.

Es funktioniert jetzt einwandfrei mit der TwinCAT Bibliothek!
Mein Fehler bzgl. des Tabellennamens war tatsächlich das Problem.

@rudl: Ok, das ist natürlich nicht schlecht! In diesem Fall wird das Endprodukt jedoch industriell eingesetzt.

Gruß
duese1990
 
Wo muss die XML gespeichert werden.
Hat einer ein Beispielprojekt für mich ? Versuche gerade mit TwinCAT 3 eine Verbindung ohne Databaseserver hin zu bekommen.
 
Zurück
Oben