#c# #serialization #tcpclient
#c# #сериализация #tcpclient
Вопрос:
я впервые задаю вопросы на этой платформе. Не стесняйтесь указывать, что я должен делать или избегать, чтобы стать лучше, спасибо.
Я пытаюсь отправить объект Struct в MES (производственную исполнительную систему) для изменения статуса моей рабочей станции. Вот иллюстрация структуры данных (2.2):
И приведенный ниже код на C # — это то, что я сделал. Я уверен, что я подключился к системе MES, но статус просто не изменился, и я подумал, что причина может быть связана с форматом передаваемых данных.
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using TcpClient = NetCoreServer.TcpClient;
//the Struct of data
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct StateOfRobotino
{
public int ResourceID;
public byte SPSType;
public byte State_info;
}
StateOfRobotino robotino10 = new StateOfRobotino();
robotino10.ResourceID = 10;
robotino10.SPSType = 2;
robotino10.State_info = 0b10000001; //MES mode, Auto
byte[] b_robotino10 = getBytes(robotino10);
//Convert Struct type to byte array through Marshal
byte[] getBytes(StateOfRobotino str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
Одна вещь, в которой я сомневался, — это третьи данные в моей структуре, могу ли я просто использовать байт (State_info) для представления 8-битных данных? Если нет, то как я должен поступить? Или есть какой-либо другой способ, которым я могу попытаться передать такие данные?
Спасибо.
Ответ №1:
Метод сортировки для получения вашего массива байтов должен работать.
Теперь перейдем к вашей структуре данных:
ResourceID Int 0
SPSType Byte 2
Auto Mode Bit 3.0
... Bit 3.n
MES Mode Bit 3.7
Я обращаю ваше внимание на числовой столбец, содержащий 0, 2 и 3.x
-
ResourceID
похоже, что они занимают байты 0 и 1. Два байта в anInt
указывают, что ваш ПЛК 16-разрядный. C #int
является 32-разрядным, который занимает ЧЕТЫРЕ байта. Вам необходимо явно указать либоInt16
илиUInt16
(возможно, беззнаковоеUInt16
, если вы MES не ожидаете отрицательного числа от ПЛК).Они также известны как
short
илиushort
, но всегда приятно быть более явным, указывая 16-разрядность при работе с внешними системами, чтобы минимизировать путаницу. -
SPSType
это просто байт. -
Остальные из них помечены как
3.0 ... 3.7
. Это обозначение для 8 бит (0 ..7), которые занимают байт 3. Что означает, что да, ожидается, что вы отправите один байт, содержащий все биты. Имейте в виду, что бит 0 является самым правым битом, как0b00000001
и AutoMode, и0b10000000
является MESMode .
Комментарии:
1. В частности, спасибо за подсказку о 4 байтах нулей и структуре данных (INT на самом деле составляет 16 бит (2 байта)).