BroadcastModule.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace BroadcastModule
  10. {
  11. public class BroadcastBoard
  12. {
  13. private UdpClient DUCP_NetSocket;
  14. private IPAddress DeviceIP;
  15. private IPEndPoint RPoint = null;
  16. private IPEndPoint TPoint = null;
  17. private int volume = 10;
  18. //*********************************************** 动态引用dll ******************************************
  19. //实现协议栈数据输出回调函数
  20. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  21. unsafe delegate byte cbDUCP_DataOutType(byte* Data, int Size);
  22. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  23. extern static void MB_STK_SetOutCallback(cbDUCP_DataOutType cb);
  24. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  25. unsafe extern static sbyte MB_STK_In(byte* Data, int Size);
  26. //回调对象
  27. private cbDUCP_DataOutType cbDuCP_dataout;
  28. //回调函数实现
  29. unsafe byte cbDUCP_DataOut(byte* Data, int Size)
  30. {
  31. sbyte Ret;
  32. byte[] buff = new byte[256];
  33. byte[] RxBuff = new byte[256];
  34. for (int i = 0; i < Size; i++)
  35. {
  36. buff[i] = Data[i];
  37. }
  38. /*发送数据到显示屏*/
  39. DUCP_NetSocket.Send(buff, Size, TPoint);
  40. /*接收显示屏回复的数据*/
  41. RxBuff = DUCP_NetSocket.Receive(ref RPoint);
  42. /*将显示屏的回复的数据传输给协议栈*/
  43. unsafe
  44. {
  45. fixed (byte* pArray = RxBuff)
  46. Ret = MB_STK_In(pArray, RxBuff.Length);
  47. }
  48. return (byte)Ret;
  49. }
  50. //调节音量
  51. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  52. unsafe extern static byte DUCP_HOST_SYS_SetVol(int vol);
  53. //播放语音
  54. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  55. unsafe extern static byte DUCP_HOST_TTS_Play(byte* pText, byte Opt);
  56. //停止播放语音
  57. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  58. unsafe extern static byte DUCP_HOST_TTS_Stop();
  59. //重启系统
  60. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  61. unsafe extern static byte DUCP_HOST_SYS_Reset();
  62. //显示已存文件
  63. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  64. unsafe extern static byte DUCP_HOST_TWIN_DisFile(int WinID, int FileID);
  65. //显示文本
  66. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  67. unsafe extern static byte DUCP_HOST_TWIN_DisText(int WinID,
  68. byte* pText,
  69. int EnterMode,
  70. int EnterSpeed,
  71. int DelayMode,
  72. int DelayTime,
  73. int EixtMode,
  74. int EixtSpeed,
  75. int FontIndex,
  76. int TextColor,
  77. int BkColor,
  78. int DisTimes);
  79. //创建文本控件
  80. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  81. extern static byte DUCP_HOST_TWIN_Create(int WinID, int Stile, int x0, int y0, int xSize, int ySize);
  82. //删除文本控件中文本文件
  83. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  84. extern static byte DUCP_HOST_TWIN_DelFile(int WinID, int FileID);
  85. //删除文本控件
  86. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  87. extern static byte DUCP_HOST_TWIN_Del(int WinID);
  88. //删除图片控件
  89. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  90. extern static byte DUCP_HOST_PIC_Del(int WinID);
  91. //设置绘图颜色
  92. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  93. extern static byte DUCP_HOST_2D_SetColor(int Color);
  94. //填充矩形
  95. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  96. extern static byte DUCP_HOST_2D_FillRect(int x0, int y0, int x1, int y1);
  97. //绘制系统自带位图
  98. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  99. extern static byte DUCP_HOST_2D_DrawSysIcon(int x0, int y0, int Num, int Denom, int IconIndex);
  100. //创建图片控件
  101. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  102. extern static byte DUCP_HOST_PIC_Create(int WinID, int x0, int y0, int xSize, int ySize);
  103. //图片控件追加图片
  104. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  105. extern static byte DUCP_HOST_PIC_Add(int WinID, int FID, byte EnterMode, byte EnterSpeed,
  106. byte StopMode, byte StopTime, byte ExitMode, byte ExitSpeed);
  107. //更新本地时间
  108. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  109. extern static byte DUCP_HOST_SYS_UpdateTime(short Year, byte Month, byte Day, byte Week, byte Hour, byte Minute, byte Second);
  110. //更新端口(更新ip方法异常,手动更新)
  111. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  112. unsafe extern static byte DUCP_HOST_SYS_SetPort(int port);
  113. //下载文本文件并与文本控件关联
  114. [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
  115. unsafe extern static byte DUCP_HOST_TWIN_DownTextFile(int WinID,
  116. int FileID,
  117. byte* pText,
  118. int EnterMode,
  119. int EnterSpeed,
  120. int DelayMode,
  121. int DelayTime,
  122. int EixtMode,
  123. int EixtSpeed,
  124. int FontIndex,
  125. int TextColor,
  126. int BkColor);
  127. //************************************************ 方法块 **************************************************
  128. // *************** 私有方法 ***************
  129. /// <summary>
  130. /// 显示特定行文字
  131. /// </summary>
  132. /// <param name="winID"></param>
  133. /// <param name="str"></param>
  134. /// <returns></returns>
  135. private bool DispString(int winID, string str, int time)
  136. {
  137. byte[] buffer = Encoding.Default.GetBytes(str);
  138. if (winID < 0 || winID > 3) { return false; }
  139. unsafe
  140. {
  141. fixed (byte* pArray = buffer)
  142. {
  143. try
  144. {
  145. if (time >= 0 && time <= 255)
  146. {
  147. DUCP_HOST_TWIN_DisText(winID, pArray,
  148. 0X15, 1,
  149. 0X00, time,
  150. 0X15, 1,
  151. 3, 0Xff, 0X00, 0);
  152. }
  153. else
  154. {
  155. DUCP_HOST_TWIN_DisText(winID, pArray,
  156. 0X15, 1,
  157. 0X02, 255,
  158. 0X15, 1,
  159. 3, 0Xff, 0X00, 0);
  160. }
  161. }
  162. catch (Exception ex) { Console.WriteLine(ex.Message); return false; }
  163. }
  164. }
  165. return true;
  166. }
  167. /// <summary>
  168. /// 显示多行文字
  169. /// </summary>
  170. /// <param name="strs"></param>
  171. /// <returns></returns>
  172. private bool DispString(string[] strs, int time)
  173. {
  174. bool normal = true;
  175. for (int i = 0; i < 4; i++)
  176. {
  177. normal = DispString(i, strs[i], time);
  178. if (!normal)
  179. {
  180. break;
  181. }
  182. }
  183. return normal;
  184. }
  185. /// <summary>
  186. /// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用
  187. /// </summary>
  188. /// <param name="winID"></param>
  189. /// <param name="str"></param>
  190. private void DownloadString(int winID, string str, int index)
  191. {
  192. unsafe
  193. {
  194. byte[] Buff;
  195. if (str.Equals("time"))
  196. {
  197. Buff = Encoding.Default.GetBytes("`H:`N:`S");
  198. fixed (byte* pArray = Buff)
  199. DUCP_HOST_TWIN_DownTextFile(winID,
  200. index >= 0 ? (index <= 15 ? index : 15) : 0,
  201. pArray,
  202. 0X15,
  203. 1,
  204. 0X08,
  205. 255,
  206. 0X15,
  207. 1,
  208. 3,
  209. 0XFF,
  210. 0);
  211. }
  212. else if (str.Equals("date"))
  213. {
  214. Buff = Encoding.Default.GetBytes("`M月`D日");
  215. fixed (byte* pArray = Buff)
  216. DUCP_HOST_TWIN_DownTextFile(winID,
  217. index >= 0 ? (index <= 15 ? index : 15) : 0,
  218. pArray,
  219. 0X15,
  220. 1,
  221. 0X09,
  222. 255,
  223. 0X15,
  224. 1,
  225. 3,
  226. 0XFF,
  227. 0);
  228. }
  229. else
  230. {
  231. Buff = Encoding.Default.GetBytes(str);
  232. fixed (byte* pArray = Buff)
  233. DUCP_HOST_TWIN_DownTextFile(winID,
  234. index >= 0 ? (index <= 15 ? index : 15) : 0,
  235. pArray,
  236. 0X15,
  237. 1,
  238. 0X02,
  239. 255,
  240. 0X15,
  241. 1,
  242. 3,
  243. 0XFF,
  244. 0);
  245. }
  246. }
  247. }
  248. /// <summary>
  249. /// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用。写入多个字符串
  250. /// </summary>
  251. /// <param name="winID"></param>
  252. /// <param name="strs"></param>
  253. private void DownloadString(int winID, string[] strs)
  254. {
  255. for (int i = 0; i < Math.Min(16, strs.Length) && strs[i] != ""; i++)
  256. {
  257. DownloadString(winID, strs[i], i);
  258. }
  259. }
  260. /// <summary>
  261. /// 显示已载入文本文件
  262. /// </summary>
  263. /// <param name="winID"></param>
  264. /// <param name="fieldID"></param>
  265. private void DispDownStr(int winID, int fieldID)
  266. {
  267. DUCP_HOST_TWIN_DisFile(winID, fieldID);
  268. }
  269. /// <summary>
  270. /// 播放语音
  271. /// </summary>
  272. /// <param name="str"></param>
  273. private void AudioPlay(string str)
  274. {
  275. unsafe
  276. {
  277. try
  278. {
  279. byte[] Buff = System.Text.Encoding.Default.GetBytes(str);
  280. fixed (byte* pArray = Buff)
  281. {
  282. DUCP_HOST_TTS_Stop();
  283. DUCP_HOST_TTS_Play(pArray, 0x01);
  284. }
  285. }
  286. catch (Exception ex)
  287. { Console.WriteLine(ex.Message); }
  288. }
  289. }
  290. /// <summary>
  291. /// 删除已下载文本文件
  292. /// </summary>
  293. /// <param name="winID"></param>
  294. /// <param name="startIndex"></param>
  295. /// <param name="endIndex"></param>
  296. private void DelFile(int winID, int startIndex, int endIndex)
  297. {
  298. if (winID >= 0 && winID < 4)
  299. {
  300. for (int i = (startIndex >= 0 ? startIndex : 0); i < (endIndex >= 15 ? 15 : endIndex); i++)
  301. {
  302. DUCP_HOST_TWIN_DelFile(winID, i);
  303. }
  304. }
  305. }
  306. /// <summary>
  307. /// CRC16
  308. /// </summary>
  309. /// <param name="data">要进行计算的数组</param>
  310. /// <returns>计算后的数组</returns>
  311. private static byte[] CRC16(byte[] crcbuf)
  312. {
  313. int crc = 0xffff;
  314. int len = crcbuf.Length;
  315. byte[] redata = new byte[2];
  316. for (int n = 0; n < len; n++)
  317. {
  318. byte i;
  319. crc = crc ^ crcbuf[n];
  320. for (i = 0; i < 8; i++)
  321. {
  322. int TT;
  323. TT = crc & 1;
  324. crc = crc >> 1;
  325. crc = crc & 0x7fff;
  326. if (TT == 1)
  327. {
  328. crc = crc ^ 0xa001;
  329. }
  330. crc = crc & 0xffff;
  331. }
  332. }
  333. redata[1] = (byte)((crc >> 8) & 0xff);
  334. redata[0] = (byte)((crc & 0xff));
  335. return redata;
  336. }
  337. // *************** 公有方法 ***************
  338. public BroadcastBoard(string ip, int port, int volume = 10)
  339. {
  340. //初始化网络连接配置
  341. DeviceIP = IPAddress.Parse(ip);
  342. RPoint = new IPEndPoint(DeviceIP, port);
  343. TPoint = new IPEndPoint(DeviceIP, port);
  344. //设置协议栈的回调函数
  345. unsafe
  346. {
  347. cbDuCP_dataout = new cbDUCP_DataOutType(cbDUCP_DataOut);
  348. MB_STK_SetOutCallback(cbDuCP_dataout);
  349. }
  350. //GC.KeepAlive(cbDuCP_dataout);
  351. /*#2.创建UDP网络套接字*/
  352. DUCP_NetSocket = new UdpClient();
  353. this.volume = volume;
  354. DUCP_HOST_SYS_SetVol(volume);
  355. //Refresh();
  356. }
  357. public void UpdateTime()
  358. {
  359. DateTime dt = DateTime.Now;
  360. DUCP_HOST_SYS_UpdateTime((short)dt.Year, (byte)dt.Month, (byte)dt.Day, (byte)dt.DayOfWeek, (byte)dt.Hour, (byte)dt.Minute, (byte)dt.Second);
  361. }
  362. /// <summary>
  363. /// 刷新屏幕
  364. /// </summary>
  365. public void Refresh()
  366. {
  367. DUCP_HOST_TWIN_Del(0);
  368. DUCP_HOST_TWIN_Del(1);
  369. DUCP_HOST_TWIN_Del(2);
  370. DUCP_HOST_TWIN_Del(3);
  371. DUCP_HOST_TWIN_Create(0, 0, 0, 0, 64, 16);
  372. DUCP_HOST_TWIN_Create(1, 0, 0, 16, 64, 16);
  373. DUCP_HOST_TWIN_Create(2, 0, 0, 32, 64, 16);
  374. DUCP_HOST_TWIN_Create(3, 0, 0, 48, 64, 16);
  375. }
  376. /// <summary>
  377. /// 音量控制
  378. /// </summary>
  379. /// <param name="offset"></param>
  380. public void VolumeControl(int offset, out int vol)
  381. {
  382. volume += offset;
  383. DUCP_HOST_SYS_SetVol(volume);
  384. vol = volume;
  385. }
  386. public void VolumeControl(int vol)
  387. {
  388. DUCP_HOST_SYS_SetVol(volume >= 0 ? (volume <= 50 ? volume : 50) : 0);
  389. }
  390. /// <summary>
  391. /// 重启机器
  392. /// </summary>
  393. public void Restart()
  394. {
  395. DUCP_HOST_SYS_Reset();
  396. }
  397. /// <summary>
  398. /// 配置ip与端口
  399. /// </summary>
  400. /// <param name="ip"></param>
  401. /// <param name="port"></param>
  402. public void IpConfig(string ip, int port)
  403. {
  404. IPAddress ipa = null;
  405. try
  406. {
  407. ipa = IPAddress.Parse(ip);
  408. if (ipa != null)
  409. {
  410. unsafe
  411. {
  412. try
  413. {
  414. byte[] protocol = new byte[] {
  415. 0x00,0x64,0xff,0xff,0x08,0x04,
  416. 0x00,0x00,0x00,0x00,
  417. 0xE6,0x17
  418. };
  419. byte[] Buff = ipa.GetAddressBytes();
  420. Buff.CopyTo(protocol, 6);
  421. byte[] temp = new byte[10];
  422. Array.Copy(protocol, temp, 10);
  423. byte[] crc = CRC16(temp);
  424. Array.Copy(crc, 0, protocol, 10, 2);
  425. fixed (byte* pArray = protocol)
  426. {
  427. cbDUCP_DataOut(pArray, 12);
  428. }
  429. }
  430. catch (Exception ex)
  431. { Console.WriteLine(ex.Message); }
  432. }
  433. DUCP_HOST_SYS_SetPort(port);
  434. }
  435. }
  436. catch (Exception ex) { Console.WriteLine(ex.Message); }
  437. }
  438. public enum PlayMode {temporary, download, delete, readBuffer, audio}
  439. /// <summary>
  440. /// 播放方法
  441. /// </summary>
  442. /// <param name="winID">显示屏窗口ID</param>
  443. /// <param name="mode">播放模式</param>
  444. /// <param name="str">待显示或播语音字符串</param>
  445. /// <param name="time">保持时间</param>
  446. /// <param name="fieldID">存储块ID</param>
  447. /// <param name="startIndex">开始下标</param>
  448. /// <param name="endIndex">结束下标</param>
  449. public void Play(int winID, PlayMode mode, string str,int time=0, int fieldID=0, int startIndex=0, int endIndex=0)
  450. {
  451. switch (mode)
  452. {
  453. case PlayMode.temporary:
  454. DispString(winID, str, time);
  455. break;
  456. case PlayMode.download:
  457. DownloadString(winID, str, fieldID);
  458. break;
  459. case PlayMode.readBuffer:
  460. DispDownStr(winID, fieldID);
  461. break;
  462. case PlayMode.delete:
  463. DelFile(winID, startIndex, endIndex);
  464. break;
  465. case PlayMode.audio:
  466. AudioPlay(str);
  467. break;
  468. }
  469. }
  470. }
  471. }