r2k-in-the-vortex
Hullo, so in summary, what would it take to crossbreed OpenPLC with EtherCAT?

Some background.
Where I'm coming from we are using Beckhoff TwinCAT running on Windows PC(achieving realtime with some clever voodoo using Intel VT-x) and controlling everything over EtherCAT and talking to non-realtime part of the system over Ads(realtime message router that TwinCAT is built around). Very similar to CodeSys.

Now I have no illusions that OpenPLC could approach practical usefulness of these proprietary systems any time soon, but one can dream, no?

The motivation is clearly there, TwinCAT costs ~600-700€ per machine, no bulk discounts. Build thousands of machines and it adds up to a pretty penny. You can run stuff with trial licences for hobby purpose, you just need to manually renew the licence every now and then, but for actual machines, you need to pay a significant amount.

The beauty of EtherCAT is that you can get IO modules of any kind imaginable from many sources, all you really need is a free NIC on the PC and Ethernet cables to chain it all up. It scales like nobodies business and its properly realtime. You can even do safety over EtherCAT, but that is another topic entirely.

For the slave modules EtherCAT is generally implemented in hardware, ASIC-s or FPGA-s, for master, if its PC you need an EtherCAT driver. As far as I know that's all available open source.

So, how to mate EtherCAT to OpenPLC? Where to start?
Quote 0 0
r2k-in-the-vortex
Right, whatever the software integration ends up being, first a test setup is clearly needed.
Easy enough, I slapped together some parts and made a blinky led type of setup
Test setup.png 
Made the most rudimentary possible PLC program for it(in TwinCAT not OpenPLC)
Program.png 
And here is the result, pretty much what you would expect


Later today I'll try to get the modules running with  https://github.com/OpenEtherCATsociety/SOEM
Once I have that much, working towards OpenPLC/EtherCAT integration should be possible.
Quote 0 0
thiagoralves
Hi there,

This seems like a very interesting idea. I'm not very familiar with EtherCAT, but I've always heard about its great real time capabilities. I honestly don't think it would be a huge challenge to integrate EtherCAT with OpenPLC. OpenPLC has a modular I/O structure. It follows the Modbus model for data I/O: digital outputs (coils), digital inputs (input status), analog output (holding registers), analog input (input registers). There are 4 global buffers, one for each different data type. All that need to be done is sync those buffers with the EtherCAT frames, to control the slave devices. OpenPLC has special functions to do that (initializeHardware() and updateBuffers()). Take the blank.cpp driver (github here) as example inside the hardware_layers folder. You just need to put whatever code is required to initialize the library under initializeHardware(), and then put the sync code under updateBuffers(). OpenPLC will call initializeHardware() when it is loading up, and then will continuously call updateBuffers() at every scan cycle.

I was taking a look at the SOEM library, it seems solid, although it runs on a relatively old Linux kernel (2.6). I haven't tried to run OpenPLC on the 2.6 kernel, but I don't foresee any big challenges in doing it. It should run fine. Let me know how your experiments are going.


Happy coding!

Thiago Alves
Quote 0 0
r2k-in-the-vortex
Well the SOEM test was a success, after quite a bit of head scratching.
Simple_test program they have as an example totally works and after a bit of tweaking even duplicates the Blinky LED behavior shown above, tho no PLC is involved at this state.
I'm currently working on Windows actually, SOEM doesn't seem to have an issue with that.
I'll see what I can pull off, thanks for the advice on starting with blank driver.
Quote 0 0
thiagoralves
Putting SOEM to work with OpenPLC under windows might be a little bit more challenging. OpenPLC is essentially a posix application. It runs on windows over a linux (actually it is posix) environment called Cygwin. Ideally you should install SOEM under Cygwin following the linux instructions on the github (https://github.com/OpenEtherCATsociety/SOEM). If it installs fine, then you're good to go.
Quote 0 0
r2k-in-the-vortex
Yeah.. it doesn't compile under CygWin, getting its fingers to the nic is a problem, on windows it uses wpcap, on linux it gets access directly, CygWin is sort of Linux, but not really when it comes to nic access, it still has to go through windows so wpcap would be needed.
I'll dig out an old laptop and put actual Linux on it, should work better.
Quote 0 0
thiagoralves
Yeah, I didn't know it had to dig that deep on the nic. Cygwin is just a posix compatibility layer, a bunch of dlls that translate posix system calls to windows system calls. It doesn't do anything with the hardware. If a program doesn't play by the rules (aka system calls), it won't work.

You can start experimenting on a VM, like VMware or virtualbox (I highly recommend VMware over virtualbox, but you can choose whatever). I believe that a VM will be easier to setup and won't require you to format you laptop. You might loose the real time ability running on top of a VM, but it is just an experiment anyway, right? Then, if it works in the Linux VM, it might run on a Raspberry Pi as well, and that's when it starts to get interesting... [smile]
Quote 0 0
r2k-in-the-vortex
EtherCAT completely bypasses TCP/IP stack so yeah, it needs to write raw packets to nic.
I did end up going with the VirtualBox route(had it installed already). Everything worked just fine on my old laptop, but, eh its old slow etc. As for the RT impact, as long as I'm running it on generic OS, its not RT anyway, virtualization or not makes little difference.

In any case, I did get EtherCAT up and operational with OpenPLC, sort of. Didn't do anything on the PLC code part yet, so the EtherCAT frames are running, devices are in OP mode, but not doing much of anything yet.
I need to think a bit more on how to do configuration and mapping properly. And the code needs a lot of cleanup before its presentable.
Quote 0 0
thiagoralves
About configuration and mapping, you might want to copy the method I used for the Modbus Master driver. I have a .cfg file that has all the slave devices configuration and mapping to OpenPLC internal variables. My modbus master driver parses this .cfg file and creates a data structure that contains this information. It might not be the best way out, but it is a good alternative. I plan to improve that in the future by integrating some GUI screens on PLCopen Editor that will automatically generate the .cfg files for the user. Check the modbus master driver page here:  http://www.openplcproject.com/getting-started-modbus-io
Quote 0 0
r2k-in-the-vortex
Heya, so I got mapping working as far as booleans go.

But only booleans. Code is available at my fork  https://github.com/r2k-in-the-vortex/OpenPLC_v2
I'll see if I can figure out how the int buffers work, I tried at some point, but they didn't seem to update data from PLC, probably my PLC side code was off.

I'm not sure I get the logic, why booleans and int/analog are in separate buffers anyway.
Maybe I'm missing something, but what happens if you want to IO with a struct, say for drive control, linking bunch of stuff is tedious, saying this whole block of memory goes there is easy.
Or if you have some non-rt comms protocol piggybacking on EtherCAT and you need to exchange its frames.
Or how do you link stuff up, if you want to have X software components controlling Y devices

The way it works in TwinCAT is easy, all the components are linked to a realtime router/data transfer layer,
each one exposing in/out images and the router has a list of data transfers it need to get done.
The router simply copies the data cyclically.

E.g.
entry z: from PLC.Out offst X.x copy N.n bytes to DevZ.In offst Y.y
X.x = 0.1 bytes meaning one bit, its possible to have weird combos like 2.1 or something.
not really necessary, but you might have some weird device that has say 12 bits of analog data and 4 control bits all stuffed into 2 bytes.
Linking logic.png 
The major benefit is that you can just keep adding components to the router,
want to have 10 copies of PLC running and connecting to 10 different devices(EtherCAT + MODbus + Something else...) on same system? Sure, no problem.
Debug data is also exposed to the router and there is a non-realtime TCP component attached,
so you can connect with HMI, monitor the PLC from IDE, control breakpoints, do step by step etc.

All that fancy stuff is maybe too much short term, but creating such a common data transfer layer might be a good idea.
Something to think about.
Quote 0 0
thiagoralves
Excellent work! I took a quick glimpse at your code and it seems to follow exactly the structure of the rest of OpenPLC code, including the build scripts and everything. Very well done, thanks! 

I have the buffers separated because I wanted OpenPLC to have different address spaces for each data type. Some PLCs have just one block of memory so that depending on where you write the data it can be digital output or analog output or a mix between both. I just think this could be confusing for the users.

I don't know exactly how EtherCAT works, but I'm pretty sure you already figured out how OpenPLC works. If there is a way to directly read and write analog data to EtherCAT devices, you can just follow the same pattern you did for digital output and it should be fine.
Quote 0 0
r2k-in-the-vortex
Yeah, I got IEC_UINT read writes working, I also added IEC_SUINT and IEC_DUINT while i was at it.
Matiec spits them out just fine, but glue generator didn't know what to do with them.
Analog inputs worked in any case, but I didn't have any analog output modules to try so I just wrote SINT to 8-DigitalOutputs module and that worked just fine.

Next up is the challenge of getting a stepper driver working 
https://www.beckhoff.com/english.asp?ethercat/el7031.htm
[EL7031__web]
But to do that I need to implement PDO mapping first,
for some of the more complex EtherCAT modules like motor drivers there is extra configuration that needs to be written before IO operations start.

EtherCAT isn't really that complicated, if you have proper software to work with it, it can be an outright wonder.
Its really fast and easy to get even complex machines up and running and its about as foolproof as you can get.
Only way I have ever managed to mess things up was when I implemented some of the slave electronics myself, that resulted in some communications instability nightmares.
https://upload.wikimedia.org/wikipedia/commons/8/8f/EthercatOperatingPrinciple.webm
Quote 0 0
r2k-in-the-vortex
Good news! It works, sort of.
The stepper driver however is touchy about communications quality and that isn't helped by Linux virtualization.
So getting it to start up and enter OP mode is a bit of a lottery.
If it does go to OP mode it works however, tho SOEM keeps throwing out complaints whenever EtherCAT packets are out of sync.

I'll have to see if I can do anything about that.
If not i'll guess I'll let it be for a while, it should work properly on a RT system and other slaves don't have a problem with it, just the stepper driver.

Manually writing the conf files and IO linking is however rather tedious and error prone, next I'll see if I can make it a bit more convenient.
Quote 0 0
ErazorVIP
Hello,
someone can help me how i get my Ethercat EK1100 working on my OpenPLC?

The openplc is running  - but how i can add the ethercat libary and else...


Quote 0 0
r2k-in-the-vortex
Hi Erazor, I think my work was never merged back to OpenPLC master, but the code I linked still works https://github.com/r2k-in-the-vortex/OpenPLC_v2
There should be a working example there with digital IO-s, analog input and stepper motor output if I remember correctly, so that's the basics covered. The key is getting SOEM driver running on your NIC, I'm not sure I remember all the details on that, but SOEM code has it's own examples and instructions on how to go about it. Try to rebuild the entire thing and see how it goes. If you get stuck on something specific ask.
Quote 0 0