Introducing libplctag.NET 1.0.0 - PLC communications via C#/VB
Tags: news, showdev
Published: 2020-09-21 07:38:39

We've released an open-source library that makes reading/writing tags to a PLC in C#/VB dead simple. It's available on [Github](https://github.com/libplctag/libplctag.NET) and [NuGet](https://www.nuget.org/packages/libplctag/).

#**Contents**
1. [What is a PLC?](#introduction)
2. [What is libplctag?](#libplctag)
3. [Why was libplctag .NET developed?](#libplctag.net)
4. [Enough talk, let's see some code!](#code)
5. [What's next?](#next)
6. [All the Thank Yous](#thanks)
7. [Github Repo](#github)


<a name="introduction"></a>
##**What is a PLC?**
For those of us in the industrial automation world we often work with hardware called PLCs (Programmable Logic Controllers). These are the de facto standard for low level control in nearly any manufacturing line whether it's assembling cars, sorting packages, or filling soda bottles. Common brands include Siemens Simatic S7, Rockwell Automation Allen-Bradley CompactLogic/ControlLogix, and Schneider Modicon. The library we're introducing today primarily supports Rockwell Automation's Allen-Bradley line - everything from their oldest models up to the current CompactLogix an ControlLogix offerings.

These PLCs use different and often proprietary methods of communicating over ethernet networks. In order to integrate them with the larger ecosystem of Manufacturing Operations Management it's required a Windows-based server running what's called an OPC server - essentially a protocol converter that reads/writes to the PLC using the proprietary protocol and makes it available to other systems over the standardized OPC protocol. Almost all OPC servers require a per installation license and often a license for the number of variables (tags in PLC lingo) you would like to read/write.


<a name="libplctag"></a>
##**What is libplctag?**
The actual low-level library is called [libplctag](https://github.com/libplctag/libplctag). It's a portable C library with a low memory footprint that runs on Linux/Mac/Windows/Android. At present, the library handles all the low-level encoding and decoding of CIP (Common Industrial Protocol AKA Ethernet/IP) implemented in various Allen-Bradley PLCs. It also handles Modbus TCP and there are plans to include other protocols and PLCs in the future. The library itself has been around since 2012 and is quite stable and used in many applications.

<a name="libplctag.net"></a>
##**Why was libplctag .NET developed?**
While C is a great language and very efficient, most programmers writing native or web applications rely on higher level languages. My language of choice is C#/dotnet these days and I've spent years using it to build programs that connect to PLCs and other industrial control systems. Unfortunately, these connections have always required either a commercially licensed C# library or an OPC server in order to communicate with the PLC. I started looking around for open-source options and came across the libplctag library via a couple of the C# wrappers that were floating around. None of the wrappers were very well documented and many were still using old versions of the lower level library. I reached out to the main C library developer and several of the wrapper maintainers to try to build a bigger community that I could help contribute to. Two of us got together, and with the help of the libplctag developer built a dotnet wrapper that includes all the features we wanted and thought should be expected in a dotnet library.
* Available on Nuget
* Self-contained - C DLL is extracted as part of dotnet DLL
* Compatible with .Net Standard (Core/Framework)
* Cross platform (Windows/Mac/Linux)
* Strongly typed
* Support Async/Await* 
* Usable in C# and Visual Basic .NET

\* _await/async is currently stubbed into the API via Task.Run due to some complexities with the C callback_

<a name="code"></a>
##**Enough talk, let's see some code!**
We've got quite a few [examples](https://github.com/libplctag/libplctag.NET/tree/master/src/Examples/CSharp%20DotNetCore) in our Github repo, but I'll show a quick example below.

The first thing to understand is that there must be a `Mapper` class to convert from the PLC datatype to the dotnet datatype. Luckily, we've included mappers for all the base PLC types (DINT, SINT, STRING, BOOL, etc) and provided an [example](https://github.com/libplctag/libplctag.NET/blob/master/src/Examples/CSharp%20DotNetCore/SequencePlcMapper.cs) for building a custom mapper for your own UDTs.

Here's a simple example for reading/writing a DINT. Note that the `myTag.Value` is typed as an `int` and not an `object`.
```C#
//Instantiate the tag with the proper mapper and datatype
var myTag = new Tag<DintPlcMapper, int>()
{
	Name = "PROGRAM:SomeProgram.SomeDINT",
	Gateway = "10.10.10.10",
	Path = "1,0",
	PlcType = PlcType.ControlLogix,
	Protocol = Protocol.ab_eip,
	Timeout = TimeSpan.FromSeconds(5)
};

//Initialize the tag to set up structures and prepare for read/write
//This is optional as an optimization before using the tag
//If omitted, the tag will initialize on the first Read() or Write()
myTag.Initialize();

//The value is held locally and only synchronized on Read() or Write()
myTag.Value = 3737;

//Transfer Value to PLC
myTag.Write();

//Transfer from PLC to Value
myTag.Read();

//Write to console
int myDint = myTag.Value;
Console.WriteLine(myDint);
```
Yeah, it's really that easy.

<a name="next"></a>
##**What's next?**
We finished all of the work that we deemed _necessary_ for an initial release. However, there is always more development to do. Here's some features/fixes that are upcoming:
* True async/await support from the lower libplctag library
* Background tag updates (read/writes on interval)
* Full discovery/listing of tags on a controller 

<a name="thanks"></a>
##**All the Thank Yous**
This has been my first real foray into open-source and it's been entirely in my spare time - so of course thanks to my family for being patient with me.

I was also really lucky to work with **timyhac** - a great C# developer that lives on nearly the exact opposite side of the globe from me. Doing code reviews with someone you've never met is quite the experience.

Finally, and most of all, I have to thank **Kyle Hayes** for the incredible libplctag base library *and* for being patient while the two C# devs asked all sorts of bothersome questions about C code and low level CIP protocol implementation.

<a name="github"></a>
##**Github Repo**
{% github libplctag/libplctag.net %}