In the last tutorial, we configured the connection between TwinCAT and MongoDB. This time, we will use the TF6420 Library to access MongoDB data.
Let’s start!
Reference Link
Function Block
This section introduces the Function Block used in this article.
FB_NoSQLQueryBuilder_DocumentDB
Function Block for defining a query on a DateBase; the Query is sent in FB_NoSQLQueryEvt, so there is no need to call the Build Method directly.
VAR_INPUT
Name | Type | Descirption |
eQueryType | E_DocumentDbQueryType | Type of query submitted to the database. |
sCollectionName | T_ MAXSTRING | Name of Collections to be Queried |
pQueryOptions | POINTER TO BYTE | Specifies the Pointer address of the QueryOptions. |
cbQueryOptionsr | UDINT | Size of QueryOptions |
E_DocumentDBQueryType
{attribute ‘qualified_only’} TYPE E_DocumentDbQueryType : ( InsertOne := 1, InsertMany := 2, UpdateOne := 3, UpdateMany := 4 , Find := 5, Aggregation := 6, Delete := 7, DeleteMany := 8, CreateCollection := 9, DropCollection := 10 ); END_TYPE |
T_QueryOptionDocumentDB_Insert
TYPE T_QueryOptionDocumentDB_Insert STRUCT pDocuments: POINTER TO BYTE; cbDocuments: UDINT; END_STRUCT END_TYPE |
Name | Type | pDocuments |
pDocuments | POINTER TO BYTE | Specify the address of the Documents variable to be added to Collections. |
cbDocuments | UDINT | Data size of Documents variable. |
FB_NoSQLQueryEvt
Function Block for executing a NoSQL Database Query, used by entering it in the Method of the QueryBuilder Function Block.
VAR_INPUT
Name | Type | Descirption |
sNetID | T_AmsNetID | AMS Network ID, leave it Empty if Local |
tTimeout | TIME | Time setting before the FB is canceled for execution. |
VAR_OUTPUTS
Name | Type | Descirption |
bBusy | BOOL | 1 = FB is running |
bError | BOOL | 1 = FB has an error. |
ipTcResult | Tc3_EventLogger.I_TcMessage | TwinCAT 3 EventLogger Interface for displaying FB execution results in Message. |
Properties:eTraceLevel
Name | Type | Access | Descirption |
eTraceLevel | TcEventSeverity | Get, Set | 1=FB specifies the Severity of the events being performed. Only events with a weighting higher than this value are sent to the TwinCAT system. Specifies the importance of the Event. Only events with a Severity higher than this value are sent to the TwinCAT System. |
METHODS:Execute
A Method to send the Query created in QueryBuilderFB to the Database.
METHOD Execute : BOOL VAR_INPUT hDBID: UDINT; iNoSQLQueryBuilder: I_NoSQLQueryBuilder; END_VAR |
VAR_INPUT
Name | Type | Descirption |
hDBID | UDINT | ID of the database setting configured. |
iNoSSQLQueryBuilder | I_NoSQLQueryBuilder | QueryBuilder FB. |
Return Value
Name | Type | Descirption |
Execute | Bool | Method execution result; True=Method execution successful. |
METHODS:ExecuteDataReturn
The Query created in QueryBuilderFB is sent to the Database; FB_NoSqlResultEvt is passed to read the Data Record returned from the Database.
METHOD ExecuteDataReturn : BOOL VAR_INPUT hDBID : UDINT; iNoSSQLQueryBuilder: I_NoSQLQueryBuilder; pNoSQLResult: POINTER TO FB_NoSQLResultEvt; END_VAR |
VAR_INPUT
Name | Type | Descirption |
hDBID | UDINT | ID of the database setting configured. |
iNoSSQLQueryBuilder | I_NoSQLQueryBuilder | QueryBuilder FB. |
pNoSQLResult | POINTER TO FB_NoSSQLResultEvt | Instance Pointer in FB_NoSQLResultEvt, used to read Methods results |
Return Value
Name | Type | Descirption |
ExecuteDataReturn | BOOL | Method execution result: True=Method execution success. |
nDataCount | UDINT | Number of records returned |
FB_NoSQLResultEvt
When the ExecuteDataReturn Method is called on a FB to read a buffered record, you must first retrieve the Data Record from the Database using FB_NoSQLQueryEvt. FB_NoSQLResultEvt. Once initialized, it can be read back as a PLC structure or a string.
VAR_INPUTS
Name | Type | Descirption |
sNetID | T_AmsNetID | AMS Network ID, leave it Empty if Local |
tTimeout | TIME | Time setting before the FB is canceled for execution. |
VAR_OUTPUTS
Name | Type | Descirption |
bBusy | BOOL | 1 = FB is running |
bError | BOOL | 1 = FB has an error. |
ipTcResult | Tc3_EventLogger.I_TcMessage | TwinCAT 3 EventLogger Interface for displaying FB execution results in Message. |
Properties:eTraceLevel
Name | Type | Descirption |
eTraceLevel | TcEventSeverity | 1=FB specifies the Severity of the events being performed. Only events with a weighting higher than this value are sent to the TwinCAT system. Specifies the importance of the Event. Only events with a Severity higher than this value are sent to the TwinCAT System. |
Properties:nDataCount
Name | Type | Descirption |
nDataCount | UDINT | Number of Data Records retrieved from Database |
Methods:ReadAsString
This method reads a specified number of Records from data cached in the TwinCAT Database Server and specifies an array of strings from which this data is copied as JSON.
VAR_INPUTS
Name | Type | Descirption |
nStartIndex | UDINT | Index of the first Record to be read. |
nRecordCount | UDINT | Number of Records to be read. |
pData | POINTER TO BYTE | Address of TwinCAT Runtime string array to which Record is written Offset |
cbData | UDINT | Size of the TwinCAT Runtime string array to which the Record is written. |
nMaxDocumentSize | UDINT | Maximum size of JSON document taken from pData. |
bDataRelease | BOOL | Delete cached data. |
Return Value
Name | Type | Descirption |
ReadAsString | BOOL | Method execution result: True=Method execution success. |
Method:ReadAsStruct
This method can read a specified number of records from the buffered result data and store them in a TwinCAT Runtime structure or array of structures; the Validation function of the Function Block can detect and react to data deviations.
VAR_INPUTS
Name | Type | Descirption |
nStartIndex | UDINT | Index of the first Record to be read. |
nRecordCount | UDINT | Number of Records to be read. |
pData | POINTER TO BYTE | Address of TwinCAT Runtime string array to which Record is written Offset |
cbData | UDINT | Size of the TwinCAT Runtime string array to which the Record is written. |
bValidate | BOOL | The returned data is compared with the pData structure array or adjusted as required. |
pNoSQLValidation | POINTER TO FB_NoSQLValidationEvt | Address of the Function Block FB_NoSQLValidationEvt that provides the information to be validated. |
nMaxDocumentSize | UDINT | Maximum size of JSON document taken from pData. |
bDataRelease | BOOL | Delete cached data. |
Return Value
Name | Type | Descirption |
ReadAsStruct | BOOL | Method execution result: True=Method execution success. |
METHOD:Release
This method can be used to release data cached by the TwinCAT Database Server.
Return Value
Name | Type | Descirption |
Release | BOOL | Method execution result: True=Method execution success. |
FB_NoSQLValidationEvt
This is a Function Block for reading the validation events and results generated when reading data in FB_NoSQLResultEvt. This Function Block is initialized in the CreateValidation method of NoSQLResult and finally refers to a call to the ReadAsStruct method.
VAR_INPUTS
Name | Type | Descirption |
sNetID | T_AmsNetID | AMS Network ID, leave it Empty if Local |
tTimeout | TIME | Time setting before the FB is canceled for execution. |
VAR_OUTPUTS
Name | Type | Descirption |
bBusy | BOOL | 1 = FB is running |
bError | BOOL | 1 = FB has an error. |
ipTcResult | Tc3_EventLogger.I_TcMessage | TwinCAT 3 EventLogger Interface for displaying FB execution results in Message. |
Properties:eTraceLevel
Name | Type | Access | Descirption |
eTraceLevel | TcEventSeverity | Get, Set | 1=FB specifies the Severity of the events being performed. Only events with a weighting higher than this value are sent to the TwinCAT system. Specifies the importance of the Event. Only events with a Severity higher than this value are sent to the TwinCAT System. |
Methods:GetIssues
Reads the validation events raised by the Function Block into an array of type T_MAXSTRING.
VAR_INPUTS
Name | Type | Descirption |
pData | POINTER TO BYTE | Address of TwinCAT Runtime string array to which Record is written Offset |
cbData | UDINT | Size of the TwinCAT Runtime string array to which the Record is written. |
bDataRelease | BOOL | Delete cached data. |
Return Value
Name | Type | Descirption |
GetIssues | BOOL | Method execution result: True=Method execution success. |
Methods:GetRemainingData
This method can be used to read the remaining data in JSON format after validation.
VAR_INPUTS
Name | Type | Descirption |
pData | POINTER TO BYTE | Address of TwinCAT Runtime string array to which Record is written Offset |
cbData | UDINT | Size of the TwinCAT Runtime string array to which the Record is written. |
cbDocument | UDINT | Document array size |
bDataRelease | BOOL | Delete cached data. |
Return Value
Name | Type | Descirption |
GetRemainingData | BOOL | Method execution result: True=Method execution success. |
METHOD:Release
This method can be used to release data cached by the TwinCAT Database Server.
Return Value
Name | Type | Descirption |
Release | BOOL | Method execution result: True=Method execution success. |
Implementation
We will now use TwinCAT’s TF6420 Library to access MongoDB data.
Flow
Here is the Flow.
DUT
This is the structure of the Query data to be sent to MongoDB in the program.
ST_SubStrucure
TYPE ST_SubStrucure : STRUCT Speed:LREAL; Position:LREAL; ErrorCode:LINT; END_STRUCT END_TYPE |
ST_MainStructure
TYPE ST_MainStructure : STRUCT Sensor1:LREAL; r32Array:ARRAY[0..2]OF LREAL; iArray:ARRAY[0..8]OF DINT; MotorData:ST_SubStrucure; END_STRUCT END_TYPE |
Program
This is the program.
PROGRAM MAIN VAR fbJson : FB_JsonSaxWriter; jsonDoc :SJsonValue; sJsonDoc :STRING(2000); sDocument : STRING(2000); END_VAR VAR nDBID: INT := 1; sNetID : STRING := ”; tTimer4SendQuery :TIME:=T#1S; TONReflesh :TON; r32SensorData :LREAL:=0.0; bError:BOOL; iStep:INT:=0; iCount:INT:=0; ArrayStuctureData : ARRAY [0..999] OF ST_MainStructure; END_VAR VAR //NoSQLFunctionBlock fbNoSQLQueryBuilder_DocumentDB: FB_NoSQLQueryBuilder_DocumentDB; fbNoSQLQuery: FB_NoSQLQueryEvt(sNetID := sNetID, tTimeout := TIME#15S0MS); fbNoSQLResult: FB_NoSQLResultEvt(sNetID := sNetID, tTimeout := TIME#15S0MS); fbNoSqlValidation : FB_NoSQLValidationEvt(sNetID := sNetID, tTimeout := TIME#15S0MS); //Optiotns InsertQueryOptions: T_QueryOptionDocumentDB_Insert; AggregationQueryOptions: T_QueryOptionDocumentDB_Aggregate; //Others InfoResult: I_TcMessage; sPipeStages : STRING(1000); END_VAR CASE iStep OF 0: InsertQueryOptions.pDocuments:= ADR(sDocument); InsertQueryOptions.cbDocuments:= SIZEOF(sDocument); fbNoSQLQueryBuilder_DocumentDB.eQueryType := E_DocumentDbQueryType.InsertOne; fbNoSQLQueryBuilder_DocumentDB.sCollectionName := ‘myCollection22’; fbNoSQLQueryBuilder_DocumentDB.pQueryOptions := ADR(InsertQueryOptions); fbNoSQLQueryBuilder_DocumentDB.cbQueryOptions := SIZEOF(InsertQueryOptions); iStep:=10; bError:=FALSE; 10: // fbJson.StartObject(); r32SensorData:=r32SensorData+0.01; IF r32SensorData > 99999.9 THEN r32SensorData:=0.0; END_IF fbJson.AddKeyLreal(key:=’Sensor1′,value:=r32SensorData); fbJson.AddKey(‘r32Array’); fbJson.StartArray(); fbJson.AddRawArray(‘123.1,444.5,512.3’); fbJson.EndArray(); fbJson.AddKey(‘iArray’); fbJson.StartArray(); fbJson.AddRawArray(‘123,1,5,6,7,8,9,0,111’); fbJson.EndArray(); fbJson.AddKey(‘MotorData’); fbJson.StartObject(); fbJson.AddKeyLreal(key:=’Speed’,value:=567.12334); fbJson.AddKeyLreal(key:=’Position’,value:=450.42); fbJson.AddKeyNumber(key:=’ErrorCode’,value:=9872); fbJson.EndObject(); fbJson.EndObject(); sJsonDoc := fbJson.GetDocument(); fbJson.ResetDocument(); iStep:=20; 20: sDocument:=sJsonDoc; IF fbNoSQLQuery.Execute(nDBID, fbNoSQLQueryBuilder_DocumentDB) THEN IF fbNoSQLQuery.bError THEN InfoResult := fbNoSQLQuery.ipTcResult; bError:=TRUE; iStep:=998; ELSE IF NOT fbNoSQLQuery.bBusy THEN iStep:=30; END_IF; END_IF END_IF 30: AggregationQueryOptions.pPipeStages := ADR(sPipeStages); AggregationQueryOptions.cbPipeStages := SIZEOF(sPipeStages); fbNoSQLQueryBuilder_DocumentDB.eQueryType := E_DocumentDbQueryType.Aggregation; fbNoSQLQueryBuilder_DocumentDB.sCollectionName := ‘myCollection22’; fbNoSQLQueryBuilder_DocumentDB.pQueryOptions := ADR(AggregationQueryOptions); fbNoSQLQueryBuilder_DocumentDB.cbQueryOptions := SIZEOF(AggregationQueryOptions); sPipeStages :='{$$match :{}}’; IF fbNoSQLQuery.ExecuteDataReturn(nDBID, fbNoSQLQueryBuilder_DocumentDB, pNoSqlResult:= ADR(fbNoSQLResult)) THEN IF fbNoSQLQuery.bError THEN InfoResult := fbNoSQLQuery.ipTcResult; bError:=TRUE; iStep:=997; ELSE iStep:=40; END_IF END_IF 40: IF fbNoSQLResult.ReadAsStruct(1, 10, ADR(ArrayStuctureData), SIZEOF(ArrayStuctureData), bValidate := TRUE, ADR(fbNoSqlValidation), bDataRelease:= TRUE) THEN IF fbNoSQLResult.bError THEN InfoResult := fbNoSQLResult.ipTcResult; bError:=TRUE; ELSE iStep:=50; END_IF END_IF 50: TONReflesh(IN:=TRUE,pt:=tTimer4SendQuery); IF TONReflesh.Q THEN TONReflesh(IN:=FALSE); iCount:=iCount+1; iStep:=0; END_IF END_CASE |
Result
Done!A new Collections called MyCollections22 has been created.
From Mongo
You can use this command to get the latest data from the MongoDB Shell.
db.myCollection22.find().sort({$natural:-1}).limit(10) |
Done!You saw the data issued by TwinCAT.
> db.myCollection22.find().sort({$natural:-1}).limit(10) { “_id” : ObjectId(“64aa662bbfe68217dc626f99”), “Sensor1” : 14.549999999999734, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6629bfe68217dc626f98”), “Sensor1” : 14.539999999999734, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6628bfe68217dc626f97”), “Sensor1” : 14.529999999999735, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6627bfe68217dc626f96”), “Sensor1” : 14.519999999999735, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6625bfe68217dc626f95”), “Sensor1” : 14.509999999999735, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6624bfe68217dc626f94”), “Sensor1” : 14.499999999999735, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6623bfe68217dc626f93”), “Sensor1” : 14.489999999999736, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6622bfe68217dc626f92”), “Sensor1” : 14.479999999999736, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa6620bfe68217dc626f91”), “Sensor1” : 14.469999999999736, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } { “_id” : ObjectId(“64aa661fbfe68217dc626f90”), “Sensor1” : 14.459999999999736, “r32Array” : [ 123.1, 444.5, 512.3 ], “iArray” : [ 123, 1, 5, 6, 7, 8, 9, 0, 111 ], “MotorData” : { “Speed” : 567.12334, “Position” : 450.42, “ErrorCode” : 9872 } } |
From TwinCAT
Data was taken from TwinCAT to MongoDB.
Download Project
You can download the project from this Link.
https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCAT_TF6420_ConnectWithMongoDB.tnzip