Inovance_EIP.cs 125 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268
  1. using Newtonsoft.Json.Linq;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Dynamic;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.Serialization;
  11. using System.Security.Policy;
  12. using System.Text;
  13. using System.Text.RegularExpressions;
  14. using System.Threading.Tasks;
  15. using System.Windows.Forms;
  16. using System.Xml.Linq;
  17. using static System.Net.Mime.MediaTypeNames;
  18. using static System.Windows.Forms.VisualStyles.VisualStyleElement;
  19. namespace EIP_Protocol
  20. {
  21. #region MES与PLC通讯结构
  22. public enum eMachineState:short
  23. {
  24. Uninitialized=0, //未初始化状态
  25. Initializing, //初始化中...
  26. Initialized, //初始化完成
  27. Running, //运行中
  28. Paused, //暂停状态
  29. Fault, //故障状态
  30. Alarm //报警状态
  31. }
  32. public enum eMesCmd:byte
  33. {
  34. none=0,
  35. InStation = 1, //1:工站进站申请
  36. OutStation =2 //2:工站出站申请
  37. }
  38. public enum eAgvCmd
  39. {
  40. RequestPassingIn = 1, // = 1, AGV请求进料
  41. ConfirmPassInFinish = 2, //= 2, AGV请求进料完成确认
  42. RequestPassingOut = 3, //=3, AGV请求出料
  43. ConfrimPassingOutFinish = 4 //= 4, AGV请求出料完成确认
  44. }
  45. public struct XiaoMiParm
  46. {
  47. public string workstation { get; set; } //装备编码
  48. public string stationCode { get; set; } //工站ID
  49. public string deviceCode { get; set; } //工位编码
  50. }
  51. //图⽚命名需要遵循⼩⽶标准
  52. //[项⽬]_[⼯站]_[SN]_[物料-功能]_[测试时间]_[定位/检测/测量结果]_[是否原图-当前第⼏张-共⼏张]
  53. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  54. public struct CommandToPLC
  55. {
  56. [MarshalAs(UnmanagedType.U1)]
  57. public byte cmd; //1:AGV请求进料 2:AGV请求进料完成确认 3:AGV请求出料 4:AGV请求出料完成确认 PLC:成功回被PC清零
  58. [MarshalAs(UnmanagedType.I2)]
  59. public short cmdParam; //1:左边接口 2:右边接口
  60. [MarshalAs(UnmanagedType.I2)]
  61. public short cmdResult; //指令执行结果 1:OK 110:失败
  62. }
  63. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  64. public struct CommandFromPLC
  65. {
  66. [MarshalAs(UnmanagedType.U1)]
  67. public byte cmd; //1:工站进站申请 2:工站出站申请
  68. [MarshalAs(UnmanagedType.I2)]
  69. public short cmdParam; //指令参数
  70. [MarshalAs(UnmanagedType.I2)]
  71. public short cmdResult; //指令执行结果 1:OK 110:失败
  72. }
  73. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  74. public struct OP10_From_PLC
  75. {
  76. [MarshalAs(UnmanagedType.I4)]
  77. public int nThrowCount; //抛料次数
  78. [MarshalAs(UnmanagedType.R4)]
  79. public float fCleanAirPress; //清洁气压
  80. [MarshalAs(UnmanagedType.R4)]
  81. public float fCleanSpeed; //清洁速度mm/s
  82. [MarshalAs(UnmanagedType.R4)]
  83. public float fWindBladeHeight; //风刀高度mm
  84. [MarshalAs(UnmanagedType.R4)]
  85. public float fCleanTime; //清洁时间S
  86. [MarshalAs(UnmanagedType.I4)]
  87. public int nCleanCount; //清洁次数
  88. }
  89. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  90. public struct OP10_DataSet_t
  91. {
  92. [MarshalAs(UnmanagedType.I4)]
  93. public int nThrowCount; //抛料次数
  94. [MarshalAs(UnmanagedType.R4)]
  95. public float fCleanAirPress; //清洁气压
  96. [MarshalAs(UnmanagedType.R4)]
  97. public float fCleanSpeed; //清洁速度mm/s
  98. [MarshalAs(UnmanagedType.R4)]
  99. public float fWindBladeHeight; //风刀高度mm
  100. [MarshalAs(UnmanagedType.R4)]
  101. public float fCleanTime; //清洁时间S
  102. [MarshalAs(UnmanagedType.I4)]
  103. public int nCleanCount; //清洁次数
  104. [MarshalAs(UnmanagedType.I4)]
  105. public int nRemainCount; //外壳体余料数
  106. }
  107. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  108. public struct IoT_DataSet_t
  109. {
  110. [MarshalAs(UnmanagedType.I2)]
  111. public short machineState; //设备状态
  112. [MarshalAs(UnmanagedType.I2)]
  113. public short work_type; //作业类型:=1 PRESSURE_TEST(压测),=2 POINT_CHECK(点检),=3 OUT_STATION(正常跑料数据)
  114. [MarshalAs(UnmanagedType.I2)]
  115. public short testStatus; //测试状态:=1 PASS 0=FAIL
  116. [MarshalAs(UnmanagedType.I2)]
  117. public short beatAction; //节拍动作 1:上料开始 2:上料结束 3
  118. //:作业开始 4:作业结束 5:下料开始 6:下料结束
  119. [MarshalAs(UnmanagedType.I2)] //节拍返回 1:OK 2:NG
  120. public short beatReturn;
  121. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] //一个单独的位代表一个报警32*10=320
  122. public uint[] fault_codes;
  123. }
  124. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  125. public struct OP20_DataSet_t
  126. {
  127. [MarshalAs(UnmanagedType.I4)]
  128. public int nThrowCount; //抛料次数
  129. [MarshalAs(UnmanagedType.I4)]
  130. public int nRemainCount; //上盖余料数
  131. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  132. public float[] nCeJuData; //测距
  133. }
  134. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  135. public struct OP30_DataSet_t //站数据集
  136. {
  137. [MarshalAs(UnmanagedType.R4)]
  138. public float fGlueSupplySpeed; //供胶速度
  139. [MarshalAs(UnmanagedType.R4)]
  140. public float fAB_AirPress; //AB管气压
  141. [MarshalAs(UnmanagedType.R4)]
  142. public float fAB_AirPressDiff; //AB管气压差
  143. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  144. public float[] fMesHeightInfos; //产品测高信息--点胶前的测高(mm)
  145. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  146. public float[] fIntervalWeights; //可能没有:定期称重数据 A胶,B胶
  147. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  148. public float[] fRemainGlues; //剩余胶量A:0 B:1
  149. }
  150. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  151. public struct OP30_TestData_t //站数据集
  152. {
  153. [MarshalAs(UnmanagedType.R4)]
  154. public float fAB_AirPress; //AB管气压
  155. [MarshalAs(UnmanagedType.R4)]
  156. public float fAB_AirPressMax; //AB管气压(最大值)
  157. [MarshalAs(UnmanagedType.R4)]
  158. public float fAB_AirPressMin; //AB管气压(最小值)
  159. [MarshalAs(UnmanagedType.R4)]
  160. public float fAB_AirPressDiff; //AB管气压差
  161. [MarshalAs(UnmanagedType.R4)]
  162. public float fAB_AirPressDiffMax; //AB管气压差(最大值)
  163. [MarshalAs(UnmanagedType.R4)]
  164. public float fAB_AirPressDiffMin; //AB管气压差(最小值)
  165. }
  166. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  167. public struct OP30_stnDataSet_t
  168. {
  169. public BarcodeSet_t BarcodeSet; //条码集合
  170. public CommandFromPLC mesCommFrmPLC; //MES通讯
  171. public OP30_DataSet_t mesData;
  172. public IoT_DataSet_t iotData;
  173. public OP30_TestData_t testData;
  174. public OP30_OtherData otherData;
  175. }
  176. public struct OP30_OtherData
  177. {
  178. [MarshalAs(UnmanagedType.I4)]
  179. public int ChangeA; //左工位 0:取消换胶 1:换胶弹窗 2:扫码完成
  180. [MarshalAs(UnmanagedType.I4)]
  181. public int ChangeB; //右工位 0:取消换胶 1:换胶弹窗 2:扫码完成
  182. }
  183. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  184. public struct OP40_DataSet_t
  185. {
  186. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  187. public float[] fGluePosX; //胶线位置X偏差
  188. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  189. public float[] fGluePosY; //胶线位置Y偏差
  190. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  191. public float[] fGlue_Areas; //胶线面积
  192. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  193. public float[] fGlue_Heights; //胶线高度
  194. [MarshalAs(UnmanagedType.I4)]
  195. public int nResult; //胶线检测结果 1:OK 非1:NG
  196. //public Image TestPic; //测试照片
  197. }
  198. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  199. public struct OP40_TestData_t //测试项
  200. {
  201. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  202. public float[] fGlue_Areas; //胶线面积
  203. [MarshalAs(UnmanagedType.R4)]
  204. public float fGlue_AreasMax; //胶线面积(最大值)
  205. [MarshalAs(UnmanagedType.R4)]
  206. public float fGlue_AreasMin; //胶线面积(最小值)
  207. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  208. public float[] fGlue_Heights; //胶线高度
  209. [MarshalAs(UnmanagedType.R4)]
  210. public float fGlue_HeightsMax; //胶线高度(最大值)
  211. [MarshalAs(UnmanagedType.R4)]
  212. public float fGlue_HeightsMin; //胶线高度(最小值)
  213. }
  214. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  215. public struct OP50_DataSet_t
  216. {
  217. [MarshalAs(UnmanagedType.I4)]
  218. public int nIsAddPCBAsmOK; //是否组装到位
  219. [MarshalAs(UnmanagedType.I4)]
  220. public int nHaveAddPCB; //是否有ADD板
  221. [MarshalAs(UnmanagedType.R4)]
  222. public float fForceAddPCB; //装ADD板的压力
  223. [MarshalAs(UnmanagedType.I4)]
  224. public int nRemainCount; //ADD板余料数
  225. }
  226. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  227. public struct OP50_TestData_t
  228. {
  229. [MarshalAs(UnmanagedType.R4)]
  230. public float fForceAddPCB; //装ADD板的压力
  231. [MarshalAs(UnmanagedType.R4)]
  232. public float fForceAddPCBMax; //装ADD板的压力(最大值)
  233. [MarshalAs(UnmanagedType.R4)]
  234. public float fForceAddPCBMin; //装ADD板的压力(最小值)
  235. }
  236. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  237. public struct OP60_DataSet_t
  238. {
  239. [MarshalAs(UnmanagedType.I4)]
  240. public int nIsTopCoverAsmOK; //是否组装到位
  241. [MarshalAs(UnmanagedType.I4)]
  242. public int nHaveTopCover; //是否有上盖板
  243. [MarshalAs(UnmanagedType.R4)]
  244. public float fForceTopCover; //装上盖板的压力
  245. }
  246. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  247. public struct OP70_DataSet_t
  248. {
  249. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  250. public float[] fScrewTimes; //锁附时间 PLC 14颗螺丝 预留6
  251. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  252. public short[] nScrewOrders; //锁附顺序 PLC 锁螺丝的标号
  253. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  254. public short[] nScrewResults; //锁附结果 PLC
  255. [MarshalAs(UnmanagedType.I4)]
  256. public int nRemainCount; //螺丝余料数
  257. }
  258. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  259. public struct OP70_ScrewDataSet_t
  260. {
  261. [MarshalAs(UnmanagedType.R4)]
  262. public float fTorque; //上位机传到PLC的锁螺丝扭力 每次读到阿特拉斯的数据都传一次
  263. [MarshalAs(UnmanagedType.R4)]
  264. public float fCircles; //上位机传到PLC的锁螺丝圈数 每次读到阿特拉斯的数据都传一次
  265. }
  266. public class OP70_PC_CollectDataSet_t
  267. {
  268. //需要自己收集
  269. public float[] fScrewTorques; //锁附扭力
  270. public float[] fScrewCircles; //锁附圈数
  271. public float[][] fTorqueCurve; //扭力曲线
  272. }
  273. public struct OP70_stnDataSet_t
  274. {
  275. public BarcodeSet_t BarcodeSet; //条码集合
  276. public CommandFromPLC mesCommFrmPLC; //MES通讯
  277. public OP70_DataSet_t mesData;
  278. public IoT_DataSet_t iotData;
  279. public OP70_ScrewDataSet_t screwDataToPLC; //传到PLC的锁螺丝数据,用于HMI显示用
  280. }
  281. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  282. public struct BarcodeSet_t
  283. {
  284. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)] //载具条码
  285. public string strCarrierBarcode;
  286. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //产品条码
  287. public string strProductBarcode;
  288. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //工位零部件条码
  289. public string strPartBarcode;
  290. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 101)] //PCB
  291. public string strPCBBarcode;
  292. }
  293. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  294. public struct OP10_MesData_t
  295. {
  296. public BarcodeSet_t BarcodeSet; //条码集合
  297. public CommandToPLC agvCommToPLC; //AGV通讯
  298. public CommandFromPLC mesCommFrmPLC; //MES通讯
  299. public OP10_DataSet_t mesData;
  300. public IoT_DataSet_t iotData;
  301. }
  302. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  303. public struct OP20_MesData_t
  304. {
  305. public BarcodeSet_t BarcodeSet; //条码集合
  306. public CommandToPLC agvCommToPLC; //AGV通讯
  307. public CommandFromPLC mesCommFrmPLC; //MES通讯
  308. public OP20_DataSet_t mesData;
  309. public IoT_DataSet_t iotData;
  310. }
  311. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  312. public struct OP30_MesData_t
  313. {
  314. public OP30_stnDataSet_t Left;
  315. public OP30_stnDataSet_t Right;
  316. }
  317. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  318. public struct OP40_MesData_t
  319. {
  320. public BarcodeSet_t BarcodeSet; //条码集合
  321. public CommandFromPLC mesCommFrmPLC; //MES通讯
  322. public OP40_DataSet_t mesData;
  323. public IoT_DataSet_t iotData;
  324. public OP40_TestData_t testData; //测试项
  325. }
  326. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  327. public struct OP50_MesData_t
  328. {
  329. public BarcodeSet_t BarcodeSet; //条码集合
  330. public CommandToPLC agvCommToPLC; //AGV通讯
  331. public CommandFromPLC mesCommFrmPLC; //MES通讯
  332. public OP50_DataSet_t mesData;
  333. public IoT_DataSet_t iotData;
  334. public OP50_TestData_t testData; //测试项
  335. }
  336. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  337. public struct OP60_MesData_t
  338. {
  339. public BarcodeSet_t BarcodeSet; //条码集合
  340. public CommandFromPLC mesCommFrmPLC; //MES通讯
  341. public OP60_DataSet_t mesData;
  342. public IoT_DataSet_t iotData;
  343. }
  344. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  345. public struct OP70_iotDataSet_t
  346. {
  347. public IoT_DataSet_t Left;
  348. public IoT_DataSet_t Right;
  349. }
  350. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  351. public struct OP70_MesData_t
  352. {
  353. public OP70_stnDataSet_t Left;
  354. public OP70_stnDataSet_t Right;
  355. }
  356. public struct OP80_DataSet_t
  357. {
  358. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  359. public float[] fScrewHeights; //螺丝高度 PLC 14颗螺丝 预留6
  360. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  361. public short[] nScrewResults; //螺丝检测结果 PLC 1:OK 0:NG
  362. }
  363. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  364. public struct OP80_MesData_t
  365. {
  366. public BarcodeSet_t BarcodeSet; //条码集合
  367. public CommandFromPLC mesCommFrmPLC; //MES通讯
  368. public OP80_DataSet_t mesData;
  369. public IoT_DataSet_t iotData;
  370. }
  371. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  372. public struct OP90_DataSet_t
  373. {
  374. [MarshalAs(UnmanagedType.I4)]
  375. public int nThrowCount; //抛料次数
  376. [MarshalAs(UnmanagedType.I4)]
  377. public int nRemainCount; //料箱余料数
  378. }
  379. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
  380. public struct OP90_MesData_t
  381. {
  382. public BarcodeSet_t BarcodeSet; //条码集合
  383. public CommandToPLC agvCommToPLC; //AGV通讯
  384. public CommandFromPLC mesCommFrmPLC; //MES通讯
  385. public OP90_DataSet_t mesData;
  386. public IoT_DataSet_t iotData;
  387. }
  388. #endregion MES与PLC通讯结构
  389. public class Inovance_EIP
  390. {
  391. private string strTagPrefix = "Application.GVL."; //标签前缀,80站是Application.GVL_HMI.,不知道为什么反正就是这样
  392. private object m_objLock = new object();
  393. bool isStart = false;
  394. string strClaimedComputerIP = ""; //PC的IP地址 - private实际IP
  395. private int m_nInstanceId = 0; //实例ID
  396. public bool m_bConnected = false;
  397. public string _pcIPStr = string.Empty; //PC的IP地址
  398. public string _plcIPStr = string.Empty; //PLC的IP地址
  399. public bool IsConnected
  400. {
  401. get { return m_bConnected; }
  402. }
  403. public void Config_TagPrefix(string TagPrefix)
  404. {
  405. strTagPrefix = TagPrefix;
  406. }
  407. #region 自定义的结构
  408. public enum ERROR_NO : int
  409. {
  410. ERR_EIP_STOPED = -2,//协议栈未开启
  411. OTHER_ERROR = -1,
  412. SUCCESS = 0,
  413. ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED = 1,//连接的实例ID与已有的ID重复或超过最大值
  414. ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH,//连接的网络路径格式错误,无法检测出来目标IP离线等错误
  415. ERRI_CONNECTION_COUNT_LIMIT_REACHED,//达到最大连接数量
  416. ERRI_OUT_OF_MEMORY,//内存溢出,缓冲区已满
  417. ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH, //连接的网络地址无效
  418. ERRR_CONN_CONFIG_FAILED_NO_RESPONSE, //连接无响应
  419. ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE,//连接响应错误
  420. ERRR_INVALID_DESTINATION, //目标标签不存在
  421. ERRR_TAGNAME_TOO_LONG, //标签名超过255字节
  422. ERRR_REQUEST_DATA_TOO_LARGE, //请求数据超限
  423. ERRR_CONN_CONNECTION_TIMED_OUT, //活动连接响应超时,请检查目标IP是否离线
  424. ERRR_TAGNAME_CONVERT_FAILED, //标签名解析错误
  425. ERRR_WRITE_DATASIZE_UNCONSISTENT, //数据长度与标签实际长度不一致
  426. ERRR_SCAN_ERROR, //扫描标签信息失败
  427. };
  428. public enum TAG_TYPE : int
  429. {
  430. TAG_TYPE_UNDEFINE = -1,
  431. TAG_TYPE_BOOL = 0xC1, //新增
  432. TAG_TYPE_SINT = 0xC2,
  433. TAG_TYPE_INT = 0xC3,
  434. TAG_TYPE_DINT = 0xC4,
  435. TAG_TYPE_LINT = 0xC5,
  436. TAG_TYPE_USINT = 0xC6,
  437. TAG_TYPE_UINT = 0xC7,
  438. TAG_TYPE_UDINT = 0xC8,
  439. TAG_TYPE_ULINT = 0xC9,
  440. TAG_TYPE_REAL = 0xCA,
  441. TAG_TYPE_LREAL = 0xCB,
  442. TAG_TYPE_STRING = 0xD0, //新增
  443. TAG_TYPE_BYTE = 0xD1,
  444. TAG_TYPE_WORD = 0xD2,
  445. TAG_TYPE_DWORD = 0xD3,
  446. TAG_TYPE_LWORD = 0xD4,
  447. TAG_TYPE_STRUCT = 0xA2, //新增
  448. TAG_TYPE_ARRAY = 0xA3
  449. };
  450. enum EtIPConnectionState : int
  451. {
  452. ConnectionNonExistent = 0x0, //该实例未有连接
  453. ConnectionConfiguring = 0x1, //连接正在打开过程中
  454. ConnectionEstablished = 0x3, //连接已成功建立并在活动中
  455. ConnectionTimedOut = 0x4, //连接超时
  456. ConnectionClosing = 0x6 //连接正在关闭中
  457. };
  458. public const uint INVALID_MEMBER = 0xffffffff; //Member is not valid flag should be used when no member should be specified in the UCMM
  459. public struct tagTagReadData
  460. {
  461. public string pName;
  462. public int nElementCount;
  463. public int nArrayPos;
  464. };
  465. public struct tagTagReadDataBase
  466. {
  467. public string pName;
  468. public int nElementCount;
  469. };
  470. public struct tagTagRetValue
  471. {
  472. public IntPtr pData;
  473. public TAG_TYPE pType;
  474. public int nDataLength;
  475. //tagTagRetValue()
  476. //{
  477. // pData = NULL;
  478. // pType = TAG_TYPE_UNDEFINE;
  479. // nDataLength = 0;
  480. //}
  481. //~tagTagRetValue()
  482. //{
  483. // if (pData)
  484. // {
  485. // delete pData;
  486. // pData = NULL;
  487. // }
  488. //}
  489. };
  490. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
  491. public struct tagTagWriteData
  492. {
  493. public string pName;
  494. public IntPtr pData;
  495. public TAG_TYPE pType;
  496. public int nArrayPos;
  497. public int nDataLength;
  498. public int nElementCount;
  499. };
  500. public struct tagTagWriteDataBase
  501. {
  502. public string pName;
  503. public IntPtr pData;
  504. public TAG_TYPE pType;
  505. public int nDataLength;
  506. public int nElementCount;
  507. };
  508. public class MySerializationBinder : SerializationBinder
  509. {
  510. public override Type BindToType(string assemblyName, string typeName)
  511. {
  512. // 如果类型名称是"MyNamespace.MyUnsupportedType",则将其转换为"MyNamespace.MySupportType"
  513. if (typeName == "MyNamespace.MyUnsupportedType")
  514. {
  515. return Type.GetType("MyNamespace.MySupportType");
  516. }
  517. // 否则返回null,表示无法进行转换
  518. return null;
  519. }
  520. }
  521. #endregion 自定义的结构
  522. #region 动态类型
  523. public class DynamicMethodProvider
  524. {
  525. public dynamic GetDynamicValue(string propertyName)
  526. {
  527. dynamic result;
  528. switch (propertyName)
  529. {
  530. case "Name":
  531. result = "John Doe";
  532. break;
  533. case "Age":
  534. result = 30;
  535. break;
  536. default:
  537. result = new ExpandoObject();
  538. ((IDictionary<string, object>)result).Add("UnknownProperty", "UnknownValue");
  539. break;
  540. }
  541. return result;
  542. }
  543. }
  544. public static T CreateElement<T>()
  545. {
  546. Type t = typeof(T);
  547. return (T)t.Assembly.CreateInstance(t.FullName);
  548. }
  549. public static dynamic CreateElement(string typename)
  550. {
  551. Type t = GetTypeByName(typename);
  552. return t.Assembly.CreateInstance(t.FullName);
  553. }
  554. public static Type GetTypeByName(string typename)
  555. {
  556. Type t = null;
  557. string source = typename;
  558. try
  559. {
  560. t = Type.GetType(source);
  561. if (t != null)
  562. {
  563. return t;
  564. }
  565. Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
  566. foreach (Assembly ass in assembly)
  567. {
  568. t = ass.GetType(source);
  569. if (t != null)
  570. {
  571. return t;
  572. }
  573. Type[] ts = ass.GetTypes();
  574. foreach (Type st in ts)
  575. {
  576. if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))
  577. {
  578. return st;
  579. }
  580. }
  581. }
  582. }
  583. catch (Exception ex)
  584. {
  585. }
  586. return t;
  587. }
  588. public static Type GetTypeByName2(string typename)
  589. {
  590. Type t = null;
  591. string source = typename;
  592. if (source.IndexOf('<') > 0)
  593. {
  594. List<string> lv = new List<string>();
  595. while (Regex.IsMatch(source, @"<[^<>]+>"))
  596. {
  597. lv.Add(Regex.Match(source, @"(?<=<)[^<>]+(?=>)").Value);
  598. source = Regex.Replace(source, @"<[^<>]+>", "/" + (lv.Count - 1));
  599. }
  600. List<Type[]> args = new List<Type[]>();
  601. for (int i = 0; i < lv.Count; i++)
  602. {
  603. List<Type> arg = new List<Type>();
  604. string[] sp = lv[i].Split(',');
  605. for (int j = 0; j < sp.Length; j++)
  606. {
  607. string s = sp[j].Trim();
  608. if (!string.IsNullOrEmpty(s))
  609. {
  610. if (Regex.IsMatch(s, @"/\d+$"))
  611. {
  612. Match m = Regex.Match(s, @"^([^/\s]+)\s*/(\d+)$");
  613. if (!m.Success)
  614. {
  615. throw new Exception("");
  616. }
  617. Type p = GetTypeByName(m.Groups[1].Value);
  618. Type c = p.MakeGenericType(args[Convert.ToInt32(m.Groups[2].Value)]);
  619. arg.Add(c);
  620. }
  621. else
  622. {
  623. arg.Add(GetTypeByName(s));
  624. }
  625. }
  626. }
  627. args.Add(arg.ToArray());
  628. }
  629. Match f = Regex.Match(source, @"^([^/\s]+)\s*/(\d+)$");
  630. if (!f.Success)
  631. {
  632. throw new Exception("");
  633. }
  634. Type fp = GetTypeByName(f.Groups[1].Value);
  635. Type fc = fp.MakeGenericType(args[Convert.ToInt32(f.Groups[2].Value)]);
  636. return fc;
  637. }
  638. else
  639. {
  640. try
  641. {
  642. t = Type.GetType(source);
  643. if (t != null)
  644. {
  645. return t;
  646. }
  647. Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
  648. foreach (Assembly ass in assembly)
  649. {
  650. t = ass.GetType(source);
  651. if (t != null)
  652. {
  653. return t;
  654. }
  655. Type[] ts = ass.GetTypes();
  656. foreach (Type st in ts)
  657. {
  658. //if (Regex.IsMatch(st.FullName, @"\." + Regex.FormatRegEx(source) + @"(`?\d+)?$"))
  659. if (Regex.IsMatch(st.FullName, @"\." + source + @"(`?\d+)?$"))
  660. {
  661. return st;
  662. }
  663. }
  664. }
  665. }
  666. catch (Exception ex)
  667. {
  668. }
  669. }
  670. return t;
  671. }
  672. #endregion 动态类型
  673. #region DLL
  674. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  675. public static extern void EipStart();
  676. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  677. public static extern void EipStop();
  678. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  679. public static extern int EipOpenConnection(string ipAddress, IntPtr instanceID);
  680. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  681. public static extern int EipCloseConnection(int nID);
  682. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  683. public static extern int EipReadTag(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1, uint nPos = INVALID_MEMBER);
  684. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  685. public static extern int EipWriteTag(int instanceID, string tagName, int type, byte[] source, int dataLength, ushort elementCount = 1, uint nPos = INVALID_MEMBER/*, uint strLen = 0*/);
  686. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  687. public static extern int EipGetConnectionState(int nID);
  688. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  689. public static extern bool EipStartExt(string ipAddress, uint nPort = 0);
  690. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  691. public static extern int EipReadTagList(int instanceID, int nNumOfTags, tagTagReadData[] pTagList, ref tagTagRetValue pdest);
  692. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  693. public static extern ERROR_NO EipWriteTagList(int instanceID, int nNumOfTags, tagTagWriteData[] pTagWritenData);
  694. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  695. public static extern bool DeleteTagListStru(ref tagTagRetValue pRetValue, int nNumOfTags);
  696. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  697. public static extern int EipReadTagExt(int instanceID, string tagName, IntPtr type, byte[] dest, int dataLength, ushort elementCount = 1);
  698. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  699. public static extern int EipWriteTagExt(int instanceID, string tagName, int type, byte[] source, int dataLength, ushort elementCount = 1);
  700. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  701. public static extern int EipReadTagListExt(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest, bool bScan = false);
  702. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  703. public static extern ERROR_NO EipWriteTagListExt(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData, bool bScan = false);
  704. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  705. public static extern ERROR_NO EipReadTagExt2(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);
  706. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  707. public static extern ERROR_NO EipWriteTagExt2(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);
  708. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  709. public static extern void ResetTagInfo();
  710. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  711. public static extern ERROR_NO EipReadTagRaw(int iInstanceID, tagTagReadDataBase[] pTagList, ref tagTagRetValue pDest);
  712. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  713. public static extern ERROR_NO EipWriteTagRaw(int iInstanceID, tagTagWriteDataBase[] pTagWritenData);
  714. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  715. public static extern int EipReadTagListRaw(int instanceID, int nNumOfTags, tagTagReadDataBase[] pTagList, ref tagTagRetValue pdest);
  716. [DllImport("EipTagSimple.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  717. public static extern ERROR_NO EipWriteTagListRaw(int instanceID, int nNumOfTags, tagTagWriteDataBase[] pTagWritenData);
  718. #endregion DLL
  719. #region private方法
  720. private string getTypeString(TAG_TYPE eType)
  721. {
  722. string strType = "";
  723. switch (eType)
  724. {
  725. case TAG_TYPE.TAG_TYPE_SINT:
  726. strType = "SINT";
  727. break;
  728. case TAG_TYPE.TAG_TYPE_INT:
  729. strType = "INT";
  730. break;
  731. case TAG_TYPE.TAG_TYPE_DINT:
  732. strType = "DINT";
  733. break;
  734. case TAG_TYPE.TAG_TYPE_LINT:
  735. strType = "LINT";
  736. break;
  737. case TAG_TYPE.TAG_TYPE_USINT:
  738. strType = "USINT";
  739. break;
  740. case TAG_TYPE.TAG_TYPE_UINT:
  741. strType = "UINT";
  742. break;
  743. case TAG_TYPE.TAG_TYPE_UDINT:
  744. strType = "UDINT";
  745. break;
  746. case TAG_TYPE.TAG_TYPE_ULINT:
  747. strType = "ULINT";
  748. break;
  749. case TAG_TYPE.TAG_TYPE_REAL:
  750. strType = "REAL";
  751. break;
  752. case TAG_TYPE.TAG_TYPE_LREAL:
  753. strType = "LREAL";
  754. break;
  755. case TAG_TYPE.TAG_TYPE_BYTE:
  756. strType = "BYTE";
  757. break;
  758. case TAG_TYPE.TAG_TYPE_WORD:
  759. strType = "WORD";
  760. break;
  761. case TAG_TYPE.TAG_TYPE_DWORD:
  762. strType = "DWORD";
  763. break;
  764. case TAG_TYPE.TAG_TYPE_LWORD:
  765. strType = "LWORD";
  766. break;
  767. case TAG_TYPE.TAG_TYPE_BOOL:
  768. strType = "BOOL";
  769. break;
  770. case TAG_TYPE.TAG_TYPE_STRING:
  771. strType = "STRING";
  772. break;
  773. case TAG_TYPE.TAG_TYPE_STRUCT:
  774. strType = "STRUCT";
  775. break;
  776. default:
  777. break;
  778. }
  779. return strType;
  780. }
  781. private byte[] StringToBytes(string s)
  782. {
  783. string[] str = s.Split(' ');
  784. int n = str.Length;
  785. byte[] cmdBytes = null;
  786. int p = 0;
  787. for (int k = 0; k < n; k++)
  788. {
  789. int sLen = str[k].Length;
  790. int bytesLen = sLen / 2;
  791. int position = 0;
  792. byte[] bytes = new byte[bytesLen];
  793. for (int i = 0; i < bytesLen; i++)
  794. {
  795. string abyte = str[k].Substring(position, 2);
  796. bytes[i] = Convert.ToByte(abyte, 16);
  797. position += 2;
  798. }
  799. if (position >= 2)
  800. {
  801. byte[] cmdBytes2 = new byte[p + bytesLen];
  802. if (cmdBytes != null)
  803. {
  804. Array.Copy(cmdBytes, 0, cmdBytes2, 0, p);
  805. }
  806. Array.Copy(bytes, 0, cmdBytes2, p, bytesLen);
  807. cmdBytes = cmdBytes2;
  808. p += bytesLen;
  809. }
  810. }
  811. return cmdBytes;
  812. }
  813. private (int,string) OpenEip(string strLocalComputerIp)
  814. {
  815. //limit input of controller
  816. bool blnTest = false;
  817. bool bValidIP = true;
  818. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  819. blnTest = regex.IsMatch(strLocalComputerIp);
  820. if (blnTest == true)
  821. {
  822. string[] strTemp = strLocalComputerIp.Split(new char[] { '.' });
  823. if (strTemp.Length < 4)
  824. {
  825. bValidIP = false;
  826. return (-1, "不符合IP格式");
  827. }
  828. for (int i = 0; (i < strTemp.Length) && bValidIP; i++)
  829. {
  830. if (Convert.ToInt32(strTemp[i]) > 255)
  831. {
  832. //大于255则提示,不符合IP格式
  833. bValidIP = false;
  834. return (-2, "IP大于255,不符合IP格式");
  835. }
  836. }
  837. }
  838. else
  839. {
  840. //输入非数字则提示,不符合IP格式
  841. bValidIP = false;
  842. return (-3, "输入非数字,不符合IP格式");
  843. }
  844. if (bValidIP)
  845. {
  846. if (!isStart)
  847. {
  848. if (EipStartExt(strLocalComputerIp, 0))
  849. {
  850. isStart = true;
  851. strClaimedComputerIP = strLocalComputerIp;
  852. return (0, "EIP协议栈开启成功");
  853. }
  854. else
  855. {
  856. isStart = false;
  857. return (1, "EIP协议栈开启失败");
  858. }
  859. }
  860. else
  861. {
  862. if (string.Compare(strClaimedComputerIP, strLocalComputerIp) != 0)
  863. {
  864. return (2,"更改上位机IP时需先关闭协议栈,再开启");
  865. }
  866. else
  867. {
  868. return (3, "EIP协议栈已经开启");
  869. }
  870. }
  871. }
  872. return (-4, "无效IP");
  873. }
  874. private (bool,string) CloseEip()
  875. {
  876. if (isStart)
  877. {
  878. EipStop();
  879. isStart = false;
  880. return (true, "EIP协议栈关闭");
  881. }
  882. else
  883. {
  884. return (false, "EIP协议栈未开启,请先开启");
  885. }
  886. }
  887. #endregion private方法
  888. #region 连接/断开
  889. #region 连接方式 一
  890. public Inovance_EIP() { }
  891. /// <summary>
  892. /// 连接PLC
  893. /// </summary>
  894. /// <param name="strComputerIp">PC的IP地址</param>
  895. /// <param name="strPlcIp">PLC的IP地址</param>
  896. /// <returns>成功:True 失败:False </returns>
  897. public (int,string) Connect(string strComputerIp,string strPlcIp)
  898. {
  899. _pcIPStr = strComputerIp;
  900. _plcIPStr = strPlcIp;
  901. lock (m_objLock)
  902. {
  903. string strRet = "";
  904. int nRet = 0;
  905. if (!isStart) (nRet, strRet) = OpenEip(strComputerIp);
  906. if (nRet != 0) return (nRet, strRet);
  907. bool blnTest = false;
  908. bool bValidIP = true;
  909. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  910. blnTest = regex.IsMatch(strPlcIp);
  911. if (blnTest == true)
  912. {
  913. string[] strTemp = strPlcIp.Split(new char[] { '.' });
  914. for (int i = 0; i < strTemp.Length; i++)
  915. {
  916. if (Convert.ToInt32(strTemp[i]) > 255)
  917. {
  918. bValidIP = false;
  919. return (-10, "PLC IP 大于255,不符合IP格式");
  920. }
  921. }
  922. }
  923. else
  924. {
  925. bValidIP = false;
  926. return (-11, "PLC IP输入非数字,不符合IP格式");
  927. }
  928. if (bValidIP)
  929. {
  930. if (strPlcIp.CompareTo(strClaimedComputerIP) == 0)
  931. {
  932. string strLog = "";
  933. strLog += "上位机IP与PLC IP相同,请重新输入";
  934. return (-20, strLog);
  935. }
  936. if (strPlcIp.CompareTo(strComputerIp) == 0)
  937. {
  938. string strLog = "";
  939. strLog += "上位机IP与PLC IP相同,请重新输入";
  940. return (-21, strLog);
  941. }
  942. int instanceId = 0;
  943. ERROR_NO errorNo;
  944. unsafe
  945. {
  946. errorNo = (ERROR_NO)EipOpenConnection(strPlcIp, (IntPtr)(&instanceId));
  947. }
  948. m_nInstanceId = instanceId;
  949. string str = "";
  950. str += "\n请求创建PLC连接 ip:";
  951. str += strPlcIp;
  952. str += " ";
  953. if (errorNo != ERROR_NO.SUCCESS)
  954. {
  955. m_bConnected = false;
  956. str += ("失败 ");
  957. switch (errorNo)
  958. {
  959. case ERROR_NO.ERR_EIP_STOPED:
  960. str += ("协议栈未开启");
  961. break;
  962. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  963. str += ("连接的实例ID与已有的ID重复或超过最大值");
  964. break;
  965. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  966. str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  967. break;
  968. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  969. str += ("达到最大连接数量");
  970. break;
  971. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  972. str += ("内存溢出,缓冲区已满");
  973. break;
  974. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  975. str += ("连接的网络地址无效");
  976. break;
  977. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  978. str += ("连接无响应");
  979. break;
  980. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  981. str += ("连接响应错误");
  982. break;
  983. default:
  984. str += ("其他错误");
  985. break;
  986. }
  987. }
  988. else
  989. {
  990. str += "成功";
  991. str += " 分配的实例ID 为 ";
  992. str += instanceId.ToString();
  993. m_bConnected = true;
  994. return (0, str);
  995. }
  996. str += "\n";
  997. return (100 + (int)errorNo, str);
  998. }
  999. }
  1000. return (1000, "Error");
  1001. }
  1002. #endregion 连接方式 一
  1003. #region 连接方式 二
  1004. /// <summary>
  1005. ///
  1006. /// </summary>
  1007. /// <param name="strComputerIp">PC的IP地址</param>
  1008. /// <param name="strPlcIp">PLC的IP地址</param>
  1009. public Inovance_EIP(string strComputerIp, string strPlcIp)
  1010. {
  1011. _pcIPStr = strComputerIp;
  1012. _plcIPStr = strPlcIp;
  1013. }
  1014. /// <summary>
  1015. /// 连接PLC
  1016. /// </summary>
  1017. /// <returns>成功:True 失败:False </returns>
  1018. public (int, string) Connect()
  1019. {
  1020. lock (m_objLock)
  1021. {
  1022. string strRet = "";
  1023. int nRet = 0;
  1024. if (!isStart) (nRet, strRet) = OpenEip(_pcIPStr);
  1025. if (nRet != 0) return (nRet, strRet);
  1026. bool blnTest = false;
  1027. bool bValidIP = true;
  1028. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  1029. blnTest = regex.IsMatch(_plcIPStr);
  1030. if (blnTest == true)
  1031. {
  1032. string[] strTemp = _plcIPStr.Split(new char[] { '.' });
  1033. for (int i = 0; i < strTemp.Length; i++)
  1034. {
  1035. if (Convert.ToInt32(strTemp[i]) > 255)
  1036. {
  1037. bValidIP = false;
  1038. return (-10, "PLC IP 大于255,不符合IP格式");
  1039. }
  1040. }
  1041. }
  1042. else
  1043. {
  1044. bValidIP = false;
  1045. return (-11, "PLC IP输入非数字,不符合IP格式");
  1046. }
  1047. if (bValidIP)
  1048. {
  1049. if (_plcIPStr.CompareTo(strClaimedComputerIP) == 0)
  1050. {
  1051. string strLog = "";
  1052. strLog += "上位机IP与PLC IP相同,请重新输入";
  1053. return (-20, strLog);
  1054. }
  1055. if (_plcIPStr.CompareTo(_pcIPStr) == 0)
  1056. {
  1057. string strLog = "";
  1058. strLog += "上位机IP与PLC IP相同,请重新输入";
  1059. return (-21, strLog);
  1060. }
  1061. int instanceId = 0;
  1062. ERROR_NO errorNo;
  1063. unsafe
  1064. {
  1065. errorNo = (ERROR_NO)EipOpenConnection(_plcIPStr, (IntPtr)(&instanceId));
  1066. }
  1067. m_nInstanceId = instanceId;
  1068. string str = "";
  1069. str += "\n请求创建PLC连接 ip:";
  1070. str += _plcIPStr;
  1071. str += " ";
  1072. if (errorNo != ERROR_NO.SUCCESS)
  1073. {
  1074. m_bConnected = false;
  1075. str += ("失败 ");
  1076. switch (errorNo)
  1077. {
  1078. case ERROR_NO.ERR_EIP_STOPED:
  1079. str += ("协议栈未开启");
  1080. break;
  1081. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1082. str += ("连接的实例ID与已有的ID重复或超过最大值");
  1083. break;
  1084. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1085. str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1086. break;
  1087. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1088. str += ("达到最大连接数量");
  1089. break;
  1090. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1091. str += ("内存溢出,缓冲区已满");
  1092. break;
  1093. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1094. str += ("连接的网络地址无效");
  1095. break;
  1096. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1097. str += ("连接无响应");
  1098. break;
  1099. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1100. str += ("连接响应错误");
  1101. break;
  1102. default:
  1103. str += ("其他错误");
  1104. break;
  1105. }
  1106. }
  1107. else
  1108. {
  1109. str += "成功";
  1110. str += " 分配的实例ID 为 ";
  1111. str += instanceId.ToString();
  1112. m_bConnected = true;
  1113. return (0, str);
  1114. }
  1115. str += "\n";
  1116. return (100 + (int)errorNo, str);
  1117. }
  1118. }
  1119. return (1000, "Error");
  1120. }
  1121. #endregion 连接方式 二
  1122. /// <summary>
  1123. /// 断开连接
  1124. /// </summary>
  1125. /// <returns>成功:True 失败:False</returns>
  1126. public bool Disconnect()
  1127. {
  1128. lock (m_objLock)
  1129. {
  1130. if (m_nInstanceId == 0 || !m_bConnected)
  1131. {
  1132. m_nInstanceId = 0;
  1133. m_bConnected = false;
  1134. return true;
  1135. }
  1136. ERROR_NO errorNo = (ERROR_NO)EipCloseConnection(m_nInstanceId);
  1137. //string str = "";
  1138. if (errorNo != ERROR_NO.SUCCESS)
  1139. {
  1140. //str += "失败";
  1141. m_bConnected = false;
  1142. m_nInstanceId = 0;
  1143. return false;
  1144. }
  1145. else
  1146. {
  1147. //str += "成功";
  1148. m_bConnected = false;
  1149. m_nInstanceId = 0;
  1150. CloseEip();
  1151. return true;
  1152. }
  1153. }
  1154. }
  1155. #endregion 连接/断开
  1156. public (int,string) Read_Tag(string strTagName, int nCount, out byte[] pBuf)
  1157. {
  1158. pBuf = null;
  1159. string strType = "";
  1160. lock (m_objLock)
  1161. {
  1162. if (!m_bConnected) return (-1,"未连接");
  1163. string tagName = strTagName;
  1164. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);
  1165. if (m_nInstanceId <= 0)
  1166. {
  1167. return (-2, "实例ID需大于0");
  1168. }
  1169. if (tagNameUTF8.Length > 255)
  1170. {
  1171. return (-3, "标签名长度超过255字节");
  1172. }
  1173. ushort elementCount = (ushort)nCount;
  1174. if (elementCount > 0)
  1175. {
  1176. int destLength = 1400;
  1177. byte[] dest = new byte[destLength];
  1178. char[] cChar = Encoding.ASCII.GetChars(dest);
  1179. //TAG_TYPE type = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1180. //int returnLength = 0;
  1181. tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[1];
  1182. pTaglist[0].pName = tagName;
  1183. pTaglist[0].nElementCount = elementCount;
  1184. tagTagRetValue[] tagValue = new tagTagRetValue[1];
  1185. ERROR_NO errorNo = ERROR_NO.OTHER_ERROR;
  1186. unsafe
  1187. {
  1188. errorNo = EipReadTagExt2(m_nInstanceId, pTaglist, ref tagValue[0]);
  1189. }
  1190. string strLog = "";
  1191. strLog += "读取请求";
  1192. if (/*returnLength < 0*/errorNo != ERROR_NO.SUCCESS)
  1193. {
  1194. strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1195. switch (/*returnLength*/errorNo)
  1196. {
  1197. //case -1:
  1198. // strLog += ("其他错误");
  1199. // break;
  1200. //case -2:
  1201. // strLog += ("协议栈未开启");
  1202. // break;
  1203. //case -3:
  1204. // strLog += ("实例id小于或等于0");
  1205. // break;
  1206. //case -4:
  1207. // strLog += ("标签名长度大于255字节");
  1208. // break;
  1209. //case -5:
  1210. // strLog += ("目标标签不存在");
  1211. // break;
  1212. //case -6:
  1213. // strLog += ("响应超时,请检查设备是否离线");
  1214. // break;
  1215. //case -7:
  1216. // strLog += ("标签名解析错误");
  1217. // break;
  1218. //case -8:
  1219. // strLog += ("扫描标签信息失败");
  1220. // break;
  1221. //default:
  1222. // strLog += ("其他错误");
  1223. // break;
  1224. case ERROR_NO.ERR_EIP_STOPED:
  1225. strLog += ("协议栈未开启");
  1226. break;
  1227. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1228. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1229. break;
  1230. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1231. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1232. break;
  1233. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1234. strLog += ("达到最大连接数量");
  1235. break;
  1236. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1237. strLog += ("内存溢出,缓冲区已满");
  1238. break;
  1239. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1240. strLog += ("连接的网络地址无效");
  1241. break;
  1242. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1243. strLog += ("连接无响应");
  1244. break;
  1245. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1246. strLog += ("连接响应错误");
  1247. break;
  1248. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1249. strLog += ("目标标签不存在");
  1250. break;
  1251. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1252. strLog += ("标签名超过255字节");
  1253. break;
  1254. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1255. strLog += ("请求数据超限");
  1256. break;
  1257. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1258. strLog += ("响应超时,请检查设备是否离线");
  1259. break;
  1260. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1261. strLog += ("标签名解析错误");
  1262. break;
  1263. case ERROR_NO.ERRR_SCAN_ERROR:
  1264. strLog += ("扫描标签信息失败");
  1265. break;
  1266. default:
  1267. strLog += ("其他错误");
  1268. break;
  1269. }
  1270. strLog += "\n";
  1271. return (10,strLog);
  1272. }
  1273. else
  1274. {
  1275. switch (/*type*/tagValue[0].pType)
  1276. {
  1277. case TAG_TYPE.TAG_TYPE_BOOL:
  1278. strType += "Boolean";
  1279. break;
  1280. case TAG_TYPE.TAG_TYPE_SINT:
  1281. strType += "SByte";
  1282. break;
  1283. case TAG_TYPE.TAG_TYPE_INT:
  1284. strType += "Int16";
  1285. break;
  1286. case TAG_TYPE.TAG_TYPE_DINT:
  1287. strType += "Int32";
  1288. break;
  1289. case TAG_TYPE.TAG_TYPE_LINT:
  1290. strType += "Int64";
  1291. break;
  1292. case TAG_TYPE.TAG_TYPE_USINT:
  1293. strType += "Byte";
  1294. break;
  1295. case TAG_TYPE.TAG_TYPE_UINT:
  1296. strType += "UInt16";
  1297. break;
  1298. case TAG_TYPE.TAG_TYPE_UDINT:
  1299. strType += "UInt32";
  1300. break;
  1301. case TAG_TYPE.TAG_TYPE_ULINT:
  1302. strType += "UInt64";
  1303. break;
  1304. case TAG_TYPE.TAG_TYPE_REAL:
  1305. strType += "Single";
  1306. break;
  1307. case TAG_TYPE.TAG_TYPE_LREAL:
  1308. strType += "Double";
  1309. break;
  1310. case TAG_TYPE.TAG_TYPE_STRING:
  1311. strType += "String";
  1312. break;
  1313. case TAG_TYPE.TAG_TYPE_BYTE:
  1314. strType += "Byte";
  1315. break;
  1316. case TAG_TYPE.TAG_TYPE_WORD:
  1317. strType += "UInt16";
  1318. break;
  1319. case TAG_TYPE.TAG_TYPE_DWORD:
  1320. strType += "UInt32";
  1321. break;
  1322. case TAG_TYPE.TAG_TYPE_LWORD:
  1323. strType += "UInt64";
  1324. break;
  1325. case TAG_TYPE.TAG_TYPE_STRUCT:
  1326. strType += "STRUCT";
  1327. break;
  1328. case TAG_TYPE.TAG_TYPE_ARRAY:
  1329. strType += "ARRAY";
  1330. break;
  1331. default:
  1332. break;
  1333. }
  1334. pBuf = new byte[tagValue[0].nDataLength];
  1335. unsafe
  1336. {
  1337. byte* memBytePtr = (byte*)tagValue[0].pData.ToPointer();
  1338. for (int j = 0; j < tagValue[0].nDataLength; j++)
  1339. {
  1340. pBuf[j] = memBytePtr[j];
  1341. //string str = "";
  1342. //str += j.ToString() + ": ";
  1343. //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";
  1344. }
  1345. }
  1346. DeleteTagListStru(ref tagValue[0], 1); //调用接口释放内存
  1347. }
  1348. }
  1349. else
  1350. {
  1351. return (-10, "元素个数参数错误,必须>0");
  1352. }
  1353. return (0, strType);
  1354. }
  1355. }
  1356. public (int, string) Write_Tag(string strTagName, int nCount, byte[] pBuf)
  1357. {
  1358. lock (m_objLock)
  1359. {
  1360. if (!m_bConnected) return (-1, "未连接");
  1361. string tagName = strTagName;
  1362. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(tagName);
  1363. if (m_nInstanceId <= 0)
  1364. {
  1365. return (-2, "实例ID需大于0");
  1366. }
  1367. if (tagNameUTF8.Length > 255)
  1368. {
  1369. return (-3, "标签名长度超过255字节");
  1370. }
  1371. ushort elementCount = (ushort)nCount;
  1372. if ((pBuf.Length < 1) || (elementCount < 1))
  1373. {
  1374. return (-4, "请求个数必须大于0,请重新输入");
  1375. }
  1376. if (pBuf.Length > 1400)
  1377. {
  1378. return (-5, "标签数据长度超过1400字节,请重新输入");
  1379. }
  1380. int dataLength = pBuf.Length;
  1381. tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[1];
  1382. //标签1属性
  1383. pTaglist[0].pName = tagName;
  1384. pTaglist[0].nElementCount = elementCount;
  1385. pTaglist[0].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1386. pTaglist[0].pData = Marshal.AllocHGlobal(1400);
  1387. pTaglist[0].nDataLength = dataLength;
  1388. byte temp = 0;
  1389. for (int i = 0; i < dataLength; ++i)
  1390. {
  1391. temp = pBuf[i];
  1392. Marshal.WriteByte(pTaglist[0].pData + i * sizeof(byte), temp);
  1393. }
  1394. //ERROR_NO errorNo = (ERROR_NO)EipWriteTag(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount, arrayPos/*, strLen*/);
  1395. //ERROR_NO errorNo = (ERROR_NO)EipWriteTagExt(m_nInstanceId, tagName, (int)type, source, dataLength, elementCount);
  1396. ERROR_NO errorNo = EipWriteTagExt2(m_nInstanceId, pTaglist);
  1397. //ERROR_NO errorNo = EipWriteTagRaw(instanceId, pTaglist);
  1398. string strLog = "";
  1399. strLog += "\n写入请求 ";
  1400. if (errorNo != ERROR_NO.SUCCESS)
  1401. {
  1402. strLog += " 失败 标签名:" + tagName + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1403. switch (errorNo)
  1404. {
  1405. case ERROR_NO.ERR_EIP_STOPED:
  1406. strLog += ("协议栈未开启");
  1407. break;
  1408. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1409. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1410. break;
  1411. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1412. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1413. break;
  1414. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1415. strLog += ("达到最大连接数量");
  1416. break;
  1417. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1418. strLog += ("内存溢出,缓冲区已满");
  1419. break;
  1420. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1421. strLog += ("连接的网络地址无效");
  1422. break;
  1423. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1424. strLog += ("连接无响应");
  1425. break;
  1426. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1427. strLog += ("连接响应错误");
  1428. break;
  1429. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1430. strLog += ("目标标签不存在");
  1431. break;
  1432. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1433. strLog += ("标签名超过255字节");
  1434. break;
  1435. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1436. strLog += ("请求数据超限");
  1437. break;
  1438. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1439. strLog += ("响应超时,请检查设备是否离线");
  1440. break;
  1441. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1442. strLog += ("标签名解析错误");
  1443. break;
  1444. case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:
  1445. strLog += ("写入数据长度与标签实际长度不一致");
  1446. break;
  1447. case ERROR_NO.ERRR_SCAN_ERROR:
  1448. strLog += ("扫描标签信息失败");
  1449. break;
  1450. default:
  1451. strLog += ("其他错误");
  1452. break;
  1453. }
  1454. strLog += "\n";
  1455. return (10, strLog);
  1456. }
  1457. else
  1458. {
  1459. return (0, "OK");
  1460. }
  1461. }
  1462. }
  1463. /// <summary>
  1464. /// 标签结构
  1465. /// </summary>
  1466. public struct StructTag
  1467. {
  1468. public string strTagName;
  1469. public Type tTagType;
  1470. public int nCount;
  1471. }
  1472. /// <summary>
  1473. /// 一次读取多个标签
  1474. /// </summary>
  1475. /// <param name="stTagList">多个标签的列表</param>
  1476. /// <param name="pBuf">多个标签的返回值</param>
  1477. /// <returns>函数执行结构值,非零异常,零成功</returns>
  1478. public (int, string) Read_Tags(List<StructTag> stTagList, out byte[][] pBuf)
  1479. {
  1480. pBuf = null;
  1481. string strType = "";
  1482. lock (m_objLock)
  1483. {
  1484. if (!m_bConnected) return (-1, "未连接");
  1485. if (m_nInstanceId <= 0)
  1486. {
  1487. return (-2, "实例ID需大于0");
  1488. }
  1489. if (stTagList == null) return (-3, "标签列表空");
  1490. int nNumOfTags = stTagList.Count;
  1491. if (nNumOfTags < 1) return (-4, "标签列表长度空");
  1492. for (int i = 0; i < nNumOfTags; i++)
  1493. {
  1494. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(stTagList[i].strTagName);
  1495. if (tagNameUTF8.Length > 255)
  1496. {
  1497. return (-5, "标签名长度超过255字节");
  1498. }
  1499. if (stTagList[i].nCount < 1) return (-6, "标签读取长度小于1");
  1500. }
  1501. tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[nNumOfTags];
  1502. for (int i = 0; i < nNumOfTags; i++)
  1503. {
  1504. pTaglist[i].pName = stTagList[i].strTagName;
  1505. pTaglist[i].nElementCount = stTagList[i].nCount;
  1506. }
  1507. tagTagRetValue[] pTagsValue = new tagTagRetValue[nNumOfTags];
  1508. pBuf = new byte[nNumOfTags][];
  1509. if (pBuf == null) return (-7, "分配内存失败,可能内存不足");
  1510. //ERROR_NO errorNo = (ERROR_NO)EipReadTagList(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);
  1511. ERROR_NO errorNo = (ERROR_NO)EipReadTagListExt(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0], true);
  1512. //ERROR_NO errorNo = (ERROR_NO)EipReadTagListRaw(m_nInstanceId, nNumOfTags, pTaglist, ref pTagsValue[0]);
  1513. string strLog = "";
  1514. strLog += "\n读取请求";
  1515. if (errorNo != ERROR_NO.SUCCESS)
  1516. {
  1517. strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1518. switch (errorNo)
  1519. {
  1520. case ERROR_NO.ERR_EIP_STOPED:
  1521. strLog += ("协议栈未开启");
  1522. break;
  1523. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1524. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1525. break;
  1526. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1527. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1528. break;
  1529. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1530. strLog += ("达到最大连接数量");
  1531. break;
  1532. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1533. strLog += ("内存溢出,缓冲区已满");
  1534. break;
  1535. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1536. strLog += ("连接的网络地址无效");
  1537. break;
  1538. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1539. strLog += ("连接无响应");
  1540. break;
  1541. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1542. strLog += ("连接响应错误");
  1543. break;
  1544. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1545. strLog += ("目标标签不存在");
  1546. break;
  1547. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1548. strLog += ("标签名超过255字节");
  1549. break;
  1550. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1551. strLog += ("请求数据超限");
  1552. break;
  1553. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1554. strLog += ("响应超时,请检查设备是否离线");
  1555. break;
  1556. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1557. strLog += ("标签名解析错误");
  1558. break;
  1559. case ERROR_NO.ERRR_SCAN_ERROR:
  1560. strLog += ("扫描标签信息失败");
  1561. break;
  1562. default:
  1563. strLog += ("其他错误");
  1564. break;
  1565. }
  1566. strLog += "\n";
  1567. return (-10, strLog);
  1568. }
  1569. else
  1570. {
  1571. for (int i = 0; i < nNumOfTags; i++)
  1572. {
  1573. strType += "\n标签名:" + pTaglist[i].pName + " 类型:";
  1574. switch (pTagsValue[i].pType)
  1575. {
  1576. case TAG_TYPE.TAG_TYPE_BOOL:
  1577. strType += "BOOL";
  1578. break;
  1579. case TAG_TYPE.TAG_TYPE_SINT:
  1580. strType += "SINT";
  1581. break;
  1582. case TAG_TYPE.TAG_TYPE_INT:
  1583. strType += "INT";
  1584. break;
  1585. case TAG_TYPE.TAG_TYPE_DINT:
  1586. strType += "DINT";
  1587. break;
  1588. case TAG_TYPE.TAG_TYPE_LINT:
  1589. strType += "LINT";
  1590. break;
  1591. case TAG_TYPE.TAG_TYPE_USINT:
  1592. strType += "USINT";
  1593. break;
  1594. case TAG_TYPE.TAG_TYPE_UINT:
  1595. strType += "UINT";
  1596. break;
  1597. case TAG_TYPE.TAG_TYPE_UDINT:
  1598. strType += "UDINT";
  1599. break;
  1600. case TAG_TYPE.TAG_TYPE_ULINT:
  1601. strType += "ULINT";
  1602. break;
  1603. case TAG_TYPE.TAG_TYPE_REAL:
  1604. strType += "REAL";
  1605. break;
  1606. case TAG_TYPE.TAG_TYPE_LREAL:
  1607. strType += "LREAL";
  1608. break;
  1609. case TAG_TYPE.TAG_TYPE_STRING:
  1610. strType += "STRING";
  1611. break;
  1612. case TAG_TYPE.TAG_TYPE_BYTE:
  1613. strType += "BYTE";
  1614. break;
  1615. case TAG_TYPE.TAG_TYPE_WORD:
  1616. strType += "WORD";
  1617. break;
  1618. case TAG_TYPE.TAG_TYPE_DWORD:
  1619. strType += "DWORD";
  1620. break;
  1621. case TAG_TYPE.TAG_TYPE_LWORD:
  1622. strType += "LWORD";
  1623. break;
  1624. case TAG_TYPE.TAG_TYPE_STRUCT:
  1625. strType += "STRUCT";
  1626. break;
  1627. case TAG_TYPE.TAG_TYPE_ARRAY:
  1628. strType += "ARRAY";
  1629. break;
  1630. default:
  1631. strType += pTagsValue[i].pType.ToString();
  1632. break;
  1633. }
  1634. strType += " 元素个数:" + pTaglist[i].nElementCount.ToString();
  1635. strType += " 数据长度:" + pTagsValue[i].nDataLength.ToString() + "\n";
  1636. unsafe
  1637. {
  1638. byte* memBytePtr = (byte*)pTagsValue[i].pData.ToPointer();
  1639. pBuf[i] = new byte[pTagsValue[i].nDataLength];
  1640. for (int j = 0; j < pTagsValue[i].nDataLength; j++)
  1641. {
  1642. pBuf[i][j] = memBytePtr[j];
  1643. //string str = "";
  1644. ///str += j.ToString() + ": ";
  1645. //str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";
  1646. }
  1647. }
  1648. }
  1649. }
  1650. DeleteTagListStru(ref pTagsValue[0], nNumOfTags); //调用接口释放内存
  1651. return (0, strType);
  1652. }
  1653. }
  1654. /// <summary>
  1655. /// 一次写多个标签
  1656. /// </summary>
  1657. /// <param name="TagList">将写入的标签列表</param>
  1658. /// <param name="ObjList">与标签列表对应的值对象</param>
  1659. /// <returns></returns>
  1660. public (int, string) Write_Tags(List<StructTag> TagList, List<Object> ObjList)
  1661. {
  1662. int size = 0;
  1663. byte[] pBuf = null;
  1664. int nRet = 0;
  1665. string strRet = "";
  1666. if (!m_bConnected) return (-1, "未连接");
  1667. if (m_nInstanceId <= 0) return (-2, "实例ID需大于0");
  1668. if (ObjList.Count != TagList.Count) return (-3, "标签列表和数据列表不一致");
  1669. int nLen = TagList.Count;
  1670. int nNumOfTags = TagList.Count;
  1671. tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[nNumOfTags];
  1672. try
  1673. {
  1674. for (int i = 0; i < nLen; i++)
  1675. {
  1676. if (TagList[i].strTagName.Length > 255) return (-4, "标签名称长度超过255字节");
  1677. if (TagList[i].tTagType == null) return (-5, "标签类型不能空");
  1678. //标签属性
  1679. pTaglist[i].pName = TagList[i].strTagName;
  1680. pTaglist[i].nElementCount = TagList[i].nCount;
  1681. pTaglist[i].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;
  1682. pTaglist[i].pData = Marshal.AllocHGlobal(1400);
  1683. //标签写入的数据
  1684. size = 0;
  1685. string str = TagList[i].tTagType.Name;
  1686. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  1687. bool containsAny = substrings.Any(substring => str.Contains(substring));
  1688. if (containsAny)
  1689. {
  1690. Type type = ObjList[i].GetType();
  1691. if (str != type.Name) return (120, "变量类型不一致");
  1692. }
  1693. if (str == "String")
  1694. {
  1695. string data = ObjList[i] as string;
  1696. pBuf = System.Text.Encoding.Default.GetBytes(data);
  1697. size = pBuf.Length;
  1698. if (size > 1400)
  1699. {
  1700. return (110, "数据长度超过1400字节,请重新输入");
  1701. }
  1702. }
  1703. else
  1704. {
  1705. if (TagList[i].tTagType.Name == "Boolean")
  1706. {
  1707. pBuf = new byte[1];
  1708. Type targetType = TagList[i].tTagType;
  1709. if ((bool)Convert.ChangeType(ObjList[i], targetType))
  1710. {
  1711. pBuf[0] = 1;
  1712. }
  1713. else
  1714. {
  1715. pBuf[0] = 0;
  1716. }
  1717. size = 1;
  1718. }
  1719. else
  1720. {
  1721. size = Marshal.SizeOf(TagList[i].tTagType);
  1722. pBuf = StructToBytes(ObjList[i], size);
  1723. }
  1724. }
  1725. //填充数据
  1726. for (int j = 0; j < size; j++)
  1727. {
  1728. Marshal.WriteByte(pTaglist[i].pData + j * sizeof(byte), pBuf[j]);
  1729. }
  1730. pTaglist[i].nDataLength = size;
  1731. }
  1732. ERROR_NO errorNo = ERROR_NO.SUCCESS;
  1733. lock (m_objLock)
  1734. {
  1735. //errorNo = EipWriteTagList(m_nInstanceId, nNumOfTags, pTaglist);
  1736. errorNo = EipWriteTagListExt(m_nInstanceId, nNumOfTags, pTaglist, true);
  1737. //errorNo = EipWriteTagListRaw(m_nInstanceId, nNumOfTags, pTaglist);
  1738. }
  1739. string strLog = "";
  1740. strLog += "\n写入请求";
  1741. if (errorNo != ERROR_NO.SUCCESS)
  1742. {
  1743. strLog += " 失败 标签个数:" + nNumOfTags.ToString() + " 实例ID:" + m_nInstanceId.ToString() + " ";
  1744. switch (errorNo)
  1745. {
  1746. case ERROR_NO.ERR_EIP_STOPED:
  1747. strLog += ("协议栈未开启");
  1748. break;
  1749. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  1750. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  1751. break;
  1752. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1753. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  1754. break;
  1755. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  1756. strLog += ("达到最大连接数量");
  1757. break;
  1758. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  1759. strLog += ("内存溢出,缓冲区已满");
  1760. break;
  1761. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  1762. strLog += ("连接的网络地址无效");
  1763. break;
  1764. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  1765. strLog += ("连接无响应");
  1766. break;
  1767. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  1768. strLog += ("连接响应错误");
  1769. break;
  1770. case ERROR_NO.ERRR_INVALID_DESTINATION:
  1771. strLog += ("目标标签不存在");
  1772. break;
  1773. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  1774. strLog += ("标签名超过255字节");
  1775. break;
  1776. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  1777. strLog += ("请求数据超限");
  1778. break;
  1779. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  1780. strLog += ("响应超时,请检查设备是否离线");
  1781. break;
  1782. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  1783. strLog += ("标签名解析错误");
  1784. break;
  1785. case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:
  1786. strLog += ("写入数据长度与标签实际长度不一致");
  1787. break;
  1788. case ERROR_NO.ERRR_SCAN_ERROR:
  1789. strLog += ("扫描标签信息失败");
  1790. break;
  1791. default:
  1792. strLog += ("其他错误");
  1793. break;
  1794. }
  1795. strLog += "\n";
  1796. strRet = strLog;
  1797. nRet = -10;
  1798. }
  1799. else
  1800. {
  1801. //成功
  1802. strRet = "OK";
  1803. nRet = 0;
  1804. }
  1805. }
  1806. catch (Exception ex)
  1807. {
  1808. nRet = 120;
  1809. strRet = ex.ToString();
  1810. }
  1811. finally
  1812. {
  1813. for (int i = 0; i < nLen; i++)
  1814. {
  1815. if (pTaglist[i].pData != ((IntPtr)0))
  1816. {
  1817. Marshal.FreeHGlobal(pTaglist[i].pData);
  1818. pTaglist[i].pData = (IntPtr)0;
  1819. }
  1820. }
  1821. }
  1822. return (nRet, strRet);
  1823. }
  1824. /// <summary>
  1825. /// 一次读取Bool标签或Bool数组标签
  1826. /// </summary>
  1827. /// <param name="strTagName">标签的名称</param>
  1828. /// <param name="nCount">读取的标签个数</param>
  1829. /// <param name="boolBuf">相应标签的返回值</param>
  1830. /// <returns>函数返回结果</returns>
  1831. public (int, string) Read_Bool_Tag(string strTagName, int nCount, out bool[] boolBuf)
  1832. {
  1833. byte[] pBuf = null;
  1834. boolBuf = null;
  1835. int nRet = 0;
  1836. string strRet = "";
  1837. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1838. if (nRet != 0) return (nRet, strRet);
  1839. return Parse_Bool_Tag(pBuf, out boolBuf);
  1840. }
  1841. /// <summary>
  1842. /// 一次写入Bool标签或Bool数组标签
  1843. /// </summary>
  1844. /// <param name="strTagName">标签的名称</param>
  1845. /// <param name="nCount">标签个数</param>
  1846. /// <param name="boolBuf">相应标签的写入值</param>
  1847. /// <returns>函数返回结果</returns>
  1848. public (int, string) Write_Bool_Tag(string strTagName, int nCount, bool[] boolBuf)
  1849. {
  1850. byte[] pBuf = null;
  1851. int nRet = 0;
  1852. string strRet = "";
  1853. pBuf = BoolToBytes(boolBuf);
  1854. if (pBuf == null) return (1, "缓存区空");
  1855. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1856. return (nRet, strRet);
  1857. }
  1858. //将转换为Byte数组
  1859. public static byte[] BoolToBytes(bool[] boolBuf)
  1860. {
  1861. if (boolBuf==null) return null;
  1862. int nNum = 0;
  1863. nNum = boolBuf.Length;
  1864. if (nNum < 1) return null;
  1865. byte[] bytes = new byte[nNum];
  1866. for (int i = 0; i < nNum; i++)
  1867. {
  1868. if (boolBuf[i])
  1869. bytes[i] = 1;
  1870. else
  1871. bytes[i] = 0;
  1872. }
  1873. return bytes;
  1874. }
  1875. public (int, string) Parse_Bool_Tag(byte[] pBuf, out bool[] boolBuf)
  1876. {
  1877. boolBuf = null;
  1878. int nNum = 0;
  1879. nNum = pBuf.Length;
  1880. if (nNum < 1) return (1, "Parse Failed");
  1881. boolBuf = new bool[nNum];
  1882. for (int i = 0; i < nNum; i++)
  1883. {
  1884. byte[] databuf = new byte[1] {0};
  1885. databuf[0] = pBuf[i];
  1886. bool iTemp = BitConverter.ToBoolean(databuf, 0);
  1887. boolBuf[i] = iTemp;
  1888. }
  1889. return (0, "OK");
  1890. }
  1891. public (int, string) Read_Byte_Tag(string strTagName, int nCount, out byte[] pBuf)
  1892. {
  1893. return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1894. }
  1895. public (int, string) Write_Byte_Tag(string strTagName, int nCount, byte[] pBuf)
  1896. {
  1897. return Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1898. }
  1899. public (int, string) Read_SInt_Tag(string strTagName, int nCount, out sbyte[] sintBuf)
  1900. {
  1901. byte[] pBuf = null;
  1902. sintBuf = null;
  1903. int nRet = 0;
  1904. string strRet = "";
  1905. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1906. if (nRet != 0) return (nRet, strRet);
  1907. return Parse_SInt_Tag(pBuf, out sintBuf);
  1908. }
  1909. public (int, string) Write_SInt_Tag(string strTagName, int nCount, sbyte[] DataBuf)
  1910. {
  1911. byte[] pBuf = null;
  1912. int nRet = 0;
  1913. string strRet = "";
  1914. pBuf = SByteToBytes(DataBuf);
  1915. if (pBuf == null) return (1, "pBuf is Null");
  1916. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1917. return (nRet, strRet);
  1918. }
  1919. //将转换为Byte数组
  1920. public static byte[] SByteToBytes(sbyte[] DataBuf)
  1921. {
  1922. if (DataBuf == null || DataBuf.Length <= 0) return null;
  1923. int nNum = 0;
  1924. nNum = DataBuf.Length;
  1925. if (nNum < 1) return null;
  1926. byte[] bytes = new byte[nNum];
  1927. for (int i = 0; i < nNum; i++)
  1928. {
  1929. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  1930. bytes[i] = databuf[0];
  1931. }
  1932. return bytes;
  1933. }
  1934. public (int, string) Parse_SInt_Tag(byte[] pBuf, out sbyte[] sintBuf)
  1935. {
  1936. sintBuf = null;
  1937. int nNum = 0;
  1938. nNum = pBuf.Length;
  1939. if (nNum < 1) return (1, "Parse Failed");
  1940. sintBuf = new sbyte[nNum];
  1941. for (int i = 0; i < nNum; i++)
  1942. {
  1943. sintBuf[i] = (sbyte)pBuf[i];
  1944. }
  1945. return (0, "OK");
  1946. }
  1947. public (int, string) Read_String_Tag(string strTagName, int nCount, out string strBuf)
  1948. {
  1949. int nRet=0;
  1950. string strRet = "";
  1951. byte[] pBuf = null;
  1952. strBuf = "";
  1953. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  1954. if (nRet == 0)
  1955. strBuf = System.Text.Encoding.UTF8.GetString(pBuf);
  1956. return (nRet, strRet);
  1957. }
  1958. public (int, string) Write_String_Tag(string strTagName, int nCount, string strBuf)
  1959. {
  1960. int nRet = 0;
  1961. string strRet = "";
  1962. byte[] pBuf = null;
  1963. if (string.IsNullOrEmpty(strBuf)) return (1, "string is null");
  1964. pBuf = System.Text.Encoding.UTF8.GetBytes(strBuf);
  1965. if (pBuf == null || pBuf.Length == 0 ) return (2, "pBuf is null");
  1966. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  1967. return (nRet, strRet);
  1968. }
  1969. public (int, string) Parse_String_Tag(byte[] pBuf, out string strBuf)
  1970. {
  1971. int nRet = 0;
  1972. string strRet = "";
  1973. strBuf = "";
  1974. strBuf = System.Text.Encoding.UTF8.GetString(pBuf);
  1975. return (nRet, strRet);
  1976. }
  1977. public (int, string) Read_Word_Tag(string strTagName, int nCount, out ushort[] wordBuf)
  1978. {
  1979. return Read_UInt_Tag(strTagName, nCount, out wordBuf);
  1980. }
  1981. public (int, string) Write_Word_Tag(string strTagName, int nCount, ushort[] wordBuf)
  1982. {
  1983. return Write_UInt_Tag(strTagName, nCount, wordBuf);
  1984. }
  1985. public (int, string) Read_DWord_Tag(string strTagName, int nCount, out uint[] dwordBuf)
  1986. {
  1987. return Read_UDInt_Tag(strTagName, nCount, out dwordBuf);
  1988. }
  1989. public (int, string) Write_DWord_Tag(string strTagName, int nCount, uint[] dwordBuf)
  1990. {
  1991. return Write_UDInt_Tag(strTagName, nCount, dwordBuf);
  1992. }
  1993. public (int, string) Read_LWord_Tag(string strTagName, int nCount, out ulong[] lwordBuf)
  1994. {
  1995. return Read_ULInt_Tag(strTagName, nCount, out lwordBuf);
  1996. }
  1997. public (int, string) Write_LWord_Tag(string strTagName, int nCount, ulong[] lwordBuf)
  1998. {
  1999. return Write_ULInt_Tag(strTagName, nCount, lwordBuf);
  2000. }
  2001. /// <summary>
  2002. /// read 16bit int
  2003. /// </summary>
  2004. /// <param name="strTagName"></param>
  2005. /// <param name="nCount"></param>
  2006. /// <param name="intBuf"></param>
  2007. /// <returns></returns>
  2008. public (int, string) Read_Int_Tag(string strTagName, int nCount, out short[] intBuf)
  2009. {
  2010. byte[] pBuf = null;
  2011. intBuf = null;
  2012. int nRet=0;
  2013. string strRet = "";
  2014. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2015. if (nRet != 0) return (nRet, strRet);
  2016. return Parse_Int_Tag(pBuf, out intBuf);
  2017. }
  2018. public (int, string) Parse_Int_Tag(byte[] pBuf, out short[] intBuf)
  2019. {
  2020. intBuf = null;
  2021. int nNum = 0;
  2022. nNum = pBuf.Length / 2;
  2023. if (nNum < 1) return (1, "Parse Failed");
  2024. intBuf = new short[nNum];
  2025. for (int i = 0; i < nNum; i++)
  2026. {
  2027. byte[] databuf = new byte[2] { 0, 0 };
  2028. databuf[0] = pBuf[i * 2];
  2029. databuf[1] = pBuf[i * 2 + 1];
  2030. short iTemp = BitConverter.ToInt16(databuf, 0);
  2031. intBuf[i] = iTemp;
  2032. }
  2033. return (0, "OK");
  2034. }
  2035. public (int, string) Write_Int_Tag(string strTagName, int nCount, short[] DataBuf)
  2036. {
  2037. byte[] pBuf = null;
  2038. int nRet = 0;
  2039. string strRet = "";
  2040. pBuf = ShortToBytes(DataBuf);
  2041. if (pBuf == null ) return (1, "pBuf is Null");
  2042. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2043. return (nRet, strRet);
  2044. }
  2045. //将转换为Byte数组
  2046. public static byte[] ShortToBytes(short[] DataBuf)
  2047. {
  2048. if (DataBuf == null || DataBuf.Length<=0) return null;
  2049. int nNum = 0;
  2050. //int size = Marshal.SizeOf(typeof(short));
  2051. //int size = sizeof(short);
  2052. nNum = DataBuf.Length;
  2053. if (nNum < 1) return null;
  2054. byte[] bytes = new byte[nNum*2];
  2055. for (int i = 0; i < nNum; i++)
  2056. {
  2057. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2058. bytes[i * 2] = databuf[0];
  2059. bytes[i * 2 + 1] = databuf[1];
  2060. }
  2061. return bytes;
  2062. }
  2063. /// <summary>
  2064. /// 16bit uint
  2065. /// </summary>
  2066. /// <param name="strTagName"></param>
  2067. /// <param name="nCount"></param>
  2068. /// <param name="uintBuf"></param>
  2069. /// <returns></returns>
  2070. public (int, string) Read_UInt_Tag(string strTagName, int nCount, out UInt16[] uintBuf)
  2071. {
  2072. byte[] pBuf = null;
  2073. uintBuf = null;
  2074. int nRet = 0;
  2075. string strRet = "";
  2076. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2077. if (nRet != 0) return (nRet, strRet);
  2078. return Parse_UInt_Tag(pBuf, out uintBuf);
  2079. }
  2080. public (int, string) Write_UInt_Tag(string strTagName, int nCount, ushort[] DataBuf)
  2081. {
  2082. byte[] pBuf = null;
  2083. int nRet = 0;
  2084. string strRet = "";
  2085. pBuf = UShortToBytes(DataBuf);
  2086. if (pBuf == null) return (1, "pBuf is Null");
  2087. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2088. return (nRet, strRet);
  2089. }
  2090. //将转换为Byte数组
  2091. public static byte[] UShortToBytes(ushort[] DataBuf)
  2092. {
  2093. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2094. int nNum = 0;
  2095. //int size = Marshal.SizeOf(typeof(short));
  2096. //int size = sizeof(short);
  2097. nNum = DataBuf.Length;
  2098. if (nNum < 1) return null;
  2099. byte[] bytes = new byte[nNum*2];
  2100. for (int i = 0; i < nNum; i++)
  2101. {
  2102. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2103. bytes[i * 2] = databuf[0];
  2104. bytes[i * 2 + 1] = databuf[1];
  2105. }
  2106. return bytes;
  2107. }
  2108. public (int, string) Parse_UInt_Tag(byte[] pBuf, out UInt16[] uintBuf)
  2109. {
  2110. uintBuf = null;
  2111. int nNum = 0;
  2112. nNum = pBuf.Length / 2;
  2113. if (nNum < 1) return (1, "Parse Failed");
  2114. uintBuf = new UInt16[nNum];
  2115. for (int i = 0; i < nNum; i++)
  2116. {
  2117. byte[] databuf = new byte[2] { 0, 0 };
  2118. databuf[0] = pBuf[i * 2];
  2119. databuf[1] = pBuf[i * 2 + 1];
  2120. UInt16 iTemp = BitConverter.ToUInt16(databuf, 0);
  2121. uintBuf[i] = iTemp;
  2122. }
  2123. return (0, "OK");
  2124. }
  2125. /// <summary>
  2126. /// 32bits int
  2127. /// </summary>
  2128. /// <param name="strTagName"></param>
  2129. /// <param name="nCount"></param>
  2130. /// <param name="intBuf"></param>
  2131. /// <returns></returns>
  2132. public (int, string) Read_DInt_Tag(string strTagName, int nCount, out int[] intBuf)
  2133. {
  2134. byte[] pBuf = null;
  2135. intBuf = null;
  2136. int nRet = 0;
  2137. string strRet = "";
  2138. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2139. if (nRet != 0) return (nRet, strRet);
  2140. return Parse_DInt_Tag(pBuf, out intBuf);
  2141. }
  2142. public (int, string) Write_DInt_Tag(string strTagName, int nCount, int[] DataBuf)
  2143. {
  2144. byte[] pBuf = null;
  2145. int nRet = 0;
  2146. string strRet = "";
  2147. pBuf = DIntToBytes(DataBuf);
  2148. if (pBuf == null) return (1, "pBuf is Null");
  2149. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2150. return (nRet, strRet);
  2151. }
  2152. //将转换为Byte数组
  2153. public static byte[] DIntToBytes(int[] DataBuf)
  2154. {
  2155. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2156. int nNum = 0;
  2157. nNum = DataBuf.Length;
  2158. if (nNum < 1) return null;
  2159. byte[] bytes = new byte[nNum*4];
  2160. for (int i = 0; i < nNum; i++)
  2161. {
  2162. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2163. bytes[i * 4] = databuf[0];
  2164. bytes[i * 4 + 1] = databuf[1];
  2165. bytes[i * 4 + 2] = databuf[2];
  2166. bytes[i * 4 + 3] = databuf[3];
  2167. }
  2168. return bytes;
  2169. }
  2170. public (int, string) Parse_DInt_Tag(byte[] pBuf, out int[] intBuf)
  2171. {
  2172. intBuf = null;
  2173. int nNum = 0;
  2174. nNum = pBuf.Length / 4;
  2175. if (nNum < 1) return (1, "Parse Failed");
  2176. intBuf = new int[nNum];
  2177. for (int i = 0; i < nNum; i++)
  2178. {
  2179. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2180. databuf[0] = pBuf[i * 4];
  2181. databuf[1] = pBuf[i * 4 + 1];
  2182. databuf[2] = pBuf[i * 4 + 2];
  2183. databuf[3] = pBuf[i * 4 + 3];
  2184. int iTemp = BitConverter.ToInt32(databuf, 0);
  2185. intBuf[i] = iTemp;
  2186. }
  2187. return (0, "OK");
  2188. }
  2189. /// <summary>
  2190. /// 无符号32位整数
  2191. /// </summary>
  2192. /// <param name="strTagName"></param>
  2193. /// <param name="nCount"></param>
  2194. /// <param name="intBuf"></param>
  2195. /// <returns></returns>
  2196. public (int, string) Read_UDInt_Tag(string strTagName, int nCount, out uint[] uintBuf)
  2197. {
  2198. byte[] pBuf = null;
  2199. uintBuf = null;
  2200. int nRet = 0;
  2201. string strRet = "";
  2202. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2203. if (nRet != 0) return (nRet, strRet);
  2204. return Parse_UDInt_Tag(pBuf, out uintBuf);
  2205. }
  2206. public (int, string) Write_UDInt_Tag(string strTagName, int nCount, uint[] DataBuf)
  2207. {
  2208. byte[] pBuf = null;
  2209. int nRet = 0;
  2210. string strRet = "";
  2211. pBuf = UDIntToBytes(DataBuf);
  2212. if (pBuf == null) return (1, "pBuf is Null");
  2213. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2214. return (nRet, strRet);
  2215. }
  2216. //将转换为Byte数组
  2217. public static byte[] UDIntToBytes(uint[] DataBuf)
  2218. {
  2219. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2220. int nNum = 0;
  2221. nNum = DataBuf.Length;
  2222. if (nNum < 1) return null;
  2223. byte[] bytes = new byte[nNum * 4];
  2224. for (int i = 0; i < nNum; i++)
  2225. {
  2226. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2227. bytes[i * 4] = databuf[0];
  2228. bytes[i * 4 + 1] = databuf[1];
  2229. bytes[i * 4 + 2] = databuf[2];
  2230. bytes[i * 4 + 3] = databuf[3];
  2231. }
  2232. return bytes;
  2233. }
  2234. public (int, string) Parse_UDInt_Tag(byte[] pBuf, out uint[] uintBuf)
  2235. {
  2236. uintBuf = null;
  2237. int nNum = 0;
  2238. nNum = pBuf.Length / 4;
  2239. if (nNum < 1) return (1, "Parse Failed");
  2240. uintBuf = new uint[nNum];
  2241. for (int i = 0; i < nNum; i++)
  2242. {
  2243. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2244. databuf[0] = pBuf[i * 4];
  2245. databuf[1] = pBuf[i * 4 + 1];
  2246. databuf[2] = pBuf[i * 4 + 2];
  2247. databuf[3] = pBuf[i * 4 + 3];
  2248. uint iTemp = BitConverter.ToUInt32(databuf, 0);
  2249. uintBuf[i] = iTemp;
  2250. }
  2251. return (0, "OK");
  2252. }
  2253. public (int, string) Read_LInt_Tag(string strTagName, int nCount, out long[] longBuf)
  2254. {
  2255. byte[] pBuf = null;
  2256. longBuf = null;
  2257. int nRet = 0;
  2258. string strRet = "";
  2259. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2260. if (nRet != 0) return (nRet, strRet);
  2261. return Parse_LInt_Tag(pBuf, out longBuf);
  2262. }
  2263. public (int, string) Write_LInt_Tag(string strTagName, int nCount, long[] DataBuf)
  2264. {
  2265. byte[] pBuf = null;
  2266. int nRet = 0;
  2267. string strRet = "";
  2268. pBuf = LIntToBytes(DataBuf);
  2269. if (pBuf == null) return (1, "pBuf is Null");
  2270. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2271. return (nRet, strRet);
  2272. }
  2273. //将转换为Byte数组
  2274. public static byte[] LIntToBytes(long[] DataBuf)
  2275. {
  2276. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2277. int nNum = 0;
  2278. nNum = DataBuf.Length;
  2279. if (nNum < 1) return null;
  2280. byte[] bytes = new byte[nNum * 8];
  2281. for (int i = 0; i < nNum; i++)
  2282. {
  2283. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2284. bytes[i * 4] = databuf[0];
  2285. bytes[i * 4 + 1] = databuf[1];
  2286. bytes[i * 4 + 2] = databuf[2];
  2287. bytes[i * 4 + 3] = databuf[3];
  2288. bytes[i * 4 + 4] = databuf[4];
  2289. bytes[i * 4 + 5] = databuf[5];
  2290. bytes[i * 4 + 6] = databuf[6];
  2291. bytes[i * 4 + 7] = databuf[7];
  2292. }
  2293. return bytes;
  2294. }
  2295. public (int, string) Parse_LInt_Tag(byte[] pBuf, out long[] longBuf)
  2296. {
  2297. longBuf = null;
  2298. int nNum = 0;
  2299. nNum = pBuf.Length / 8;
  2300. if (nNum < 1) return (1, "Parse Failed");
  2301. longBuf = new long[nNum];
  2302. for (int i = 0; i < nNum; i++)
  2303. {
  2304. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2305. databuf[0] = pBuf[i * 4];
  2306. databuf[1] = pBuf[i * 4 + 1];
  2307. databuf[2] = pBuf[i * 4 + 2];
  2308. databuf[3] = pBuf[i * 4 + 3];
  2309. databuf[4] = pBuf[i * 4 + 4];
  2310. databuf[5] = pBuf[i * 4 + 5];
  2311. databuf[6] = pBuf[i * 4 + 6];
  2312. databuf[7] = pBuf[i * 4 + 7];
  2313. long iTemp = BitConverter.ToInt64(databuf, 0);
  2314. longBuf[i] = iTemp;
  2315. }
  2316. return (0, "OK");
  2317. }
  2318. /// <summary>
  2319. /// 无符号64整数
  2320. /// </summary>
  2321. /// <param name="strTagName"></param>
  2322. /// <param name="nCount"></param>
  2323. /// <param name="ulongBuf"></param>
  2324. /// <returns></returns>
  2325. public (int, string) Read_ULInt_Tag(string strTagName, int nCount, out ulong[] ulongBuf)
  2326. {
  2327. byte[] pBuf = null;
  2328. ulongBuf = null;
  2329. int nRet = 0;
  2330. string strRet = "";
  2331. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2332. if (nRet != 0) return (nRet, strRet);
  2333. return Parse_ULInt_Tag(pBuf, out ulongBuf);
  2334. }
  2335. public (int, string) Write_ULInt_Tag(string strTagName, int nCount, ulong[] DataBuf)
  2336. {
  2337. byte[] pBuf = null;
  2338. int nRet = 0;
  2339. string strRet = "";
  2340. pBuf = ULIntToBytes(DataBuf);
  2341. if (pBuf == null) return (1, "pBuf is Null");
  2342. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2343. return (nRet, strRet);
  2344. }
  2345. //将转换为Byte数组
  2346. public static byte[] ULIntToBytes(ulong[] DataBuf)
  2347. {
  2348. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2349. int nNum = 0;
  2350. nNum = DataBuf.Length;
  2351. if (nNum < 1) return null;
  2352. byte[] bytes = new byte[nNum * 8];
  2353. for (int i = 0; i < nNum; i++)
  2354. {
  2355. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2356. bytes[i * 4] = databuf[0];
  2357. bytes[i * 4 + 1] = databuf[1];
  2358. bytes[i * 4 + 2] = databuf[2];
  2359. bytes[i * 4 + 3] = databuf[3];
  2360. bytes[i * 4 + 4] = databuf[4];
  2361. bytes[i * 4 + 5] = databuf[5];
  2362. bytes[i * 4 + 6] = databuf[6];
  2363. bytes[i * 4 + 7] = databuf[7];
  2364. }
  2365. return bytes;
  2366. }
  2367. public (int, string) Parse_ULInt_Tag(byte[] pBuf, out ulong[] ulongBuf)
  2368. {
  2369. ulongBuf = null;
  2370. int nNum = 0;
  2371. nNum = pBuf.Length / 8;
  2372. if (nNum < 1) return (1, "Parse Failed");
  2373. ulongBuf = new ulong[nNum];
  2374. for (int i = 0; i < nNum; i++)
  2375. {
  2376. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2377. databuf[0] = pBuf[i * 4];
  2378. databuf[1] = pBuf[i * 4 + 1];
  2379. databuf[2] = pBuf[i * 4 + 2];
  2380. databuf[3] = pBuf[i * 4 + 3];
  2381. databuf[4] = pBuf[i * 4 + 4];
  2382. databuf[5] = pBuf[i * 4 + 5];
  2383. databuf[6] = pBuf[i * 4 + 6];
  2384. databuf[7] = pBuf[i * 4 + 7];
  2385. ulong iTemp = BitConverter.ToUInt64(databuf, 0);
  2386. ulongBuf[i] = iTemp;
  2387. }
  2388. return (0, "OK");
  2389. }
  2390. public (int, string) Read_Real_Tag(string strTagName, int nCount, out float[] floatBuf)
  2391. {
  2392. floatBuf = null;
  2393. byte[] pBuf = null;
  2394. int nRet = 0;
  2395. string strRet = "";
  2396. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2397. if (nRet != 0) return (nRet, strRet);
  2398. return Parse_Real_Tag(pBuf, out floatBuf);
  2399. }
  2400. public (int, string) Write_Real_Tag(string strTagName, int nCount, float[] DataBuf)
  2401. {
  2402. byte[] pBuf = null;
  2403. int nRet = 0;
  2404. string strRet = "";
  2405. pBuf = RealToBytes(DataBuf);
  2406. if (pBuf == null) return (1, "pBuf is Null");
  2407. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2408. return (nRet, strRet);
  2409. }
  2410. //将转换为Byte数组
  2411. public static byte[] RealToBytes(float[] DataBuf)
  2412. {
  2413. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2414. int nNum = 0;
  2415. nNum = DataBuf.Length;
  2416. if (nNum < 1) return null;
  2417. byte[] bytes = new byte[nNum * 4];
  2418. for (int i = 0; i < nNum; i++)
  2419. {
  2420. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2421. bytes[i * 4] = databuf[0];
  2422. bytes[i * 4 + 1] = databuf[1];
  2423. bytes[i * 4 + 2] = databuf[2];
  2424. bytes[i * 4 + 3] = databuf[3];
  2425. }
  2426. return bytes;
  2427. }
  2428. public (int, string) Parse_Real_Tag(byte[] pBuf, out float[] floatBuf)
  2429. {
  2430. floatBuf = null;
  2431. int nNum = 0;
  2432. nNum = pBuf.Length / 4;
  2433. floatBuf = new float[nNum];
  2434. if (nNum < 1) return (1, "Parse Failed");
  2435. for (int i = 0; i < nNum; i++)
  2436. {
  2437. byte[] databuf = new byte[4] { 0, 0, 0, 0 };
  2438. databuf[0] = pBuf[i * 4];
  2439. databuf[1] = pBuf[i * 4 + 1];
  2440. databuf[2] = pBuf[i * 4 + 2];
  2441. databuf[3] = pBuf[i * 4 + 3];
  2442. float fTemp = BitConverter.ToSingle(databuf, 0);
  2443. floatBuf[i] = fTemp;
  2444. }
  2445. return (0, "OK");
  2446. }
  2447. public (int, string) Read_LReal_Tag(string strTagName, int nCount, out double[] doubleBuf)
  2448. {
  2449. doubleBuf = null;
  2450. byte[] pBuf = null;
  2451. int nRet = 0;
  2452. string strRet = "";
  2453. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2454. if (nRet != 0) return (nRet, strRet);
  2455. return Parse_LReal_Tag(pBuf, out doubleBuf);
  2456. }
  2457. public (int, string) Write_LReal_Tag(string strTagName, int nCount, double[] DataBuf)
  2458. {
  2459. byte[] pBuf = null;
  2460. int nRet = 0;
  2461. string strRet = "";
  2462. pBuf = LRealToBytes(DataBuf);
  2463. if (pBuf == null) return (1, "pBuf is Null");
  2464. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2465. return (nRet, strRet);
  2466. }
  2467. //将转换为Byte数组
  2468. public static byte[] LRealToBytes(double[] DataBuf)
  2469. {
  2470. if (DataBuf == null || DataBuf.Length <= 0) return null;
  2471. int nNum = 0;
  2472. nNum = DataBuf.Length;
  2473. if (nNum < 1) return null;
  2474. byte[] bytes = new byte[nNum * 8];
  2475. for (int i = 0; i < nNum; i++)
  2476. {
  2477. byte[] databuf = BitConverter.GetBytes(DataBuf[i]);
  2478. bytes[i * 4] = databuf[0];
  2479. bytes[i * 4 + 1] = databuf[1];
  2480. bytes[i * 4 + 2] = databuf[2];
  2481. bytes[i * 4 + 3] = databuf[3];
  2482. bytes[i * 4 + 4] = databuf[4];
  2483. bytes[i * 4 + 5] = databuf[5];
  2484. bytes[i * 4 + 6] = databuf[6];
  2485. bytes[i * 4 + 7] = databuf[7];
  2486. }
  2487. return bytes;
  2488. }
  2489. public (int, string) Parse_LReal_Tag(byte[] pBuf, out double[] doubleBuf)
  2490. {
  2491. doubleBuf = null;
  2492. int nNum = 0;
  2493. nNum = pBuf.Length / 8;
  2494. if (nNum < 1) return (1, "Parse Failed");
  2495. doubleBuf = new double[nNum];
  2496. for (int i = 0; i < nNum; i++)
  2497. {
  2498. byte[] databuf = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
  2499. databuf[0] = pBuf[i * 8];
  2500. databuf[1] = pBuf[i * 8 + 1];
  2501. databuf[2] = pBuf[i * 8 + 2];
  2502. databuf[3] = pBuf[i * 8 + 3];
  2503. databuf[4] = pBuf[i * 8 + 4];
  2504. databuf[5] = pBuf[i * 8 + 5];
  2505. databuf[6] = pBuf[i * 8 + 6];
  2506. databuf[7] = pBuf[i * 8 + 7];
  2507. double dTemp = BitConverter.ToDouble(databuf, 0);
  2508. doubleBuf[i] = dTemp;
  2509. }
  2510. return (0, "OK");
  2511. }
  2512. #region 对象与字节数组转化
  2513. //将结构体类型转换为Byte数组
  2514. public static byte[] StructToBytes(object structObj, int size)
  2515. {
  2516. byte[] bytes = new byte[size];
  2517. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2518. try
  2519. {
  2520. //将结构体拷到分配好的内存空间
  2521. Marshal.StructureToPtr(structObj, structPtr, false);
  2522. //从内存空间拷贝到byte 数组
  2523. Marshal.Copy(structPtr, bytes, 0, size);
  2524. }
  2525. finally
  2526. {
  2527. //释放内存空间
  2528. Marshal.FreeHGlobal(structPtr);
  2529. }
  2530. return bytes;
  2531. }
  2532. //将Byte转换为结构体类型
  2533. public static object ByteToStruct(byte[] bytes, Type type)
  2534. {
  2535. int size = Marshal.SizeOf(type);
  2536. if (type.Name == "Boolean") size = 1;
  2537. if (size > bytes.Length)
  2538. {
  2539. return null;
  2540. }
  2541. //分配结构体内存空间
  2542. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2543. object obj = null;
  2544. try
  2545. {
  2546. //将byte数组拷贝到分配好的内存空间
  2547. Marshal.Copy(bytes, 0, structPtr, size);
  2548. //将内存空间转换为目标结构体
  2549. obj = Marshal.PtrToStructure(structPtr, type);
  2550. }
  2551. finally
  2552. {
  2553. //释放内存空间
  2554. Marshal.FreeHGlobal(structPtr);
  2555. }
  2556. return obj;
  2557. }
  2558. //将Byte转换为结构体类型
  2559. public static Object ByteToStruct2(byte[] bytes, Type type)
  2560. {
  2561. int size = Marshal.SizeOf(type);
  2562. if (type.Name == "Boolean") size = 1;
  2563. if (size > bytes.Length)
  2564. {
  2565. return null;
  2566. }
  2567. //分配结构体内存空间
  2568. IntPtr structPtr = Marshal.AllocHGlobal(size);
  2569. object obj = null;
  2570. try
  2571. {
  2572. //将byte数组拷贝到分配好的内存空间
  2573. Marshal.Copy(bytes, 0, structPtr, size);
  2574. //将内存空间转换为目标结构体
  2575. obj = Marshal.PtrToStructure(structPtr, type);
  2576. }
  2577. finally
  2578. {
  2579. //释放内存空间
  2580. Marshal.FreeHGlobal(structPtr);
  2581. }
  2582. return obj;
  2583. }
  2584. public static T ConvertBytesToStruct<T>(byte[] bytes)
  2585. {
  2586. // 将字节数组转换为结构体
  2587. GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
  2588. T myStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
  2589. handle.Free();
  2590. return myStruct;
  2591. }
  2592. #endregion 对象与字节数组转化
  2593. /// <summary>
  2594. /// 一次读取单个标签
  2595. /// </summary>
  2596. /// <typeparam name="T">需要读取的标签结构</typeparam>
  2597. /// <param name="strTagName">需要读取的标签名</param>
  2598. /// <param name="nCount">读取标签的个数</param>
  2599. /// <param name="outObj">返回相应标签值对象</param>
  2600. /// <returns></returns>
  2601. public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj, Control uiControl)
  2602. {
  2603. // 初始化输出参数
  2604. outObj = default(T);
  2605. byte[] pBuf = null;
  2606. int nRet = 0;
  2607. string strRet = "";
  2608. try
  2609. {
  2610. // 创建一个标志变量,用于判断是否需要显示提示框
  2611. bool isProcessingDialogShown = false;
  2612. // 启动一个后台任务执行核心逻辑
  2613. Task<(int, string)> readTask = Task.Run(() =>
  2614. {
  2615. return Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2616. });
  2617. // 启动一个计时器任务,用于检测是否超过 5 秒
  2618. Task delayTask = Task.Delay(5000);
  2619. // 等待两个任务中的任意一个完成
  2620. Task completedTask = Task.WhenAny(readTask, delayTask).Result;
  2621. if (completedTask == delayTask)
  2622. {
  2623. // 如果超时,则显示提示框
  2624. ShowProcessingDialog(uiControl);
  2625. isProcessingDialogShown = true;
  2626. // 继续等待读取任务完成
  2627. readTask.Wait();
  2628. }
  2629. // 获取读取结果
  2630. (nRet, strRet) = readTask.Result;
  2631. // 检查类型并处理数据
  2632. string str = typeof(T).Name;
  2633. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2634. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2635. if (containsAny)
  2636. {
  2637. if (str != strRet) return (120, "变量类型不一致");
  2638. }
  2639. if (str == "String")
  2640. {
  2641. outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);
  2642. }
  2643. else
  2644. {
  2645. outObj = (T)ByteToStruct(pBuf, typeof(T));
  2646. }
  2647. // 如果显示了提示框,则关闭它
  2648. if (isProcessingDialogShown)
  2649. {
  2650. CloseProcessingDialog(uiControl);
  2651. }
  2652. }
  2653. catch (Exception ex)
  2654. {
  2655. // 异常处理
  2656. return (110, ex.ToString());
  2657. }
  2658. return (nRet, "OK");
  2659. }
  2660. private Form _processingForm;
  2661. private void ShowProcessingDialog(Control uiControl)
  2662. {
  2663. if (uiControl == null)
  2664. {
  2665. throw new ArgumentNullException(nameof(uiControl), "UI 控件不能为空。");
  2666. }
  2667. // 确保在主线程上更新 UI
  2668. if (uiControl.InvokeRequired)
  2669. {
  2670. uiControl.Invoke(new Action(() => ShowProcessingDialog(uiControl)));
  2671. return;
  2672. }
  2673. // 创建并显示提示框
  2674. Form processingForm = new Form
  2675. {
  2676. Text = "请稍候",
  2677. Size = new Size(300, 100),
  2678. StartPosition = FormStartPosition.CenterScreen,
  2679. FormBorderStyle = FormBorderStyle.FixedDialog,
  2680. ControlBox = false,
  2681. TopMost = true
  2682. };
  2683. Label label = new Label
  2684. {
  2685. Text = "正在读取中,请稍后...",
  2686. Dock = DockStyle.Fill,
  2687. TextAlign = ContentAlignment.MiddleCenter
  2688. };
  2689. processingForm.Controls.Add(label);
  2690. processingForm.Show();
  2691. // 保存提示框引用以便后续关闭
  2692. _processingForm = processingForm;
  2693. }
  2694. private void CloseProcessingDialog(Control uiControl)
  2695. {
  2696. if (uiControl == null)
  2697. {
  2698. return;
  2699. }
  2700. // 确保在主线程上更新 UI
  2701. if (uiControl.InvokeRequired)
  2702. {
  2703. uiControl.Invoke(new Action(() => CloseProcessingDialog(uiControl)));
  2704. return;
  2705. }
  2706. // 关闭提示框
  2707. _processingForm?.Close();
  2708. _processingForm = null;
  2709. }
  2710. /*
  2711. public (int, string) Read_SingleTag<T>(string strTagName, int nCount, out T outObj)
  2712. {
  2713. outObj = default(T);
  2714. byte[] pBuf = null;
  2715. int nRet = 0;
  2716. string strRet = "";
  2717. try
  2718. {
  2719. (nRet, strRet) = Read_Tag(strTagPrefix + strTagName, nCount, out pBuf);
  2720. if (nRet != 0) return (nRet, strRet);
  2721. string str = typeof(T).Name;
  2722. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2723. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2724. if (containsAny)
  2725. {
  2726. if (str != strRet) return (120, "变量类型不一致");
  2727. }
  2728. if (str == "String")
  2729. {
  2730. outObj = (T)(object)System.Text.Encoding.UTF8.GetString(pBuf);
  2731. return (0, "OK");
  2732. }
  2733. outObj = (T)ByteToStruct(pBuf, typeof(T));
  2734. }
  2735. catch (Exception ex)
  2736. {
  2737. return (110, ex.ToString());
  2738. }
  2739. return (0, "OK");
  2740. }*/
  2741. public (int, string) Write_SingleTag<T>(string strTagName, int nCount, T inObj)
  2742. {
  2743. byte[] pBuf = null;
  2744. int nRet = 0;
  2745. string strRet = "";
  2746. int size = 0;
  2747. try
  2748. {
  2749. string str = typeof(T).Name;
  2750. string[] substrings = { "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "String" };
  2751. bool containsAny = substrings.Any(substring => str.Contains(substring));
  2752. if (containsAny)
  2753. {
  2754. Type type = inObj.GetType();
  2755. if (str != type.Name) return (120, "变量类型不一致");
  2756. }
  2757. if (str == "String")
  2758. {
  2759. //size = inObj.ToString().Length + 1;
  2760. string wtStr= inObj as string;
  2761. pBuf = System.Text.Encoding.Default.GetBytes(wtStr);
  2762. size = pBuf.Length;
  2763. }
  2764. else
  2765. {
  2766. if (typeof(T).Name == "Boolean")
  2767. {
  2768. //pBuf = new byte[1];
  2769. //Type targetType = typeof(T);
  2770. //if ((bool)Convert.ChangeType(inObj, targetType))
  2771. //{
  2772. // pBuf[0] = 1;
  2773. //}
  2774. //else
  2775. //{
  2776. // pBuf[0] = 0;
  2777. //}
  2778. size = 1;
  2779. }
  2780. else
  2781. {
  2782. size = Marshal.SizeOf(typeof(T));
  2783. }
  2784. pBuf = StructToBytes(inObj, size);
  2785. }
  2786. (nRet, strRet) = Write_Tag(strTagPrefix + strTagName, nCount, pBuf);
  2787. return (nRet, strRet);
  2788. }
  2789. catch (Exception ex)
  2790. {
  2791. return (110, ex.ToString());
  2792. }
  2793. }
  2794. /// <summary>
  2795. /// 一次读取多个标签
  2796. /// </summary>
  2797. /// <param name="stTagList">需要读取的标签列表信息</param>
  2798. /// <param name="outObj">返回的相应标签对象</param>
  2799. /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>
  2800. public (int, string) Read_MultiTags(List<StructTag> stTagList, out List<Object> outObj)
  2801. {
  2802. outObj = new List<Object>();
  2803. byte[][] pBuf = null;
  2804. int nRet = 0;
  2805. string strRet = "";
  2806. int nLen = stTagList.Count;
  2807. List<StructTag> TagList=new List<StructTag>();
  2808. try
  2809. {
  2810. foreach(StructTag tag in stTagList)
  2811. {
  2812. TagList.Add(new StructTag {strTagName= strTagPrefix + tag.strTagName,tTagType=tag.tTagType,nCount=tag.nCount});
  2813. }
  2814. (nRet, strRet) = Read_Tags(TagList, out pBuf);
  2815. if (nRet != 0) return (nRet, strRet);
  2816. for (int i = 0; i < nLen; i++)
  2817. {
  2818. //需要调用的方法
  2819. //MethodInfo mi = typeof(Inovance_EIP).GetMethod("ByteToStruct");
  2820. //该方法的泛型类型Type->typeof(int)
  2821. //MethodInfo miConstructed = mi.MakeGenericMethod(strTagList[i].TagType);
  2822. //var arg = { pBuf[i]};
  2823. //执行调用
  2824. //miConstructed.Invoke(null, args);
  2825. //outObj.Add(Convert.ChangeType(ByteToStruct2(pBuf[i], targetType), targetType));
  2826. Type targetType = TagList[i].tTagType;
  2827. if (targetType != null)
  2828. {
  2829. object obj = ByteToStruct(pBuf[i], targetType);
  2830. //if (obj != null)
  2831. outObj.Add(obj);
  2832. }
  2833. }
  2834. }
  2835. catch (Exception ex)
  2836. {
  2837. return (110, ex.ToString());
  2838. }
  2839. return (0, "OK");
  2840. }
  2841. /// <summary>
  2842. /// 一次写多个标签
  2843. /// </summary>
  2844. /// <param name="stTagList">需要写入的标签列表信息</param>
  2845. /// <param name="ObjList">写入的相应标签对象</param>
  2846. /// <returns>执行是否成功,非0不成功,以及显示相应的失败信息</returns>
  2847. public (int, string) Write_MultiTags(List<StructTag> stTagList, List<Object> ObjList)
  2848. {
  2849. int nRet = 0;
  2850. string strRet = "";
  2851. int nLen = stTagList.Count;
  2852. if (ObjList.Count != nLen) return (10, "标签列表和对象列表长度不一致");
  2853. List<StructTag> TagList = new List<StructTag>();
  2854. try
  2855. {
  2856. foreach (StructTag tag in stTagList)
  2857. {
  2858. TagList.Add(new StructTag { strTagName = strTagPrefix + tag.strTagName, tTagType = tag.tTagType, nCount = tag.nCount });
  2859. }
  2860. (nRet, strRet) = Write_Tags(TagList, ObjList);
  2861. return (nRet, strRet);
  2862. }
  2863. catch (Exception ex)
  2864. {
  2865. return (110, ex.ToString());
  2866. }
  2867. }
  2868. #region 清除标签缓存
  2869. /// <summary>
  2870. /// 清除标签缓存
  2871. /// </summary>
  2872. public void Clear_TagCache()
  2873. {
  2874. ResetTagInfo();
  2875. }
  2876. #endregion 清除标签缓存
  2877. }
  2878. }