123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- using StageController.M3H;
- using System;
- using System.Collections.Generic;
- using System.IO.Ports;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace StageController
- {
- public delegate void VoltageEvent(CommandBase command, Result result, string msg);
- public class VoltageController
- {
- //定义接收数据事件
- public event VoltageEvent VoltageReceived;
- private SerialPort m_serialPort;
- private Queue<CommandBase> m_commandQueue;
- private MsgMgr m_msgMgr = new MsgMgr();
- private Thread m_waitingThread;
- private static VoltageController m_instance = null;
- private VoltageController()
- {
- m_commandQueue = new Queue<CommandBase>(100);
- }
- public static VoltageController GetInstance()
- {
- if (m_instance == null)
- {
- m_instance = new VoltageController();
- }
- return m_instance;
- }
- private bool m_running = false;
- public string[] GetSerialPorts()
- {
- return SerialPort.GetPortNames();
- }
- // 正式环境中的处理流程:
- // Step 1 : 枚举所有串口
- // Step 2 : Open(comName)
- // Step 3 : AddCommand(ConnectCheckCommand)
- // Step 4 : callback
- // Step 5 : Close
- // 重复Step 2 ~ Step 5
- public void Open(string portName, int baudRate)
- {
- if (!m_running)
- {
- m_serialPort = new SerialPort(portName, baudRate);
- m_serialPort.Encoding = Encoding.ASCII;
- m_serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
- m_serialPort.Open();
- m_commandQueue.Clear();
- m_waitingThread = new Thread(new ThreadStart(MessageThreadEntry));
- m_waitingThread.Start();
- m_running = true;
- }
- }
- public void Close()
- {
- if (m_running)
- {
- m_msgMgr.EndLoop();
- if ((m_serialPort != null) && m_serialPort.IsOpen)
- {
- m_serialPort.Close();
- }
- m_running = false;
- }
- m_commandQueue.Clear();
- }
- public void AddCommand(CommandBase command)
- {
- m_commandQueue.Enqueue(command);
- m_msgMgr.SendMsg(MSG_TOSEND, null, null);
- }
- private string m_responseCommand;
- private string parseCmdPkg(string response)
- {
- string retStr = null;
- int stopPosi = response.IndexOf("#");
- if (stopPosi > 0) //第0个字符不可能为 "!"
- {
- int startPosi = response.IndexOf("*"); // response.LastIndexOf("@");
- if (startPosi >= 0)
- {
- retStr = response.Substring(startPosi, stopPosi - startPosi + 1);
- }
- }
- return retStr;
- }
- // 接收串口返回数据
- private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
- {
- SerialPort sp = (SerialPort)sender;
- string recvData = sp.ReadExisting();
- if (string.IsNullOrWhiteSpace(recvData))
- {
- Logs.Write("Err: Received null or white or space!");
- return;
- }
- Logs.Write("Recv Data: " + recvData);
- m_responseCommand += recvData;
- // 拆包
- string resPkg = parseCmdPkg(m_responseCommand);
- if (resPkg != null)
- {
- Logs.Write("Recv Pack: " + resPkg);
- // 解析
- if (m_curCommand.Parse(resPkg))
- {
- m_msgMgr.SendMsg(MSG_RECVED, resPkg, m_curCommand);
- }
- else
- {
- Logs.Write("Err: command parse faild!");
- m_msgMgr.SendMsg(MSG_ERR, resPkg, m_curCommand);
- }
- // m_responseCommand = "";
- // edit by maxb 20200807 连续两个命令同时执行时,可能会出现接收到的数据包含第二条命令返回数据的一部分
- int stopPosi = m_responseCommand.IndexOf("#");
- m_responseCommand = m_responseCommand.Substring(stopPosi + 1);
- }
- // 接收字符串长度超过200,说明出错误了。
- if (m_responseCommand.Length > 200)
- {
- Logs.Write("Err: m_responseCommand.Length is : " + m_responseCommand.Length);
- m_responseCommand = ""; //TODO
- }
- }
- private const int MSG_TOSEND = 0; //parm1: 0, parm2:0
- private const int MSG_RECVED = 1; //parm1:address, parm2: data
- private const int MSG_TIMEOUT = 2; //parm1: 0, parm2:0
- private const int MSG_ERR = 3; //parm1: errType, parm2:errCode
- //errType : Checksum, Response
- private const int STS_IDLE = 0;
- private const int STS_WAITRES = 1;
- private int m_curSts = STS_IDLE;
- private CommandBase m_curCommand = null;
- private const int RETRY_TIME = 2;
- private int m_retryCnt = 0;
- private void callCallback(CommandBase command, Result result, string msg)
- {
- if (VoltageReceived != null)
- {
- VoltageReceived(command, result, msg);
- }
- }
- private void MsgProcess(int msg, object parm1, object parm2)
- {
- // 状态机模型
- switch (msg)
- {
- case MSG_TOSEND:
- if (STS_IDLE == m_curSts)
- {
- if (m_commandQueue.Count > 0)
- {
- m_curCommand = m_commandQueue.Dequeue();
- m_retryCnt = 0;
- SendCommandBySerial(m_curCommand);
- StartSendTimer();
- m_curSts = STS_WAITRES;
- }
- }
- break;
- case MSG_RECVED:
- if (STS_WAITRES == m_curSts)
- {
- StopSendTimer();
- //Logs.Write("callCallback");
- //收到回复数据包,而且解析正常
- callCallback(m_curCommand, Result.OK, (string)parm1); //parm1中记录了收到的数据包
- m_curSts = STS_IDLE;
- m_msgMgr.SendMsg(MSG_TOSEND, 0, null);
- }
- break;
- case MSG_TIMEOUT:
- if (STS_WAITRES == m_curSts)
- {
- StopSendTimer();
- if (m_retryCnt >= RETRY_TIME)
- {
- // 没收到回复的数据包
- callCallback(m_curCommand, Result.ERR_TIMEOUT, "超时");
- m_curSts = STS_IDLE;
- }
- else
- {
- SendCommandBySerial(m_curCommand);
- StartSendTimer();
- m_retryCnt++;
- }
- }
- break;
- case MSG_ERR:
- if (STS_WAITRES == m_curSts)
- {
- StopSendTimer();
- // 收到回复数据包,解析时发现错误
- if (m_retryCnt >= RETRY_TIME)
- {
- callCallback(m_curCommand, Result.ERR_PARSE, (string)parm1); //parm1中记录了收到的数据包
- m_curSts = STS_IDLE;
- }
- else
- {
- SendCommandBySerial(m_curCommand);
- StartSendTimer();
- m_retryCnt++;
- }
- }
- break;
- }
- }
- private void MessageThreadEntry()
- {
- m_msgMgr.MessageProcess = MsgProcess;
- m_msgMgr.MsgLoop();
- }
- #region serial port
- private void SendCommandBySerial(CommandBase cmd)
- {
- string sendData = cmd.Make();
- Logs.Write("send : " + sendData);
- if ((m_serialPort != null) && m_serialPort.IsOpen)
- {
- m_serialPort.Write(sendData);
- }
- }
- #endregion
- #region timer
- private System.Timers.Timer m_sendTimer = null;
- private void SendTimerTimeout(object sender, System.Timers.ElapsedEventArgs e)
- {
- m_msgMgr.SendMsg(MSG_TIMEOUT, null, null);
- }
- private void StartSendTimer()
- {
- if (m_sendTimer == null)
- {
- m_sendTimer = new System.Timers.Timer(1000.0);
- m_sendTimer.Elapsed += SendTimerTimeout;
- m_sendTimer.AutoReset = false; //one short timer.
- }
- m_sendTimer.Start();
- }
- private void StopSendTimer()
- {
- if (m_sendTimer != null)
- {
- m_sendTimer.Stop();
- }
- }
- #endregion
- }
- }
|