EtherCAT.NET icon indicating copy to clipboard operation
EtherCAT.NET copied to clipboard

Trouble accessing input bits

Open BennyBread opened this issue 2 years ago • 5 comments

First off all thanks for the great library. I managed it to make it runnable. But now I have trouble accessing my inputs and outputs through the memorymapping.

I use an hilscher NIC RE 50 module which has both an input area and an output area. The inputs have an offset address of 1000, the outputs 2000

Lets say I want to read From the outputs (sdoindex 2000) Byte no. 8 Bit no. 2.

How to do this?

In the SlavePdos I can see that the 6th pdo is the start of the outputs so I assume this has address 2000. Now I try to get the correct offset:

const int outputPdoIndex = 6;  <== first Output
const int channel = 8;
var bitOffset= SlavePdos[outputPdoIndex].Variables[channel].BitOffset;
var channel = MemoryMappingOutputs[0] & (1 << bitOffset);
var value = (byte)BitConverter.ToChar(channel.ToByteArray(), 0);

But the value is always false no matter what byte and bit offset I ask for.

I 've seen that in soemwrapper there is a function ecx_SDOread of which the parameter sdoIndex is the addess to read.

when using ethercat-explorer (https://sourceforge.net/p/ethercat-explorer/svn/HEAD/tree/) which uses also semwrapper but oviously a different version? I can query address 2000 and get a pretty long byte array in which some bytes do have values. This code is calling ecx_sdoread as well...

So. how can I achieve to read some bool or short from an defined offset??

Any help highly appreciated!

Regards, Benny

BennyBread avatar Apr 22 '22 13:04 BennyBread

Do you have the ESI file available? I could not find it for download.

According to https://www.ethercat.org/download/documents/EtherCAT_Device_Protocol_Poster.pdf there are no output data at offset 1000 (hex?). The output data should begin at offset 0x7000:

image

In your question you are mixing SDO and PDO, I am not sure what you really want to read. SDOs are for configuration (before startup) and PDOs contain the process data (e.g. measurement data).

I don't know where your MemoryMappingOutputs array comes from, so maybe the sample helps you to get access to I/O map:

https://github.com/Apollo3zehn/EtherCAT.NET/blob/51f59a8a3e95104eeae136ac4a626fa295a34445/sample/SampleMaster/Program.cs#L126

From there you can continue extracting the right bit.

Apollo3zehn avatar Apr 25 '22 07:04 Apollo3zehn

Thanks for your reply. I didn't find the esi file on the internet. but uploaded it here: ESI-XML File for Hilscher NIC 50-RE ECS V2.2.X

Sorry for mixing up sdo and pdo. I meant pdo of course.

the MemoryMappingOutputs comes from my code. I wrote this because I detected that the outputs start at 7th pdo:

private const int OutputPdoIndex = 6;
...
var variableCh1 = SlavePdos[0].Variables.First();
var variableCh6 = SlavePdos[OutputPdoIndex].Variables.First();
// get memory address of inputs
MemoryMappingInputs = (int*)variableCh1.DataPtr.ToPointer();
// get memory address of outputs
MemoryMappingOutputs = (int*)variableCh6.DataPtr.ToPointer();

I wrote a method inside my class based on DigitalOut with some modifications to read the outputs of the device as bool value

        private bool GetBoolOutputValue(byte input, byte bitNumber)
        {
            var slaveVariable = SlavePdos[OutputPdoIndex].Variables[input];
            var idx = slaveVariable.Index;
            var subIdx = slaveVariable.SubIndex;

            var byteArray = new byte[8];
            EcUtilities.SdoRead(MasterContext, Slave.SlaveIndex, idx, subIdx, ref byteArray);
    
            Console.Write(BitConverter.ToString(byteArray) + @" => ");

            var outputValue = (byteArray[0] & 1 << bitNumber) == 1;
            return outputValue;
        }

I call e.g. GetBoolOutputValue(7, 2) which should be TRUE, but always returns FALSE.

according to the documentation I have 7.2 should be "READY" and be true. (I verified this using a beckhoff plc)

SlavePdos[6].Variables[7].Index = 2000 and SlavePdos[6].Variables[7].SubIndex = 8 in my case. So I assume the index 2000 is correct.

I'm kind of lost now and don't know how I can continue because no matter what input I query all are FALSE. :-(

I can upload the full test code if you want to.

BennyBread avatar Apr 25 '22 10:04 BennyBread

You cannot use SdoRead to read PDO data (at least I have never seen this). So your method might not work:

image

You could instead try to print the full IO map. The IO map is not directly accessible but the start pointer of the IO map is equal to the pointer of the very first variable in the system. Please run the following code once after master.Configure(rootSlave); to print the IO map content. Is there any non-zero data?

void PrintIOMap()
{
    unsafe
    {
        var ioMapPtr = slaves.First().DynamicData.Pdos.First().Variables.First().DataPtr.ToPointer();
        var ioMap = new Span<byte>(ioMapPtr, settings.IoMapLength);

        for (int i = 0; i < ioMap.Length; i++)
        {
            if (ioMap[i] != 0)
                Console.WriteLine($"IO map byte {i} is non-zero ({ioMap[i]})");
        }
    }
}        

What is this "READY" value? When should it be true, i.e. what are the preconditions? Is it for example necessary for the slave to be in the EtherCAT OP state to be "READY"?

Apollo3zehn avatar Apr 26 '22 07:04 Apollo3zehn

Oh sh*t! I made the same error again. 🤦‍♂️🤦‍♂️ I discovered that by myself a minute ago. Shame on me. I'll try out your code right now.

BennyBread avatar Apr 26 '22 09:04 BennyBread

Thats what I get.

IO map byte 4 is non-zero (1) IO map byte 6 is non-zero (2) IO map byte 7 is non-zero (36) IO map byte 56 is non-zero (200) IO map byte 57 is non-zero (83) IO map byte 58 is non-zero (2) IO map byte 59 is non-zero (66) IO map byte 60 is non-zero (36) IO map byte 3880 is non-zero (206) IO map byte 3881 is non-zero (209) IO map byte 3882 is non-zero (245) IO map byte 3883 is non-zero (237) IO map byte 3885 is non-zero (5) IO map byte 3887 is non-zero (144)

So my slave attatched actually deliveres data.

Btw. the READY value is configured to reflect the state of my device when it's "ready for action".. The device is ready when its conditions are fulfilled and this is the case.

The ethercat slave itself is in operational state. I checked this using this:

var state = master.GetState(1); // first slave
Console.WriteLine($"EtherCAT Slave state is {state}");

Prints "Operational"

I will try to access the data inside the PDO Variables to access the actual bits I need and come back here..

BennyBread avatar Apr 26 '22 10:04 BennyBread