PLC.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. using Houdar.PLC.Driver.Simenss;
  2. using Houdar.PLC.Driver.Simenss.Protocol.Common;
  3. using Houdar.PLC.Driver.Simenss.Protocol.ReadData;
  4. using System;
  5. using WCS.Data;
  6. using WCS.Data.Utils;
  7. namespace WCS.PLC
  8. {
  9. public class PLC
  10. {
  11. private readonly object olock = new object();
  12. private string _plc_name = string.Empty;
  13. private PlcErrorCount _plcErrorCount = new PlcErrorCount() { ErrorCount = 0, LastTime = DateTime.MinValue };
  14. private Action StopPlcEvent;
  15. internal SimenssPlc _splc = null;
  16. public PLC() { _splc = new SimenssPlc(); }
  17. //slot 插槽,port 端口,rack 道轨
  18. public bool Connect(string ip, int rack, int slot)
  19. {
  20. if (_splc.ConnectTo(ip, rack, slot))
  21. return true;
  22. return false;
  23. }
  24. public bool Connect(string ip, int rack, int slot, string plc_name)
  25. {
  26. if (_splc.ConnectTo(ip, rack, slot))
  27. {
  28. _plc_name = plc_name;
  29. _splc.RegisterMessageEvent(PrintMsg);
  30. return true;
  31. }
  32. return false;
  33. }
  34. #region 读取值;
  35. public object ReadSignal(ushort DBNumber, ushort start, ushort len)
  36. {
  37. object obj = 0;
  38. byte[] msg = new byte[len];
  39. if (Read(DBNumber, start, len, ref msg))
  40. {
  41. if (len == 1)
  42. {
  43. //obj = BitConverter.ToUInt16(bt,0);
  44. obj = msg[0];
  45. }
  46. else if (len == 2)
  47. {
  48. //byte[] temp = new byte[2];
  49. //temp[0] = bt[1];
  50. //temp[1] = bt[0];
  51. //obj = BitConverter.ToInt16(temp, 0);
  52. obj = Convert.ToUInt16(msg[0] * 256 + msg[1]);
  53. }
  54. else if (len == 4)
  55. {
  56. //byte[] temp = new byte[4];
  57. //temp[0] = bt[3];
  58. //temp[1] = bt[2];
  59. //temp[2] = bt[1];
  60. //temp[3] = bt[0];
  61. //obj = BitConverter.ToInt16(temp, 0);
  62. obj = Convert.ToUInt32(msg[0] * 256 * 256 * 256 + msg[1] * 256 * 256 + msg[2] * 256 + msg[3]);
  63. }
  64. }
  65. else
  66. {
  67. obj = 0;
  68. }
  69. return obj;
  70. }
  71. public bool ReadBit(ushort DBNumber, ushort start)
  72. {
  73. if (_splc.Connected)
  74. {
  75. DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, 1, DataType.Bit);
  76. if (di != null && di.Err == ResultCode.OKFF)
  77. {
  78. return Convert.ToBoolean(di.Data[0]);
  79. }
  80. else
  81. {
  82. if (di != null)
  83. Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());
  84. return false;
  85. }
  86. }
  87. Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");
  88. return false;
  89. }
  90. public bool ReadBitArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)
  91. {
  92. if (_splc.Connected)
  93. {
  94. for (int i = 0; i < len; i++)
  95. {
  96. DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, (ushort)i, 1, DataType.Bit);
  97. if (di != null && di.Err == ResultCode.OKFF)
  98. {
  99. msg[i] = di.Data[0];
  100. //return true;
  101. }
  102. else
  103. {
  104. if (di != null)
  105. Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");
  112. return false;
  113. }
  114. public bool Read(ushort DBNumber, ushort start, ushort len, ref byte[] msg)
  115. {
  116. if (_splc.Connected)
  117. {
  118. DataType dt;
  119. if (len == 1) dt = DataType.Byte;
  120. else if (len == 2) dt = DataType.Word;
  121. else if (len == 4) dt = DataType.DWord;
  122. else return false;
  123. DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, dt);
  124. if (di != null && di.Err == ResultCode.OKFF)
  125. {
  126. msg = di.Data;
  127. return true;
  128. }
  129. else
  130. {
  131. if (di != null)
  132. Log4netHelper.Logger_Error.ErrorFormat(di.Err.ToString());
  133. return false;
  134. }
  135. }
  136. Log4netHelper.Logger_Error.ErrorFormat("PLC未连接。");
  137. return false;
  138. }
  139. public bool ReadByteArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)
  140. {
  141. lock (olock)
  142. {
  143. try
  144. {
  145. if (_splc.Connected)
  146. {
  147. DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, DataType.Byte);
  148. if (di != null && di.Err == ResultCode.OKFF)
  149. {
  150. msg = di.Data;
  151. return true;
  152. }
  153. else
  154. {
  155. if (di == null)
  156. {
  157. Log4netHelper.Logger_Error.ErrorFormat(string.Format("DB[{0}]读取失败,未查询到读取失败原因。", DBNumber));
  158. if (PlcErrorIsFull(DBNumber))
  159. {
  160. StopPlc();
  161. }
  162. }
  163. else
  164. Log4netHelper.Logger_Error.ErrorFormat(string.Format("DB[{0}]读取失败,原因:[{1}]", DBNumber, di.Err.ToString()));
  165. return false;
  166. }
  167. }
  168. else
  169. {
  170. LogMessageHelper.RecordLogMessage(string.Format("PLC[{0}]DB[{1}]读取失败,Connected为fasle,系统将重新连接plc。", _plc_name, DBNumber));
  171. }
  172. }
  173. catch (Exception ex)
  174. {
  175. Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());
  176. }
  177. }
  178. return false;
  179. }
  180. private void PrintMsg(MessageEvent msg)
  181. {
  182. if (msg.Message.Trim() != "OK")
  183. {
  184. Log4netHelper.Logger_Info.Info(string.Format("PLC通信DLL消息:方法:[{0}]消息[{1}]", msg.Method, msg.Message));
  185. }
  186. }
  187. private bool PlcErrorIsFull(ushort dbnumber)
  188. {
  189. bool result = false;
  190. int count = 18;
  191. if (dbnumber == 520 || dbnumber == 521)
  192. {
  193. if (_plcErrorCount.ErrorCount == 0)
  194. {
  195. Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]第一次报错,次数+1", _plc_name));
  196. _plcErrorCount.ErrorCount = 1;
  197. _plcErrorCount.LastTime = DateTime.Now;
  198. }
  199. else if (_plcErrorCount.ErrorCount < count)
  200. {
  201. if (_plcErrorCount.LastTime.AddSeconds(10) > DateTime.Now)
  202. {
  203. _plcErrorCount.ErrorCount += 1;
  204. _plcErrorCount.LastTime = DateTime.Now;
  205. Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]次数+1 ,现有次数[{1}]", _plc_name, _plcErrorCount.ErrorCount));
  206. }
  207. else
  208. {
  209. _plcErrorCount.ErrorCount = 0;
  210. _plcErrorCount.LastTime = DateTime.Now;
  211. Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]10秒未报错,次数重置", _plc_name, _plcErrorCount.ErrorCount));
  212. }
  213. }
  214. else if (_plcErrorCount.ErrorCount >= count)
  215. {
  216. _plcErrorCount.ErrorCount = 0;
  217. LogMessageHelper.RecordLogMessage(string.Format("PLC[{0}]读取DB频繁返回Null值达到[{1}]次,将停止PLC连接,次数清零,并重启PLC连接。", _plc_name, count));
  218. result = true;
  219. }
  220. }
  221. return result;
  222. }
  223. //public bool ReadWordArea(ushort DBNumber, ushort start, ushort len, ref byte[] msg)
  224. //{
  225. // if (_splc.Connected)
  226. // {
  227. // DataItem di = _splc.ReadArea(AreaType.DB, DBNumber, start, len, DataType.Word);
  228. // if (di != null && di.Err == ResultCode.OKFF)
  229. // {
  230. // msg = di.Data;
  231. // return true;
  232. // }
  233. // else
  234. // {
  235. // Current.Logger_Error.ErrorFormat(di.Err.ToString());
  236. // return false;
  237. // }
  238. // }
  239. // Current.Logger_Error.ErrorFormat("PLC未连接。");
  240. // return false;
  241. //}
  242. #endregion;
  243. #region 写入值
  244. public bool WriteSignal(ushort DBNumber, ushort start, ushort len, object msg)
  245. {
  246. lock (olock)
  247. {
  248. bool result = false;
  249. byte[] bt = new byte[len];
  250. if (len == 1)
  251. {
  252. bt[0] = Convert.ToByte(msg);
  253. }
  254. else if (len == 2)
  255. {
  256. byte[] from_wcs = System.BitConverter.GetBytes(Convert.ToUInt16(msg));
  257. bt[0] = from_wcs[1];//地位值
  258. bt[1] = from_wcs[0];//高位值
  259. }
  260. else if (len == 4)
  261. {
  262. byte[] from_wcs = System.BitConverter.GetBytes(Convert.ToUInt32(msg));
  263. bt[0] = from_wcs[3];
  264. bt[1] = from_wcs[2];
  265. bt[2] = from_wcs[1];
  266. bt[3] = from_wcs[0];
  267. }
  268. result = Write(DBNumber, start, bt);
  269. return result;
  270. }
  271. }
  272. public bool WriteBits(ushort DBNumber, uint start, bool status)
  273. {
  274. lock (olock)
  275. {
  276. bool result = false;
  277. if (_splc.Connected)
  278. {
  279. byte[] bt = new byte[1];
  280. bt[0] = Convert.ToByte(status);
  281. if (_splc.WriteArea(AreaType.DB, DBNumber, start, 1, DataType.Bit, bt))
  282. {
  283. result = true;
  284. }
  285. else
  286. {
  287. Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC可能未连接。(WriteBits)");
  288. }
  289. }
  290. else
  291. {
  292. Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC未连接。(WriteBits)");
  293. }
  294. return result;
  295. }
  296. }
  297. public bool Write(ushort DBNumber, ushort start, byte[] msg)
  298. {
  299. lock (olock)
  300. {
  301. bool result = false;
  302. if (_splc.Connected)
  303. {
  304. //DataType dt;
  305. //if (len == 1) dt = DataType.Byte;
  306. //else if (len == 2) dt = DataType.Word;
  307. //else if (len == 4) dt = DataType.DWord;
  308. //else return false;
  309. if (_splc.WriteArea(AreaType.DB, DBNumber, start, (ushort)msg.Length, DataType.Byte, msg))
  310. {
  311. result = true;
  312. }
  313. else
  314. {
  315. Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC可能未连接。(Write)");
  316. }
  317. }
  318. else
  319. {
  320. Log4netHelper.Logger_Error.ErrorFormat("写入DB信息失败,PLC未连接。(Write)");
  321. }
  322. return result;
  323. }
  324. }
  325. #endregion;
  326. public void PlcStop()
  327. {
  328. _splc.PlcStop();
  329. }
  330. public void RegisterStopPlcEvent(Action stopPlcAction)
  331. {
  332. if (stopPlcAction == null) throw new ArgumentNullException("stopPlcAction");
  333. StopPlcEvent = stopPlcAction;
  334. }
  335. private void StopPlc()
  336. {
  337. if (StopPlcEvent != null) StopPlcEvent.Invoke();
  338. }
  339. }
  340. public struct PlcErrorCount
  341. {
  342. public int ErrorCount;
  343. public DateTime LastTime;
  344. }
  345. }