我有一个通过COM-Port链接到多个传感器的GUI。我有一个Datahandler,可以确保收到和发送的包具有正确的大小和内容。然后我有一个包含所有传感器的SensorContainer,每当添加新传感器时都会触发事件!
我现在的问题是: 我需要一种方法,只需点击一下即可初始化所有传感器。
我不能这样做。如果我逐个初始化它们,它可以工作,但所有方法都不起作用。 我的想法是包被混合,处理程序不再接受传感器进行初始化。所以我试图让方法等待第一个传感器初始化和继续,但我不知道如何! 我用多线程尝试了一些东西,但是我并没有在那个领域真正经历过,而且最终它还没有成功......
SensorContainerClass :
public static class SensorContainer
{
public static event EventHandler<ContainerEvent> ContainerChanged;
public static ObservableCollection<Sensor> SensorList
{
get { return _sensorList; }
}
public static void AddSensor(Sensor sensor)
{
Sensor sensorExists = GetSensor(sensor.Address);
if (sensorExists == null)
{
Application.Current.Dispatcher.Invoke(() => _sensorList.Add(sensor));
ContainerChanged(null,new ContainerEvent(sensor.Address, true));
}
else
{
Console.WriteLine("It's not possible to add multiple sensors with the same address.");
}
}
public static void RemoveSensor(Sensor sensor)
{
Sensor sensorExists = GetSensor(sensor.Address);
if (sensorExists != null)
{
Application.Current.Dispatcher.Invoke(() => _sensorList.Remove(sensor));
ContainerChanged(null, new ContainerEvent(sensor.Address, false));
}
else
{
Console.WriteLine("No sensor with address " + sensor.Address);
}
}
public static Sensor GetSensor(byte address)
{
foreach (Sensor sensor in _sensorList)
{
if (sensor.Address == address)
{
return sensor;
}
}
return null;
}
// members
private static readonly ObservableCollection<Sensor> _sensorList = new ObservableCollection<Sensor>();
}
的DataHandler :
public class DataHandler:ModelBase
{
private const int MAX_TIMER_TIME = 500;
public long answertime_milli;
Timer aTimer;
Stopwatch watch;
Sensor tempSensor;
private byte[] tempFrame;
private bool framePartPendingFlag = false;
public bool framesEqual;
public bool initalisationFlag = false;
public InitType initialisationType;
public byte[] TxFrame
{
get { return txFrame; }
}
public byte TxAddress
{
get { return TxFrame[0]; }
}
public byte TxLength
{
get { return TxFrame[1]; }
}
public byte TxCommand
{
get { return TxFrame[2]; }
}
public byte[] TxData
{
get { return TxFrame.GetRange(3, TxLength - 2); }
}
public byte TxChecksum
{
get { return TxFrame[TxLength - 1]; }
}
private byte[] txFrame;
private bool successfull;
public bool Successfull
{
get
{
return successfull;
}
set
{
if(successfull != value)
{
successfull = value;
this.OnPropertyChanged();
}
}
}
public DataHandler()
{
txFrame = new byte[4] { 0, 0, 0, 0 };
aTimer = new Timer(MAX_TIMER_TIME);
watch = new Stopwatch();
CommandManager.Instance.Init();
InterfaceWrapper.Instance.SerialPort.DataReceived += OnSerialPortReceived;
}
public void InitializeSensor(InitType type, byte address, Int32 serialNumber = 0)
{
if (SensorContainer.GetSensor(address) != null )
{
MessageBox.Show("Sensoraddress already used");
return;
}
foreach(Sensor temp in SensorContainer.SensorList)
{
if(temp.Serialnr == serialNumber)
{
MessageBox.Show("Sensor with the same SerialNumber already initalized");
return;
}
}
byte[] frame;
if (type == InitType.INIT_TO_ONE_DEVICE)
{
Sensor.COM_ADDR_SET_ONE_TX initStruct = new Sensor.COM_ADDR_SET_ONE_TX();
initStruct.Address = address;
frame = createFrame(initStruct, 0xFF, 0x20);
}
else
{
Sensor.COM_ADDR_SET_TO_SN_TX initStruct = new Sensor.COM_ADDR_SET_TO_SN_TX();
initStruct.Address = address;
if (serialNumber == 0)
{
MessageBox.Show("Serialnumber is missing");
return;
}
initStruct.SerialNumber = serialNumber;
frame = createFrame(initStruct, 0x00, 0x22);
}
setTxFrame(frame);
InterfaceWrapper.Instance.SerialPort.SendData(frame);
initalisationFlag = true;
initialisationType = type;
}
public void StartDataTransfer(Sensor sensor, byte commandid)
{
if (sensor == null)
{
MessageBox.Show("No such sensor");
return;
}
Command command = sensor.getCommand(commandid);
if (command == null)
{
MessageBox.Show("Command does not exist");
return;
}
foreach (KeyValuePair<CommandAttribute, Command> pair in sensor.CommandList)
{
if (pair.Value == command)
{
timeout = pair.Key.Timeout;
transmission = pair.Key.Transmission;
break;
}
}
tempSensor = sensor;
if (SensorContainer.GetSensor(sensor.Address) != null)
{
byte[] endFrame = createFrame(command, sensor.Address, commandid);
setTxFrame(endFrame);
if (true)
{
InterfaceWrapper.Instance.SerialPort.SendData(txFrame);
}
}
else
{
MessageBox.Show("Sensor not yet initialized");
}
}
private byte[] createFrame(Command command, byte address, byte commandId)
{
byte[] data = MarshalHelper.Serialize(command);
byte[] frame = new byte[4 + data.Length];
frame[0] = address;
frame[1] = (byte)frame.Length;
frame[2] = commandId;
Buffer.BlockCopy(data, 0, frame, 3, data.Length);
frame[frame.Length - 1] = GenerateChecksum(frame);
return frame;
}
public void OnSerialPortReceived(object sender, ComDataRxEvent e)
{
byte[] data = e.Data;
setRxFrame(data);
}
public void setTxFrame(byte[] _txFrame)
{
Successfull = false;
txFrame = _txFrame;
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = false;
aTimer.Start();
watch.Start();
}
public void setRxFrame(byte[] _rxFrame)
{
if (framePartPendingFlag)
{
byte[] newTempFrame = new byte[tempFrame.Length + _rxFrame.Length];
tempFrame.CopyTo(newTempFrame, 0);
_rxFrame.CopyTo(newTempFrame, tempFrame.Length);
framePartPendingFlag = false;
setRxFrame(newTempFrame);
}
else if (!checkMinLength(_rxFrame))
{
tempFrame = _rxFrame;
framePartPendingFlag = true;
}
else if (!checkBit(_rxFrame))
{
tempFrame = _rxFrame;
framePartPendingFlag = true;
}
else
{
framePartPendingFlag = false;
aTimer.Stop();
watch.Stop();
answertime_milli = watch.ElapsedMilliseconds;
if (!initalisationFlag)
{
if (checkAll(_rxFrame))
{
writeCommandToSensor(_rxFrame);
}
}
else
{
createSensorAfterInitialization(_rxFrame);
}
}
}
private void writeCommandToSensor(byte[] frame)
{
Command expCommand = CommandManager.Instance.GetRxCommand(tempSensor.GetType(), TxCommand);
Command command = MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
tempSensor.setCommand(command);
}
private void createSensorAfterInitialization(byte[] frame)
{
if (initalisationFlag && initialisationType == InitType.INIT_TO_ONE_DEVICE)
{
Sensor.COM_ADDR_SET_ONE_RX expCommand = new Sensor.COM_ADDR_SET_ONE_RX();
Sensor.COM_ADDR_SET_ONE_RX command = (Sensor.COM_ADDR_SET_ONE_RX)MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
Sensor tempSensor = Sensor.GetSensorInstance(command.SerialNumber, command.Address, command.SensorName, command.SensorSubName, command.dataStructType, command.dataStructSubType,command.pcbVersion,command.firmware);
tempSensor.setCommand(command);
SensorContainer.AddSensor(tempSensor);
initalisationFlag = false;
}
else
{
Sensor.COM_ADDR_SET_TO_SN_RX expCommand = new Sensor.COM_ADDR_SET_TO_SN_RX();
Sensor.COM_ADDR_SET_TO_SN_RX command = (Sensor.COM_ADDR_SET_TO_SN_RX)MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
if (command == null)
{
MessageBox.Show("Sensor not answering");
}
else {
Sensor tempSensor = Sensor.GetSensorInstance(command.SerialNumber, command.Address, command.SensorName, command.SensorSubName, command.dataStructType, command.dataStructSubType, command.pcbVersion, command.firmware);
tempSensor.setCommand(command);
SensorContainer.AddSensor(tempSensor);
initalisationFlag = false;
}
}
}
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
framePartPendingFlag = false;
}
}