Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I read ASCII data? #1

Open
locodust6 opened this issue Aug 2, 2022 · 6 comments
Open

How can I read ASCII data? #1

locodust6 opened this issue Aug 2, 2022 · 6 comments

Comments

@locodust6
Copy link

I tried with below code.

PLCData<char> devices = new(PlcDeviceType.W, 0x100, 256);
devices.ReadData();

StringBuilder sb = new();
for (int i = 0; i < 160; i++)
{
    sb.Append(devices[i]);
}
sb.ToString();

However, I get "McProtocol.PLCData`1[System.Char]".
How can I get the string?

@locodust6
Copy link
Author

locodust6 commented Aug 2, 2022

I was able to get it in the following way.

PLCData<short> devices = new(PlcDeviceType.W, 0x100, 256);
devices.ReadData();

StringBuilder sb = new();
for (int i = 0; i < 160; i++)
{
    string str = ASCIIEncoding.ASCII.GetString(Convert.FromHexString(devices[i].ToString("X2")));
    if (str == "\0") break;
    sb.Append(str);
}
sb.ToString();

Is there a smarter way or an official way?

@ping9719
Copy link
Owner

ping9719 commented Aug 3, 2022

支持直接转的类型有:Boolean,Int32,Int16,UInt16,UInt32,Single,Char
我开放出来了Bytes,在版本 v2.1.6
你可以试试:(我也不知道是否可行,我没有测试环境,如果不行请告诉我)
`
//>= v2.1.6
PLCData devices = new(PlcDeviceType.W, 0x100, 256);
devices.ReadData();
Encoding.ASCII.GetString(devices.Bytes);

//< v2.1.6
var bytes = await mcProtocolTcp.ReadDeviceBlockByte(PlcDeviceType.W, 0x100, 256);
Encoding.ASCII.GetString(bytes);
`

@locodust6
Copy link
Author

locodust6 commented Aug 4, 2022

Thank you for your response.

However, since the byte order is reversed, it cannot be converted into a string as is.
For example, "ABCDEF" becomes "BADCFE".

Therefore, it was necessary to change the byte order as shown below and convert it to a string.

//It is necessary to loop to read all character strings, but it is omitted.
Encoding.ASCII.GetString(Convert.FromHexString(BinaryPrimitives.ReadInt16LittleEndian(bytes.AsSpan(intStart, intLength)).ToString("X2")))

Appendix

I was able to get it in the following way.

PLCData<short> devices = new(PlcDeviceType.W, 0x100, 256);
devices.ReadData();
byte[] devicesBytes = devices.Bytes;

byte[] cropBytes = bytes.AsSpan(0 * 2, 160 * 2).ToArray();
byte[] trimdBytes = cropBytes.TakeWhile(x => x != 0).ToArray();
byte[] sortedBytes = new byte[trimdBytes.Length];
for (int i = 0; i < sortedBytes.Length; i += 2)
{
    if (i == sortedBytes.Length -1)
        {
            sortedBytes[i] = trimdBytes[i];
            break;
        }
        sortedBytes[i] = trimdBytes[i + 1];
        sortedBytes[i + 1] = trimdBytes[i];
}

Encoding.ASCII.GetString(sortedBytes);

@ping9719
Copy link
Owner

ping9719 commented Aug 5, 2022

高低位转换需要自己转换,不是很难。不提供的原因是一般都是为ABCDE这样的,你自己转换就行了。
我为你提供一段代码思路:

    byte[] bytes = Encoding.ASCII.GetBytes("BADCFEG");
    for (int i = 0; i < bytes.Length - 1; i += 2)
        (bytes[i], bytes[i + 1]) = (bytes[i + 1], bytes[i]);
    //ABCDEFG
    string re = Encoding.ASCII.GetString(bytes);

@locodust6
Copy link
Author

Thank you.

I will refer to it.
Since it is a process that is commonly used, I would be happy if it could be provided by the ToString() method.

@ping9719
Copy link
Owner

ping9719 commented Aug 8, 2022

string 和 int bool .... 不同,你可以自己写一个类来完成自己的特殊化需求。
然后你把你的代码发出来(我试了一下,我的代码不是很合理),我试试能不能加入到代码中,提供给所有的人使用。

Please provide your code for my reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants