|
| 1 | +#include <QGuiApplication> |
| 2 | +#include <QQmlApplicationEngine> |
| 3 | +#include <QQmlContext> |
| 4 | +#include <QDebug> |
| 5 | + |
| 6 | +// qads "library" headers |
| 7 | +#include <tc3manager.h> |
| 8 | +#include <tc3value.h> |
| 9 | + |
| 10 | +// this header is required for all examples, one could do without this, |
| 11 | +// but for large scale projects an object like this is useful |
| 12 | +#include "plcdriver.h" |
| 13 | + |
| 14 | +// this header is used for example 2, where complete structs are |
| 15 | +// read and write, respectively. In large scale projects, a header |
| 16 | +// like this should be generated (i.e. by parsing Twincat3's TMC file |
| 17 | +// and generating C++ code from it) |
| 18 | +#include "plcdef.h" |
| 19 | + |
| 20 | +int main(int argc, char *argv[]) |
| 21 | +{ |
| 22 | + QGuiApplication app(argc, argv); |
| 23 | + |
| 24 | + PlcDriver data("10.100.20.228.1.1:851", &app); |
| 25 | + Tc3Manager* manager = data.manager(); |
| 26 | + |
| 27 | + |
| 28 | + // EXAMPLE 1: single variable access |
| 29 | + // change something on the PLC with the set method |
| 30 | + qDebug() << manager->value("MAIN.variable")->get(); |
| 31 | + manager->value("MAIN.variable")->set("connected to plc"); |
| 32 | + qDebug() << manager->value("MAIN.variable")->get(); |
| 33 | + |
| 34 | + // EXAMPLE 2: struct variable access |
| 35 | + // read "complex" struct from plc |
| 36 | + // change something in the struct and write it to the plc |
| 37 | + // read the struct again and let's check, if we actually change something |
| 38 | + Tc3Value *exampleStruct = manager->value("MAIN.struct1", sizeof(Plc::ExampleStruct)); |
| 39 | + Plc::ExampleStruct exampleStructData = exampleStruct->get<Plc::ExampleStruct>(); |
| 40 | + |
| 41 | + qDebug() << "Initial value" << exampleStructData.sub1.sub2.integer1; |
| 42 | + |
| 43 | + exampleStructData.sub1.sub2.integer1 += 1; |
| 44 | + exampleStruct->set<Plc::ExampleStruct>(exampleStructData); |
| 45 | + |
| 46 | + exampleStructData = exampleStruct->get<Plc::ExampleStruct>(); |
| 47 | + qDebug() << "New value" << exampleStructData.sub1.sub2.integer1; |
| 48 | + |
| 49 | + |
| 50 | + // EXAMPLE 3: QML example |
| 51 | + // Primitive datatypes (INT, DINT, REAL, ...) - where one can use Tc3Manager::AutoType |
| 52 | + // can be bound to properties within QML |
| 53 | + qmlRegisterType<Tc3Value>("Tc3Value", 1, 0, "Tc3Value"); |
| 54 | + qmlRegisterType<PlcButton>("PlcButton", 1, 0, "PlcButton"); |
| 55 | + qmlRegisterType<PlcAnalogIo>("PlcAnalogIo", 1, 0, "PlcAnalogIo"); |
| 56 | + |
| 57 | + QQmlApplicationEngine engine; |
| 58 | + QQmlContext* context = engine.rootContext(); |
| 59 | + |
| 60 | + // Make generic read/write access to plc available within qml |
| 61 | + context->setContextProperty("plcDriver", &data); |
| 62 | + |
| 63 | + // Make qml aware of two buttons - each could start a sequence on the plc |
| 64 | + PlcButton btnStartMotor(manager->value("MAIN.btnStartMotor", Tc3Manager::AutoType), &data); |
| 65 | + PlcButton btnStopMotor(manager->value("MAIN.btnStopMotor", Tc3Manager::AutoType), &data); |
| 66 | + context->setContextProperty("btnStartMotor", &btnStartMotor); |
| 67 | + context->setContextProperty("btnStopMotor", &btnStopMotor); |
| 68 | + |
| 69 | + // Editable analog output |
| 70 | + PlcAnalogIo nominalMotorSpeed(manager->value("MAIN.nominalSpeed", Tc3Manager::AutoType), &data); |
| 71 | + context->setContextProperty("nominalMotorSpeed", &nominalMotorSpeed); |
| 72 | + |
| 73 | + // Display the current value of an analog input with qml (this is readonly, see qml code) |
| 74 | + PlcAnalogIo actualMotorSpeed(manager->value("MAIN.actualSpeed", Tc3Manager::AutoType, Tc3Manager::NotificationType::Cycle, 100, 1000), &data); |
| 75 | + context->setContextProperty("actualMotorSpeed", &actualMotorSpeed); |
| 76 | + |
| 77 | + // Stress QML with random values, that should update the corresponding ui element whenever a change occurs |
| 78 | + // parameters 0,1000 forces to receive every change - you wouldn't want to do this in real life applications, |
| 79 | + // also for actual applications, one would implement a QModel for something like that, but we keep it simple here |
| 80 | + QVector<PlcAnalogIo*> randval; |
| 81 | + for(int i=0; i<10; ++i) |
| 82 | + { |
| 83 | + randval << new PlcAnalogIo(manager->value(QString("MAIN.randval[%1]").arg(i), Tc3Manager::AutoType, Tc3Manager::NotificationType::Change, 50, 200), &data); |
| 84 | + context->setContextProperty(QString("randval%1").arg(i), randval[i]); |
| 85 | + } |
| 86 | + |
| 87 | + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); |
| 88 | + if (engine.rootObjects().isEmpty()) |
| 89 | + return -1; |
| 90 | + |
| 91 | + return app.exec(); |
| 92 | +} |
| 93 | + |
0 commit comments