using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace BroadcastModule { public class BroadcastBoard { private UdpClient DUCP_NetSocket; private IPAddress DeviceIP; private IPEndPoint RPoint = null; private IPEndPoint TPoint = null; private int volume = 10; //*********************************************** 动态引用dll ****************************************** //实现协议栈数据输出回调函数 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] unsafe delegate byte cbDUCP_DataOutType(byte* Data, int Size); [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static void MB_STK_SetOutCallback(cbDUCP_DataOutType cb); [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static sbyte MB_STK_In(byte* Data, int Size); //回调对象 private cbDUCP_DataOutType cbDuCP_dataout; //回调函数实现 unsafe byte cbDUCP_DataOut(byte* Data, int Size) { sbyte Ret; byte[] buff = new byte[256]; byte[] RxBuff = new byte[256]; for (int i = 0; i < Size; i++) { buff[i] = Data[i]; } /*发送数据到显示屏*/ DUCP_NetSocket.Send(buff, Size, TPoint); /*接收显示屏回复的数据*/ RxBuff = DUCP_NetSocket.Receive(ref RPoint); /*将显示屏的回复的数据传输给协议栈*/ unsafe { fixed (byte* pArray = RxBuff) Ret = MB_STK_In(pArray, RxBuff.Length); } return (byte)Ret; } //调节音量 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_SYS_SetVol(int vol); //播放语音 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_TTS_Play(byte* pText, byte Opt); //停止播放语音 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_TTS_Stop(); //重启系统 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_SYS_Reset(); //显示已存文件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_TWIN_DisFile(int WinID, int FileID); //显示文本 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_TWIN_DisText(int WinID, byte* pText, int EnterMode, int EnterSpeed, int DelayMode, int DelayTime, int EixtMode, int EixtSpeed, int FontIndex, int TextColor, int BkColor, int DisTimes); //创建文本控件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_TWIN_Create(int WinID, int Stile, int x0, int y0, int xSize, int ySize); //删除文本控件中文本文件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_TWIN_DelFile(int WinID, int FileID); //删除文本控件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_TWIN_Del(int WinID); //删除图片控件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_PIC_Del(int WinID); //设置绘图颜色 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_2D_SetColor(int Color); //填充矩形 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_2D_FillRect(int x0, int y0, int x1, int y1); //绘制系统自带位图 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_2D_DrawSysIcon(int x0, int y0, int Num, int Denom, int IconIndex); //创建图片控件 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_PIC_Create(int WinID, int x0, int y0, int xSize, int ySize); //图片控件追加图片 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_PIC_Add(int WinID, int FID, byte EnterMode, byte EnterSpeed, byte StopMode, byte StopTime, byte ExitMode, byte ExitSpeed); //更新本地时间 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] extern static byte DUCP_HOST_SYS_UpdateTime(short Year, byte Month, byte Day, byte Week, byte Hour, byte Minute, byte Second); //更新端口(更新ip方法异常,手动更新) [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_SYS_SetPort(int port); //下载文本文件并与文本控件关联 [DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)] unsafe extern static byte DUCP_HOST_TWIN_DownTextFile(int WinID, int FileID, byte* pText, int EnterMode, int EnterSpeed, int DelayMode, int DelayTime, int EixtMode, int EixtSpeed, int FontIndex, int TextColor, int BkColor); //************************************************ 方法块 ************************************************** // *************** 私有方法 *************** /// /// 显示特定行文字 /// /// /// /// private bool DispString(int winID, string str, int time) { byte[] buffer = Encoding.Default.GetBytes(str); if (winID < 0 || winID > 3) { return false; } unsafe { fixed (byte* pArray = buffer) { try { if (time >= 0 && time <= 255) { DUCP_HOST_TWIN_DisText(winID, pArray, 0X15, 1, 0X00, time, 0X15, 1, 3, 0Xff, 0X00, 0); } else { DUCP_HOST_TWIN_DisText(winID, pArray, 0X15, 1, 0X02, 255, 0X15, 1, 3, 0Xff, 0X00, 0); } } catch (Exception ex) { Console.WriteLine(ex.Message); return false; } } } return true; } /// /// 显示多行文字 /// /// /// private bool DispString(string[] strs, int time) { bool normal = true; for (int i = 0; i < 4; i++) { normal = DispString(i, strs[i], time); if (!normal) { break; } } return normal; } /// /// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用 /// /// /// private void DownloadString(int winID, string str, int index) { unsafe { byte[] Buff; if (str.Equals("time")) { Buff = Encoding.Default.GetBytes("`H:`N:`S"); fixed (byte* pArray = Buff) DUCP_HOST_TWIN_DownTextFile(winID, index >= 0 ? (index <= 15 ? index : 15) : 0, pArray, 0X15, 1, 0X08, 255, 0X15, 1, 3, 0XFF, 0); } else if (str.Equals("date")) { Buff = Encoding.Default.GetBytes("`M月`D日"); fixed (byte* pArray = Buff) DUCP_HOST_TWIN_DownTextFile(winID, index >= 0 ? (index <= 15 ? index : 15) : 0, pArray, 0X15, 1, 0X09, 255, 0X15, 1, 3, 0XFF, 0); } else { Buff = Encoding.Default.GetBytes(str); fixed (byte* pArray = Buff) DUCP_HOST_TWIN_DownTextFile(winID, index >= 0 ? (index <= 15 ? index : 15) : 0, pArray, 0X15, 1, 0X02, 255, 0X15, 1, 3, 0XFF, 0); } } } /// /// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用。写入多个字符串 /// /// /// private void DownloadString(int winID, string[] strs) { for (int i = 0; i < Math.Min(16, strs.Length) && strs[i] != ""; i++) { DownloadString(winID, strs[i], i); } } /// /// 显示已载入文本文件 /// /// /// private void DispDownStr(int winID, int fieldID) { DUCP_HOST_TWIN_DisFile(winID, fieldID); } /// /// 播放语音 /// /// private void AudioPlay(string str) { unsafe { try { byte[] Buff = System.Text.Encoding.Default.GetBytes(str); fixed (byte* pArray = Buff) { DUCP_HOST_TTS_Stop(); DUCP_HOST_TTS_Play(pArray, 0x01); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } } /// /// 删除已下载文本文件 /// /// /// /// private void DelFile(int winID, int startIndex, int endIndex) { if (winID >= 0 && winID < 4) { for (int i = (startIndex >= 0 ? startIndex : 0); i < (endIndex >= 15 ? 15 : endIndex); i++) { DUCP_HOST_TWIN_DelFile(winID, i); } } } /// /// CRC16 /// /// 要进行计算的数组 /// 计算后的数组 private static byte[] CRC16(byte[] crcbuf) { int crc = 0xffff; int len = crcbuf.Length; byte[] redata = new byte[2]; for (int n = 0; n < len; n++) { byte i; crc = crc ^ crcbuf[n]; for (i = 0; i < 8; i++) { int TT; TT = crc & 1; crc = crc >> 1; crc = crc & 0x7fff; if (TT == 1) { crc = crc ^ 0xa001; } crc = crc & 0xffff; } } redata[1] = (byte)((crc >> 8) & 0xff); redata[0] = (byte)((crc & 0xff)); return redata; } // *************** 公有方法 *************** public BroadcastBoard(string ip, int port, int volume = 10) { //初始化网络连接配置 DeviceIP = IPAddress.Parse(ip); RPoint = new IPEndPoint(DeviceIP, port); TPoint = new IPEndPoint(DeviceIP, port); //设置协议栈的回调函数 unsafe { cbDuCP_dataout = new cbDUCP_DataOutType(cbDUCP_DataOut); MB_STK_SetOutCallback(cbDuCP_dataout); } //GC.KeepAlive(cbDuCP_dataout); /*#2.创建UDP网络套接字*/ DUCP_NetSocket = new UdpClient(); this.volume = volume; DUCP_HOST_SYS_SetVol(volume); //Refresh(); } public void UpdateTime() { DateTime dt = DateTime.Now; 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); } /// /// 刷新屏幕 /// public void Refresh() { DUCP_HOST_TWIN_Del(0); DUCP_HOST_TWIN_Del(1); DUCP_HOST_TWIN_Del(2); DUCP_HOST_TWIN_Del(3); DUCP_HOST_TWIN_Create(0, 0, 0, 0, 64, 16); DUCP_HOST_TWIN_Create(1, 0, 0, 16, 64, 16); DUCP_HOST_TWIN_Create(2, 0, 0, 32, 64, 16); DUCP_HOST_TWIN_Create(3, 0, 0, 48, 64, 16); } /// /// 音量控制 /// /// public void VolumeControl(int offset, out int vol) { volume += offset; DUCP_HOST_SYS_SetVol(volume); vol = volume; } public void VolumeControl(int vol) { DUCP_HOST_SYS_SetVol(volume >= 0 ? (volume <= 50 ? volume : 50) : 0); } /// /// 重启机器 /// public void Restart() { DUCP_HOST_SYS_Reset(); } /// /// 配置ip与端口 /// /// /// public void IpConfig(string ip, int port) { IPAddress ipa = null; try { ipa = IPAddress.Parse(ip); if (ipa != null) { unsafe { try { byte[] protocol = new byte[] { 0x00,0x64,0xff,0xff,0x08,0x04, 0x00,0x00,0x00,0x00, 0xE6,0x17 }; byte[] Buff = ipa.GetAddressBytes(); Buff.CopyTo(protocol, 6); byte[] temp = new byte[10]; Array.Copy(protocol, temp, 10); byte[] crc = CRC16(temp); Array.Copy(crc, 0, protocol, 10, 2); fixed (byte* pArray = protocol) { cbDUCP_DataOut(pArray, 12); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } DUCP_HOST_SYS_SetPort(port); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } public enum PlayMode {temporary, download, delete, readBuffer, audio} /// /// 播放方法 /// /// 显示屏窗口ID /// 播放模式 /// 待显示或播语音字符串 /// 保持时间 /// 存储块ID /// 开始下标 /// 结束下标 public void Play(int winID, PlayMode mode, string str,int time=0, int fieldID=0, int startIndex=0, int endIndex=0) { switch (mode) { case PlayMode.temporary: DispString(winID, str, time); break; case PlayMode.download: DownloadString(winID, str, fieldID); break; case PlayMode.readBuffer: DispDownStr(winID, fieldID); break; case PlayMode.delete: DelFile(winID, startIndex, endIndex); break; case PlayMode.audio: AudioPlay(str); break; } } } }