Dave Long

Problems getting WinCC to read a Double

1 post in this topic

Dear reader,

I am writing a C# program using the library  ‘EasyModbus’ that needs to communicate with Siemens WinCC via the connection type ‘Modicon modbus’ I have written a version using the ‘float’ data type in WinCC and that works perfectly. Here my code fragment:

Method to convert ‘double’ to bytes in C#:

public static byte[] DoubleToModbusFloat(double value)
{
    byte[] bytes = new byte[4];
    float floatValue = (float)value;
    int intValue = BitConverter.ToInt32(BitConverter.GetBytes(floatValue), 0);

    bytes[0] = (byte)(intValue >> 24);
    bytes[1] = (byte)(intValue >> 16);
    bytes[2] = (byte)(intValue >> 8);
    bytes[3] = (byte)intValue;

    return bytes;
}


Call of the method and loading of the modbus registers in EasyModbus:

Bytes = PublicCode.DoubleToModbusFloat(TmpDbl);

int n = (int)ModbusStartAddress + ((i - 1) * 2);

mb.ModServer.holdingRegisters[n + 1] = (short)((Bytes[0] << 8) + Bytes[1]);
mb.ModServer.holdingRegisters[n + 2] = (short)((Bytes[2] << 8) + Bytes[3]);


So far so good – this works fine. But I also want to be able to use the ‘Double’ data type in WinCC because I sometimes need more precision than the 7 figures of the ‘float’. I thought it would simply be a case of doubling up the code so I wrote:


Method to convert ‘double’ to bytes in C#:

public static byte[] DoubleToModbusDouble(double value)
{
    byte[] bytes = new byte[8];
    long intValue = BitConverter.ToInt64(BitConverter.GetBytes(value), 0);

    bytes[0] = (byte)((intValue >> 56) & 0xff);
    bytes[1] = (byte)((intValue >> 48) & 0xff);
    bytes[2] = (byte)((intValue >> 40) & 0xff);
    bytes[3] = (byte)((intValue >> 32) & 0xff);
    bytes[4] = (byte)((intValue >> 24) & 0xff);
    bytes[5] = (byte)((intValue >> 16) & 0xff);
    bytes[6] = (byte)((intValue >> 8) & 0xff);
    bytes[7] = (byte)(intValue & 0xff);

    return bytes;
}


Call of method and loading of the modbus registers in EasyModbus:

Bytes = PublicCode.DoubleToModbusDouble(TmpDbl);

int n = (int)ModbusStartAddress + ((i - 1) * 4);

mb.ModServer.holdingRegisters[n + 1] = (short)((Bytes[0] << 8) + Bytes[1]);
mb.ModServer.holdingRegisters[n + 2] = (short)((Bytes[2] << 8) + Bytes[3]);

mb.ModServer.holdingRegisters[n + 3] = (short)((Bytes[4] << 8) + Bytes[5]);
mb.ModServer.holdingRegisters[n + 4] = (short)((Bytes[6] << 8) + Bytes[7]);


However, this code does not work correctly. I have tried all combinations of byte and word reversal, and whatever I do WinCC either displays nonsensical values or ‘####’ showing that it cannot display the value. I have tried reading as much documentation as I can but it still looks to me as if I am doing the right thing. Also, I have downloaded a number of ‘modbus master’ code examples, and they seem to be able to read the ‘Double’ from my program without any issues. In WinCC I also see that there are two types of double – ‘Double’ and ‘+/- Double’ – I am also unsure as to why this is – there is no ‘+/- Float’ data type, which seems inconsistent to me.

I am obviously missing something, but cannot seem to discover what exactly.

I hope that someone can point me in the right direction as to what I am doing wrong.


Please see attached word file for a picture of the configuration of the connection in WinCC.

 

Thanks in advance for any help !,

Dave Long

Double trouble.docx

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now