文章目录

  • 前言
  • 一、硬件环境
  • 二、整体构造
    • 1.灯光控制模块
    • 2.主中控模块
    • 3.电脑主机的开关机控制
    • 4.控制电视机的开关

前言

记录自己独自完成的一个完整的展厅中控系统。整体实现思路:灯光线路接上网络继电器,网络继电器接上串口服务器,串口服务器接上路由器,电脑接上路由器,华为paid连接路由器无线网络,实现所有设备连接在一个局域网内。 中控的主要功能: 1.控制灯光的开关 2.控制电脑开关机 3.控制电视机的开机和关机 4.控制内容: a、PPT的上下翻页(有动态效果的) b、视频的暂停、播放、停止 c、系统声音的加减


一、硬件环境

交换机:光电信息转换
路由器:创建局域网络,连接不同的网络设备
AC控制器:管理所有AP设备(无线WIFI)
串口服务器:可以直连传统串口设备(不带IP的模块),通过网络协议发送指令给模块
时序电源:提送稳定可控的电源(可通过IP或串口控制各个电源开闭)
网络继电器:通过网络控制灯光开关
电脑:每台电脑作为单独的服务端
电视机:这里用的是电视机作为显示器
华为paid:安卓系统,作为客户端给每台电脑发送指令

二、整体构造

1.灯光控制模块

灯光连接智能照明模块(其实就是一个继电器),智能照明模块再与串口服务器连接

实现:串口服务器作为服务端,自己开发一个客户端,通过网络协议(我这里是UDP和端口号)连接到串口服务器上,发送指令,实现智能照明模块的开口 开闭合控制灯光的开关

注意事项:智能照明模块的波特率要与串口服务器的波特率设置一致,网络协议(在串口服 务器内也可设置)要确定好(UDP或者是TCP);
确定好智能照明模块的指令(每个模块都有自己的指令,说明书或者供应商提供)

代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;public class SendInstructionsToLamp : MonoBehaviour
{public Socket socket;public int _port = 9600;public string _ip = "192.168.0.7";void Start(){ConnectLight();}/// <summary>/// 通过TCP协议连接智能照明模块(灯组控制部分)/// </summary>public void ConnectLight(){try{//创建客户端Socket,获得远程ip和端口号socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);IPAddress ip = IPAddress.Parse(_ip);IPEndPoint point = new IPEndPoint(ip, _port);socket.Connect(point);Debug.Log("连接成功!");}catch (Exception){Debug.Log("IP或者端口号错误...");}}bool quankai;List<byte[]> instructions_temp;/// <summary>/// 给智能照明模块发送指令(灯组控制部分)/// </summary>/// <param name="instructions">发送指令的list集合</param>/// <param name="timeSpan">发送指令的时间间隔</param>public void SendInstructions(List<byte[]> instructions, float timeSpan) {StartCoroutine(SendInstructions_TimeSpan(instructions, timeSpan));}IEnumerator SendInstructions_TimeSpan(List<byte[]> instructions, float timeSpan) {for (int k = 0; k < 10; k++)//这里为什么要做一个循环发送指令,是因为在实际测试中发现,发送一两次指令不稳定,多发送几次确保指令能被网络继电器接收到{for (int i = 0; i < instructions.Count; i++){byte[] b = new byte[8];socket.Send(instructions[i]);yield return new WaitForSeconds(0.1f);}}yield return new WaitForSeconds(timeSpan);//StopAllCoroutines();}//连接关闭void SocketQuit() {socket.Close();}private void OnApplicationQuit(){Debug.Log(123456);SocketQuit();}/// <summary>/// 一键照明指令/// </summary>/// <param name="b">true为全开、false为全关</param>public void One_KeyLightSwitch(bool b) {if (b){List<byte[]> list_byte1 = new List<byte[]>();byte[] bt1 = new byte[8] { 0x04, 0x06, 0x00, 0x02, 0x00, 0x01, 0xE9, 0x9F };list_byte1.Add(bt1);SendInstructions(list_byte1, 0);Debug.Log("照明全开!");}else {List<byte[]> list_byte2 = new List<byte[]>();byte[] bt1 = new byte[8] { 0x04, 0x06, 0x00, 0x01, 0x00, 0x00, 0xD8, 0x5F };list_byte2.Add(bt1);SendInstructions(list_byte2, 0);Debug.Log("照明全关!");}}
}

2.主中控模块

代码如下:

客户端

using UnityEngine;
using System;
//using System.IO.Ports;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
using UnityEngine.UI;public class SpSend : MonoBehaviour
{public static SpSend _instance;public Toggle[] toggles;public Toggle toggle1;public Socket socketSend;Socket socketSend_Tcp_Udp;string ip;private void Awake(){_instance = this;}private void Start(){bt_connect_Click("192.168.0.101");}public QiehuanVideoPPT_1 qiehuanVideoPPT_1;public void Send_Udp_String(string s){byte[] b = Encoding.ASCII.GetBytes(s.ToCharArray());socketSend_Tcp_Udp.Send(b);}public void bt_connect_Click(string _ip){if (socketSend != null)socketSend = null;try{int _port = 8888;socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);IPAddress ip = IPAddress.Parse(_ip);IPEndPoint point = new IPEndPoint(ip, _port);socketSend.Connect(point);Debug.Log("连接成功!");}catch (Exception){Debug.Log("IP或者端口号错误...");}}public void SendMassageToClient(string s) {//string s = "u:video1.mp4";Debug.Log(s);byte[] b = Encoding.ASCII.GetBytes(s.ToCharArray());socketSend.Send(b);//socketSend.Close();}}

服务端

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine.Video;
using RenderHeads.Media.AVProVideo;public class UDPServer : MonoBehaviour
{public static UDPServer _instance;private void Awake(){_instance = this;}/// <summary>/// 模拟按键  按键对应表:http://www.doc88.com/p-895906443391.html/// </summary>/// <param name="bvk">虚拟键值 </param>/// <param name="bScan">0</param>/// <param name="dwFlags">0为按下,1按住,2释放</param>/// <param name="dwExtraInfo">0</param>[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "keybd_event")]public static extern void Keybd_event(byte bvk, byte bScan, int dwFlags, int dwExtraInfo);//控制键盘事件public void KeybdWait(byte t){Keybd_event(t, 0, 0, 0);Keybd_event(t, 0, 2, 0);}public string ipAddress = "192.168.0.10";public int ConnectPort = 8888;public string recvStr;public ReadConfigJson configJson;public VideoPlayer videoPlayer;public MediaPlayer mediaPlayer;public SoundManager soundManager;Socket socket;EndPoint clientEnd;IPEndPoint ipEnd;string sendStr;byte[] recvData = new byte[1024];byte[] sendData = new byte[1024];int recvLen;Thread connectThread;bool isPlayer,baohu=true;//初始化void InitSocket(){ipEnd = new IPEndPoint(IPAddress.Parse(ipAddress), ConnectPort);socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);socket.Bind(ipEnd);//定义客户端IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);clientEnd = (EndPoint)sender;print("等待连接数据");//开启一个线程连接connectThread = new Thread(new ThreadStart(SocketReceive));connectThread.Start();}public void SocketSend(string sendStr){sendData = new byte[1024];sendData = Encoding.UTF8.GetBytes(sendStr);socket.SendTo(sendData, sendData.Length, SocketFlags.None, clientEnd);}//服务器接收void SocketReceive(){while (true){recvData = new byte[1024];recvLen = socket.ReceiveFrom(recvData, ref clientEnd);recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);Debug.Log("收到得信息 " + recvStr);//控制object要放在主线程里  控制系统虚拟按键要放在线程里——切记切记if (recvStr == "F5"){//recvStr = "";KeybdWait(116);}else if (recvStr == "prve"){//recvStr = "";KeybdWait(37);}else if (recvStr == "next"){//recvStr = "";KeybdWait(39);}else if (recvStr == "frist"){// recvStr = "";WindowMod._instance.SetFrist("中控播放器");}//else if (recvStr == "stop"|| recvStr.Contains(".mp4"))//{//    KeybdWait(27);//}}}//连接关闭void SocketQuit(){//关闭线程if (connectThread != null){connectThread.Interrupt();connectThread.Abort();}//最后关闭socketif (socket != null)socket.Close();Debug.LogWarning("断开连接");}// Use this for initializationvoid Start(){ipAddress = IPManager.GetIP(ADDRESSFAM.IPv4);ConnectPort = configJson.configInfo.port;InitSocket(); //在这里初始化serverToolControlTaskBar.HideTaskBar();}public void PlayerInstruction(){if (recvStr == "frist"){recvStr = "";WindowMod._instance.SetFrist("ZKPlayer");KillProcess("PowerPoint 幻灯片放映 - [ppt1.pptx]");}else if (recvStr.Contains(".ppsx")&&baohu){baohu = false;isPlayer = false;KillProcess("POWERPNT.EXE");FunctionControl._instance.shiping.SetActive(false);//videoPlayer.Stop();//videoPlayer.targetTexture.Release();mediaPlayer.Stop();Application.OpenURL(Application.streamingAssetsPath + "/ppt/" + recvStr);//StartCoroutine(WaitLookForPPT());//WindowMod._instance.SetFrist(recvStr+" - PowerPoint");recvStr = "";baohu = true;}else if (recvStr.Contains(".mp4")){isPlayer = true;mediaPlayer.m_VideoPath = Application.streamingAssetsPath + "/mp4/" + recvStr;//mediaPlayer.//videoPlayer.url = Application.streamingAssetsPath + "/mp4/" + recvStr;//videoPlayer.Play();mediaPlayer.OpenVideoFromFile(MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder, mediaPlayer.m_VideoPath);mediaPlayer.Play();recvStr = "";FunctionControl._instance.shiping.SetActive(true);WindowMod._instance.SetFrist("ZKPlayer");KillProcess("POWERPNT.EXE");}else if (recvStr == "play"&&isPlayer){recvStr = "";//videoPlayer.Play();mediaPlayer.Play();}else if (recvStr == "pause"){//videoPlayer.Pause();mediaPlayer.Pause();recvStr = "";}else if (recvStr == "stop"){isPlayer = false;//videoPlayer.Stop();//videoPlayer.targetTexture.Release();mediaPlayer.Stop();WindowMod._instance.SetFrist("ZKPlayer");FunctionControl._instance.shiping.SetActive(false);KillProcess("POWERPNT.EXE");recvStr = "";}//else if (recvStr!=null && recvStr.Contains(".mp4"))//{//    videoPlayer.url= Application.streamingAssetsPath + "/mp4/" + recvStr;//    videoPlayer.Stop();//    videoPlayer.Play();//    recvStr = "";//}if (recvStr == "volumeup"){soundManager.SystemVolumeUp();recvStr = "";}else if (recvStr == "volumedown"){soundManager.SystemVolumeDown();recvStr = "";}else if (recvStr == "close"){CloseComputer();recvStr = "";}}private void Update(){PlayerInstruction();if (Screen.width != ReadConfigJson._instance.configInfo.screenWidth){Screen.SetResolution(ReadConfigJson._instance.configInfo.screenWidth, ReadConfigJson._instance.configInfo.screenHeigth, true);}}void OnApplicationQuit(){SocketQuit();ToolControlTaskBar.ShowTaskBar();}public void CloseComputer(){System.Diagnostics.Process p = new System.Diagnostics.Process();p.StartInfo.FileName = "cmd.exe";p.StartInfo.Arguments = "/c " + "shutdown -s -t 0";p.Start();}/// <summary>/// 杀死进程/// </summary>/// <param name="processName">应用程序名</param>void KillProcess(string processName){System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses();foreach (System.Diagnostics.Process process in processes){Debug.Log(process.ProcessName);try{if (!process.HasExited){if (process.ProcessName == processName){process.Kill();UnityEngine.Debug.Log("已杀死进程");}}}catch (System.InvalidOperationException){//UnityEngine.Debug.Log("Holy batman we've got an exception!");}}}}

本来视频播放用的是unity自带组件videoplayer,但是展厅的主机没有独立显卡,视频播放起来会卡顿,于是便换成了AVpro。


3.电脑主机的开关机控制

开机:通过网络给电脑发开机指令
注意事项:你的电脑允许网络唤醒,在boss主板设置勾选允许网络唤醒
网卡驱动也要设置允许网络唤醒

如果你发现你的你没有电源管理,请更新网卡驱动

网络唤醒代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
public class WakeUpComputer : MonoBehaviour
{//通过正则表达式设定MAC地址筛选标准,关于正则表达式请自行百度const string macCheckRegexString = @"^([0-9a-fA-F]{2})(([/\s:-][0-9a-fA-F]{2}){5})$";private static readonly Regex MacCheckRegex = new Regex(macCheckRegexString);//唤醒主要逻辑方法public static bool WakeUp(string mac){//查看该MAC地址是否匹配正则表达式定义,(mac,0)前一个参数是指mac地址,后一个是从指定位置开始查询,0即从头开始if (MacCheckRegex.IsMatch(mac, 0)){byte[] macByte = FormatMac(mac);WakeUpCore(macByte);return true;}return false;}private static void WakeUpCore(byte[] mac){//发送方法是通过UDPUdpClient client = new UdpClient();//Broadcast内容为:255,255,255,255.广播形式,所以不需要IPclient.Connect(IPAddress.Broadcast, 50000);//下方为发送内容的编制,6遍“FF”+17遍mac的byte类型字节。byte[] packet = new byte[17 * 6];for (int i = 0; i < 6; i++)packet[i] = 0xFF;for (int i = 1; i <= 16; i++)for (int j = 0; j < 6; j++)packet[i * 6 + j] = mac[j];//唤醒动作client.Send(packet, packet.Length);}private static byte[] FormatMac(string macInput){byte[] mac = new byte[6];string str = macInput;//消除MAC地址中的“-”符号string[] sArray = str.Split('-');//mac地址从string转换成bytefor (var i = 0; i < 6; i++){var byteValue = Convert.ToByte(sArray[i], 16);mac[i] = byteValue;}return mac;}public void Button_Click_WakeUp(string s){WakeUp(s);//print(WakeUp("4A-BB-6D-61-75-AE"));//print(WakeUp("E4-3A-6E-36-38-AA"));}
}

关机:发送指令给电脑关机
注意事项:关机没啥主意事项,很简单
关机代码:

 public void CloseComputer(){System.Diagnostics.Process p = new System.Diagnostics.Process();p.StartInfo.FileName = "cmd.exe";p.StartInfo.Arguments = "/c " + "shutdown -s -t 0";p.Start();
}

4.控制电视机的开关

开关机:RS232红外学习模块+串口服务器,
实现:串口服务器做服务端,RS232红外学习模块与串口服务器直连,自己开发客户端通过网络协议(我这里是UDP和端口号)连接到串口服务器上,发送指令给服务端,从而控制RS232红外学习模块。
(连接方式和设置同智能照明模块一样,接线可能有所区别)
注意事项:红外学习模块学习电视机的开关机频率,同时设置指令;
学习的时候,电视遥控器对准红外学习指示灯,按住遥控器开机键,直到红外学习指示灯 快速连闪3下,学习结束

Unity开发展厅中控系统相关推荐

  1. Unity 影音视频播放中控系统(适用于展厅、影音厅),带UDP控制切换!

    Unity - 影音视频播放中控系统(适用于展厅.影音厅等等),带有关机.音量控制.UDP控制切换! 一:效果图 二:所用插件 三:项目说明! 三:工程详解! 四:Demo学习 五:关于AB资源打包的 ...

  2. IronMCC 多媒体展厅中控系统

    IronMCC 多媒体展厅中控系统 官网:http://ironlight.cn 可定制开发:http://ironlight.cn/app/customized 简介 IronMCC 是一款操作简单 ...

  3. 展厅中控系统分二阶段开发方案

    第一:中控方案 利用Java做服务器.C#做客户端.Android做平板控制端.3个部分组成一个简单的中控系统,然后在逐渐在第二期增加 电源控制器.串口控制器. 第一期 :Demo 开发 1.PPT. ...

  4. php展厅播控系统,展厅中控系统

    展厅智能中控系统简介 展厅智能中控系统是一种对展厅所有展项进行集中管理和控制的智能控制系统.展厅智能中控系统主要是通过PC端.平板电脑.手机等智能设备来控制展厅各展项的智能控制系统,现代化人性化.目前 ...

  5. vr沉浸式仿真实训展厅中控系统提高课堂纪律

    为解决实训教学过程中"看不到.进不去.成本高.危险大"的问题,VR智能中控系统为职业教育及高等教育老师提供一个数字化.沉浸式.集中管控的实训教学工具. VR智能中控系统通过对VR教 ...

  6. 展厅多媒体视频系统视频服务器,展厅中控|展厅视频播放控制系统-米禾数字

    随着多媒体应用技术的快速发展,数字沙盘.互动滑轨屏.触摸互动.体感互动等多媒体互动展项在现代化展厅展馆中的应用也越来越普遍,展览展示中需要控制的应用越来越多,人为手动控制愈发不便,所以现代化展厅展馆设 ...

  7. 展厅智能中控系统在博物馆中的应用

    随着数字化技术的发展,各类科技馆.企业展厅.博物馆等在展厅设计施工时都加入了智能中控系统.尤其是在博物馆设计中,为了能够更直观展示文物藏品,通过运用智能中控系统来控制展厅声.光.电等所有设备,从而给观 ...

  8. 【蓝鸥Unity开发基础三】课时3 Terrain地形系统【未完】

    [蓝鸥Unity开发基础三]课时3  Terrain地形系统[未完] 推荐视频讲师博客:http://11165165.blog.51cto.com/ 一.Terrain地形系统 Terrain地形系 ...

  9. 【Unity游戏开发】动画系统(二)2D动画

    文章目录 动画系统之2D动画 Unity的动画 2d动画 实例 准备工作 开始简单的动画 结语 动画系统之2D动画 2d动画其实就是图片的转换,每帧转换实现2d的动态效果其实这也是3d动画的实现原理, ...

最新文章

  1. java和内存交互,java内存模型-内存间交互操作
  2. C罗还会是史上第一个上链的得分王吗?
  3. p2657 windy数
  4. js 月份加6个月_12月AHA HS大众急救认证培训22个城市报名开启!2021年1~6月份课程预售限时开启!!...
  5. 特性和混入不是面向对象的
  6. composer升级_Composer-命令简介
  7. STM32——流水灯
  8. 网页弹出框----播放视频
  9. document.body、document.documentElement和window获取视窗大小的区别
  10. RT-Thread Stduio 增加一个串口3
  11. i计算机网络的应用程序,计算机网络技术及其在校园网的研究与应用毕业论文.doc...
  12. 模糊逻辑学习--建立Mamdani系统(GUI)
  13. Verilog 初学笔记--顺序操作 和 并行操作的一点思考(参考黑金教程:Verilog HDL那些事 建模篇)...
  14. Python数据清洗处理,csv,pandas,数据匹配
  15. 基于matlab的图像识别分类实验(一)
  16. 052试题 97 - SQL*Loader Direct Path and Conventional Path
  17. 2022危险化学品经营单位安全管理人员操作证考试题库及在线模拟考试
  18. Java基础之MySQL数据库与JDBC
  19. 细胞亚器文献阅读二~An ER-Mitochondria Tethering Complex Revealed by a Synthetic Biology Screen
  20. 决定迭代次数的两种效应

热门文章

  1. 大数据升级治霾手段:拒绝“一刀切”误伤
  2. 台式计算机没有usb3.0,台式机USB3.0扩展卡怎么样 | 台式机USB3.0扩展卡开箱_什么值得买...
  3. Android音频改进设想及PulseAudio
  4. 《雨季不再来》自序选 三毛
  5. 人生苦短,我要学Python,2019年最靠谱Python书单送你
  6. 是终点,也是起点 ---150天通关RHCA心得体会
  7. Future和Callable的使用
  8. [pig框架实战] 手撕视频管理发布平台[02] - pig框架源码分析(去除开发过程中每次输入验证码的过程,方便快速登录)
  9. 发一台数字控制稳压电源试试 测试IC等小功率低波纹高精度专用
  10. 微信小程序实现下拉菜单效果