Plc.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using Sharp7;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace snap7Enc
  8. {
  9. public class Plc : IDisposable
  10. {
  11. private S7Client Client;
  12. /// <summary>
  13. /// IP address of the PLC
  14. /// </summary>
  15. public string IP { get; private set; }
  16. /// <summary>
  17. /// CPU type of the PLC
  18. /// </summary>
  19. public CpuType CPU { get; private set; }
  20. /// <summary>
  21. /// Rack of the PLC
  22. /// </summary>
  23. public Int16 Rack { get; private set; }
  24. /// <summary>
  25. /// Slot of the CPU of the PLC
  26. /// </summary>
  27. public Int16 Slot { get; private set; }
  28. /// <summary>
  29. /// Checks if the socket is connected and polls the other peer (the PLC) to see if it's connected.
  30. /// This is the variable that you should continously check to see if the communication is working
  31. /// See also: http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c
  32. /// </summary>
  33. public bool IsConnected
  34. {
  35. get
  36. {
  37. try
  38. {
  39. return Client.Connected;
  40. }
  41. catch { return false; }
  42. }
  43. }
  44. /// <summary>
  45. /// Creates a PLC object with all the parameters needed for connections.
  46. /// For S7-1200 and S7-1500, the default is rack = 0 and slot = 0.
  47. /// You need slot > 0 if you are connecting to external ethernet card (CP).
  48. /// For S7-300 and S7-400 the default is rack = 0 and slot = 2.
  49. /// </summary>
  50. /// <param name="cpu">CpuType of the PLC (select from the enum)</param>
  51. /// <param name="ip">Ip address of the PLC</param>
  52. /// <param name="rack">rack of the PLC, usually it's 0, but check in the hardware configuration of Step7 or TIA portal</param>
  53. /// <param name="slot">slot of the CPU of the PLC, usually it's 2 for S7300-S7400, 0 for S7-1200 and S7-1500.
  54. /// If you use an external ethernet card, this must be set accordingly.</param>
  55. public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot)
  56. {
  57. if (!Enum.IsDefined(typeof(CpuType), cpu))
  58. throw new ArgumentException($"The value of argument '{nameof(cpu)}' ({cpu}) is invalid for Enum type '{typeof(CpuType).Name}'.", nameof(cpu));
  59. if (string.IsNullOrEmpty(ip))
  60. throw new ArgumentException("IP address must valid.", nameof(ip));
  61. CPU = cpu;
  62. IP = ip;
  63. Rack = rack;
  64. Slot = slot;
  65. Client = new S7Client();
  66. }
  67. public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
  68. {
  69. try {
  70. if (Client != null)
  71. {
  72. byte[] buffer = new byte[count];
  73. if (dataType == DataType.DataBlock)
  74. {
  75. Client.DBRead(db, startByteAdr, count, buffer);
  76. return buffer;
  77. }
  78. }
  79. }
  80. catch (Exception ex) { Console.WriteLine("snap7读异常," + ex.Message + "," + ex.StackTrace); }
  81. return null;
  82. }
  83. public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
  84. {
  85. try
  86. {
  87. if (Client != null)
  88. {
  89. if (dataType == DataType.DataBlock)
  90. {
  91. int result = Client.DBWrite(db, startByteAdr, value.Length, value);
  92. if (result == 0)
  93. return ErrorCode.NoError;
  94. }
  95. }
  96. }
  97. catch(Exception ex) { Console.WriteLine("snap7写异常,"+ex.Message+","+ex.StackTrace); }
  98. return ErrorCode.ConnectionError;
  99. }
  100. /// <summary>
  101. /// Open connection to PLC
  102. /// </summary>
  103. public ErrorCode Open()
  104. {
  105. int result = -1;
  106. if (Client != null)
  107. {
  108. result = Client.ConnectTo(IP, Rack, Slot);
  109. }
  110. return result == 0 ? ErrorCode.NoError : ErrorCode.ConnectionError;
  111. }
  112. /// <summary>
  113. /// Close connection to PLC
  114. /// </summary>
  115. public void Close()
  116. {
  117. if (Client != null)
  118. {
  119. if (Client.Connected) Client.Disconnect();
  120. }
  121. }
  122. #region IDisposable Support
  123. private bool disposedValue = false; // To detect redundant calls
  124. /// <summary>
  125. /// Dispose Plc Object
  126. /// </summary>
  127. /// <param name="disposing"></param>
  128. protected virtual void Dispose(bool disposing)
  129. {
  130. if (!disposedValue)
  131. {
  132. if (disposing)
  133. {
  134. Close();
  135. }
  136. // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
  137. // TODO: set large fields to null.
  138. disposedValue = true;
  139. }
  140. }
  141. // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
  142. // ~Plc() {
  143. // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  144. // Dispose(false);
  145. // }
  146. // This code added to correctly implement the disposable pattern.
  147. void IDisposable.Dispose()
  148. {
  149. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  150. Dispose(true);
  151. // TODO: uncomment the following line if the finalizer is overridden above.
  152. // GC.SuppressFinalize(this);
  153. }
  154. #endregion
  155. }
  156. }