Skip to content

C++17 header only, driver library for manipulating IO-Link devices and masters. It is targeting all the IFM's IO-Link Masters and all of the IO-Link compatible devices regardless of the manufacturer.

License

Notifications You must be signed in to change notification settings

ekondayan/libiolink

Repository files navigation

libiolink


Description

C++17 header only, driver library for manipulating IO-Link devices and masters. It is targeting two categories of devices:

  • All the IFM's IO-Link Masters

  • All the IO-Link compatible devices(sensors, actuators, displays, etc.) regardless of the manufacturer.

The library provides drivers for most of IFM masters and a growing collection of drivers for IO-Link devices. The library not only allows you to use the available drivers, but also gives you the tools to implement them by yourself. Writing a driver for an IFM's master can be done in just a few minutes and writing a driver for an IO-Link compatible devices from scratch can be done even faster.

It is making heavy usage of C++ template system which gives big performance benefit for the runtime executable. The header only approach greatly simplifies the process of including it into other projects. The minimum C++ standard is ISO/IEC 14882 (C++17).

It is intended to be used in a several different ways:

  • Use available drivers for IFM masters

  • Use available drivers for IO-Link devices

  • Write you own driver for manipulating an IFM master

  • Write you own driver for manipulating IO-Link device

  • A mixture of all the above

The project is hosted on GitHub https://github.com/ekondayan/libiolink.

Dependencies

libiolink uses Niels Lohmann's JSON library which is hosetd on GitHub

https://github.com/nlohmann/json to parse requests and responses from/to the

master. It is already included in the project so no action is required on your

side. This is the only dependency and the rest is plain C++17. You can use this library in you project as an added benefit.

Usage

Override the GET and POST methods of InterfaceComm

The library does not provide a network layer to execute POST and GET requests to the master, so it needs to be implement separately. This is easily done by inheriting the iolink::iot::InterfaceComm and overriding the two virtual methods:

std::string_t httpGet(const iolink::string_t &adr) const override;
std::string_t httpPost(const iolink::string_t &json) const override;

Those two methods do one simple task - to execute a POST and a GET requests on

the master and return its raw response. This design decision was made for two reasons:

  • There is a plethora of networking libraries out there and there is no reason to duplicate their functionality

  • You may want to use one of your choice

  • You may wish to have more control over the execution of GET and POST. For example if you want to track the execution time or to count the requests

Instantiate a driver for the master

A code snippet worth a thousand words.

al1352::Device al1352(std::make_unique<Comm>());

Here Comm is your class that inherits form iolink::iot::InterfaceComm. The code above will create a driver instance for the AL1352 master. This is all you need to have full controll over the master.

Instantiate a driver for the device

Using only the masters driver is not of a much use, unless you plan to use only it's digital I/O interfaces. To read and write the IO-Link devices connected to the master, a device driver must be attached to a port on the master itself. This may sound complicate but it boils down to a single line of code ;)

auto o1d105_w = al1352.iolinkmaster.port3.iolinkdevice.driverAttach<O1D105>();

This will instantiate a driver and will also attach it to a port on the master, in this example port3. The variable o1d105_w is a weak pointer to O1D105 driver. To access the devices you have to cast the pointer to a shared pointer by calling o1d105_w.lock() on the weak pointer:

auto o1d105_drv = o1d105_w.lock();

This approach using weak pointers will save you from shooting yourself in the foot. For example if you delete the master's driver instance you will not be left with a dangling device drivers. Because of the tight integration between the device driver and the master driver, trying to access a dangling device driver will cause a crash.

Example:

if(auto o1d105_drv = o1d105_w.lock())
  auto power_cycles = o1d105_drv->power_cycles.read();

That's it and here comes the ...

Full blown example

For simplicity I will use the QT's library network module, but you can use whatever you like. Some good libraries are Qt, Boost, POCO, libcurl, and many others.

#include <QCoreApplication>
#include <QtNetwork>
#include "iolink/src/driver/master/al1352/device.h"
#include "iolink/src/driver/device/ifm/o1d105/o1d105.h"

class Comm final: public iolink::iot::InterfaceComm
{
    public:
        explicit Comm(const iolink::string_t &ip, uint16_t port = 80):
        InterfaceComm(ip, port)
        {
        }

        iolink::string_t httpGet(const iolink::string_t &adr) const override
        {
            if(adr.empty()) return string_t{};

            QNetworkAccessManager qnam;

            QNetworkRequest request(QUrl(QString::fromStdString(urlFromAddress(adr))));

            auto *reply = qnam.get(request);

            timer.start();

            while(!reply->isFinished()) QCoreApplication::processEvents();

            if(!reply->isFinished()) return string_t{};

            auto reply_data = reply->readAll();

            return reply_data.toStdString();
        }

        iolink::string_t httpPost(const iolink::string_t &json) const override
        {
            if(json.empty()) return string_t{};

            QNetworkAccessManager qnam;

            QNetworkRequest request(QUrl(QString::fromStdString(urlFromAddress())));
            request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");

            auto *reply = qnam.post(request, QByteArray::fromStdString(json));

            timer.start();

            while(!reply->isFinished()) QCoreApplication::processEvents();

            if(!reply->isFinished()) return string_t{};

            auto reply_data = reply->readAll();

            return reply_data.toStdString();
        }
};

int main(int argc, char *argv[])
{
    using namespace iolink;
    using namespace iolink::driver;
    using namespace iolink::master;

    QCoreApplication a(argc, argv);

    al1352::Device al1352(std::make_unique<Comm>("192.168.1.30"));

    auto sn = al1352.deviceinfo.serialnumber.getData();

    auto o1d105_w = al1352.iolinkmaster.port3.iolinkdevice.driverAttach<O1D105>();

    if(auto o1d105_drv = o1d105_w.lock())
    {
        auto pc = driver->power_cycles.read();
    }

    return 0;
}

Tutorials

In the tutorial section you can find a step by step guides how to:

  • create a driver for an IFM master

  • create a driver for an IO-Link device

  • simple usage of the available drivers

Download

You can download the project from GitHub using this command:

git clone https://github.com/ekondayan/libiolink.git libiolink

Install

In order to use libiolink, you just need to download and extract the header files into you project. In fact, the header files in the libiolink subdirectory are the

only files required to compile programs with the library. The header files

are cross platform. It is not necessary to use CMake or install

anything, just include the header files into your project.

License

Copyright (c) 2019-will2020 Emil Kondayan

This Source Code Form is subject to the terms of the Mozilla Public

License, v. 2.0. If a copy of the MPL was not distributed with this

file, You can obtain one at http://mozilla.org/MPL/2.0/.

Now what?

  • Head to the tutorials section

  • Head to the examples section

  • Head to the documentation

  • if you are feeling nerdy, dig into the source code :)

About

C++17 header only, driver library for manipulating IO-Link devices and masters. It is targeting all the IFM's IO-Link Masters and all of the IO-Link compatible devices regardless of the manufacturer.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published