You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 line
11 KiB

  1. using ReaderB;
  2. using System.Text;
  3. namespace UHFHelper
  4. {
  5. public class UHFCardHelper
  6. {
  7. /// <summary>
  8. /// 单例模式
  9. /// </summary>
  10. private static UHFCardHelper? Instance { get; set; }
  11. private UHFCardHelper()
  12. {
  13. }
  14. public static UHFCardHelper GetInstance()
  15. {
  16. if (Instance == null)
  17. {
  18. Instance = new UHFCardHelper();
  19. }
  20. return Instance;
  21. }
  22. //当前操作的ComAdr
  23. private byte fComAdr = 0xff;
  24. //返回串口的索引号
  25. private int frmcomportindex;
  26. /// <summary>
  27. /// 打开的COM口号
  28. /// </summary>
  29. public int OpenComNo { get; set; }
  30. //所有执行指令的返回值
  31. private int fCmdRet { get; set; } = 30;
  32. /// <summary>
  33. /// 串口打开标示
  34. /// </summary>
  35. public bool ComOpen { get; set; } = false;
  36. /// <summary>
  37. /// 密码
  38. /// </summary>
  39. private byte[] fPassWord = new byte[4];
  40. /// <summary>
  41. /// 错误码
  42. /// </summary>
  43. private int ferrorcode;
  44. //定义Timer类
  45. private System.Timers.Timer timer;
  46. //定义委托
  47. public delegate void SetControlValue(string value);
  48. private void InitTimer()
  49. {
  50. int interval = 1000;
  51. timer = new System.Timers.Timer(interval);
  52. timer.AutoReset = true;
  53. timer.Enabled = true;
  54. //绑定事件,每隔一秒执行一次此方法
  55. timer.Elapsed += new System.Timers.ElapsedEventHandler(MyMethod);
  56. }
  57. private void MyMethod(object sender, System.Timers.ElapsedEventArgs e)
  58. {
  59. //TODO 持续扫码
  60. }
  61. /// <summary>
  62. /// 打开串口
  63. /// </summary>
  64. /// <returns></returns>
  65. public Resultoutput OpenPort()
  66. {
  67. int port = 0;
  68. int openresult;
  69. fComAdr = Convert.ToByte("FF", 16); // $FF;
  70. try
  71. {
  72. openresult = StaticClassReaderB.AutoOpenComPort(ref port, ref fComAdr, 5, ref frmcomportindex);
  73. OpenComNo = frmcomportindex;
  74. if (openresult == 0)
  75. {
  76. ComOpen = true;
  77. //自动执行读取写卡器信息
  78. byte[] TrType = new byte[2];
  79. byte[] VersionInfo = new byte[2];
  80. byte ReaderType = 0;
  81. byte ScanTime = 0;
  82. byte dmaxfre = 0;
  83. byte dminfre = 0;
  84. byte powerdBm = 0;
  85. fCmdRet = StaticClassReaderB.GetReaderInformation(ref fComAdr, VersionInfo, ref ReaderType, TrType, ref dmaxfre, ref dminfre, ref powerdBm, ref ScanTime, frmcomportindex);
  86. if ((fCmdRet == 0x35) | (fCmdRet == 0x30))
  87. {
  88. StaticClassReaderB.CloseSpecComPort(frmcomportindex);
  89. ComOpen = false;
  90. return new Resultoutput { Res=false,ResMes= "串口通讯错误" };
  91. }
  92. if ((OpenComNo == -1) && (openresult == 0x30))
  93. {
  94. return new Resultoutput { Res = false, ResMes = "串口通讯错误" };
  95. }
  96. }
  97. }
  98. catch(Exception ex) {
  99. return new Resultoutput { Res = false, ResMes = ex.ToString() };
  100. }
  101. ComOpen = true;
  102. //var result = WorkMode();
  103. //if (!result.Res)
  104. //{
  105. // return result;
  106. //}
  107. return new Resultoutput { Res = true, ResMes = "串口打开成功" };
  108. }
  109. /// <summary>
  110. /// 关闭串口
  111. /// </summary>
  112. /// <returns></returns>
  113. public Resultoutput ClosePort()
  114. {
  115. fCmdRet = StaticClassReaderB.CloseSpecComPort(OpenComNo);
  116. if (fCmdRet == 0)
  117. {
  118. ComOpen = false;
  119. }
  120. else
  121. {
  122. return new Resultoutput { Res = false, ResMes = "串口关闭失败" };
  123. }
  124. return new Resultoutput { Res = true, ResMes = "串口关闭成功" };
  125. }
  126. /// <summary>
  127. /// 设置工作模式
  128. /// </summary>
  129. public Resultoutput WorkMode()
  130. {
  131. byte[] Parameter = new byte[6];
  132. //应答模式
  133. Parameter[0] = Convert.ToByte(0);
  134. //工作模式 EPCC1 ISO18000-6B
  135. int Reader_bit0 = 0;
  136. //输出模式
  137. int Reader_bit1 = 0;
  138. //蜂鸣开关
  139. int Reader_bit2 = 1;
  140. //起始地址
  141. int Reader_bit3 = 0;
  142. //是否SYRIS485输出
  143. int Reader_bit4 = 0;
  144. Parameter[1] = Convert.ToByte(Reader_bit0 * 1 + Reader_bit1 * 2 + Reader_bit2 * 4 + Reader_bit3 * 8 + Reader_bit4 * 16);
  145. //存储区 EPC区
  146. Parameter[2] = 1;
  147. //起始字地址(Hex)
  148. Parameter[3] = Convert.ToByte("02", 16);
  149. //读取字数
  150. Parameter[4] = Convert.ToByte(1);
  151. //单张标签过滤时间
  152. Parameter[5] = Convert.ToByte(0);
  153. //设置工作模式
  154. fCmdRet = StaticClassReaderB.SetWorkMode(ref fComAdr, Parameter, frmcomportindex);
  155. if (fCmdRet == 0)
  156. {
  157. return new Resultoutput { Res = true, ResMes = "工作模式设置成功" };
  158. }
  159. return new Resultoutput { Res = false, ResMes = "读卡失败" };
  160. }
  161. /// <summary>
  162. /// 读卡
  163. /// </summary>
  164. /// <returns></returns>
  165. public string ReadCard()
  166. {
  167. int CardNum = 0;
  168. int Totallen = 0;
  169. int EPClen, m;
  170. byte[] EPC = new byte[5000];
  171. string temps;
  172. string sEPC;
  173. //fIsInventoryScan = true;
  174. byte AdrTID = 0;
  175. byte LenTID = 0;
  176. byte TIDFlag = 0;
  177. AdrTID = 0;
  178. LenTID = 0;
  179. TIDFlag = 0;
  180. fCmdRet = StaticClassReaderB.Inventory_G2(ref fComAdr, AdrTID, LenTID, TIDFlag, EPC, ref Totallen, ref CardNum, frmcomportindex);
  181. if ((fCmdRet == 1) | (fCmdRet == 2) | (fCmdRet == 3) | (fCmdRet == 4) | (fCmdRet == 0xFB))//代表已查找结束,
  182. {
  183. byte[] daw = new byte[Totallen];
  184. Array.Copy(EPC, daw, Totallen);
  185. temps = ByteArrayToHexString(daw);
  186. m = 0;
  187. if (CardNum == 0)
  188. {
  189. return "";
  190. }
  191. for (int CardIndex = 0; CardIndex < CardNum; CardIndex++)
  192. {
  193. EPClen = daw[m];
  194. sEPC = temps.Substring(m * 2 + 2, EPClen * 2);
  195. m = m + EPClen + 1;
  196. if (sEPC.Length != EPClen * 2)
  197. {
  198. return "";
  199. }
  200. string cardcode = sEPC.Substring(1, sEPC.Length-1);
  201. return cardcode;
  202. }
  203. }
  204. return "";
  205. }
  206. /// <summary>
  207. /// 写卡
  208. /// </summary>
  209. /// <returns></returns>
  210. public Resultoutput WriteCard(string CardCodeStr)
  211. {
  212. byte[] WriteEPC = new byte[100];
  213. byte WriteEPClen;
  214. byte ENum;
  215. string AccessCode = "00000000";
  216. try
  217. {
  218. string CardCode = CardCodeStr;
  219. if ((CardCode.Length % 4) != 0)
  220. {
  221. CardCode = "0" + CardCodeStr;
  222. }
  223. WriteEPClen = Convert.ToByte(CardCode.Length / 2);
  224. ENum = Convert.ToByte(CardCode.Length / 4);
  225. byte[] EPC = new byte[ENum];
  226. EPC = HexStringToByteArray(CardCode);
  227. fPassWord = HexStringToByteArray(AccessCode);
  228. fCmdRet = StaticClassReaderB.WriteEPC_G2(ref fComAdr, fPassWord, EPC, WriteEPClen, ref ferrorcode, frmcomportindex);
  229. if (fCmdRet == 0)
  230. {
  231. return new Resultoutput { Res = true, ResMes = "写卡成功!" };
  232. }
  233. else
  234. {
  235. return new Resultoutput { Res = false, ResMes = "写卡失败!错误码:" + ferrorcode };
  236. }
  237. }
  238. catch (Exception ex)
  239. {
  240. return new Resultoutput { Res = false, ResMes = "写卡失败"+ ex.Message };
  241. }
  242. }
  243. /// <summary>
  244. /// 解析数据
  245. /// </summary>
  246. /// <param name="s"></param>
  247. /// <returns></returns>
  248. private byte[] HexStringToByteArray(string s)
  249. {
  250. s = s.Replace(" ", "");
  251. byte[] buffer = new byte[s.Length / 2];
  252. for (int i = 0; i < s.Length; i += 2)
  253. buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
  254. return buffer;
  255. }
  256. /// <summary>
  257. /// 解析数据
  258. /// </summary>
  259. /// <param name="data"></param>
  260. /// <returns></returns>
  261. private string ByteArrayToHexString(byte[] data)
  262. {
  263. StringBuilder sb = new(data.Length * 3);
  264. foreach (byte b in data)
  265. sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
  266. return sb.ToString().ToUpper();
  267. }
  268. /// <summary>
  269. /// 字符串转16进制
  270. /// </summary>
  271. /// <param name="strEncode"></param>
  272. /// <returns></returns>
  273. public string ToEncode16(string strEncode)
  274. {
  275. byte[] b = Encoding.UTF8.GetBytes(strEncode);//按照指定编码将string编程字节数组
  276. string result = string.Empty;
  277. for (int i = 0; i < b.Length; i++)//逐字节变为16进制字符
  278. {
  279. result += Convert.ToString(b[i], 16);
  280. }
  281. return result;
  282. }
  283. /// <summary>
  284. /// 16进制转字符串
  285. /// </summary>
  286. /// <param name="strEncode"></param>
  287. /// <returns></returns>
  288. public string ToEncodeString(string strDecode)
  289. {
  290. string strTemp = "";
  291. byte[] b = new byte[strDecode.Length / 2];
  292. for (int i = 0; i < strDecode.Length / 2; i++)
  293. {
  294. strTemp = strDecode.Substring(i * 2, 2);
  295. b[i] = Convert.ToByte(strTemp, 16);
  296. }
  297. //按照指定编码将字节数组变为字符串
  298. return Encoding.UTF8.GetString(b);
  299. }
  300. }
  301. }