有一说一,这个功能从需求角度是个伪需求,你说你用遥控器不行吗?
但是有的时候,场景不允许的情况下不便于拿着遥控器到处跑,用手机更合适。所以有的上一篇,如何用.net+Xamarin.iOS来调用局域网的udp。
公司中有一些设备是联网的,有的是独立设备。例如进入内部的一个3.5米高的大门,领导和我说,曾经这个东西是可以远程打开的,我是去机房找,爬梯子找,也没有能找到如何用com口链接这个门。
后来经过一些机缘巧合吧,有人和我说了一个办法,遥控器开关的门,用遥控器解锁也是个好办法啊!我看到遥控器背面有个标签,贴着一个315mhz,于是我就去某宝上搜索了一下如何315Mhz发射信号。
看到了一个USB转射频的小玩意,看着像是个U盘,尾巴上有个弹簧(天线)。
商家会给一个软件,用来监听com口的反馈,给这个插上之后,按遥控器,就会显示出这个遥控器的key,是一个7位数的byte(16进制)。这个设备的帧头和帧尾和遥控器的不一样,我问商家,商家的意思是说发送信号必须使用指定的头尾来替换
还好设备就两个按钮(开门,关门)所以记录下来了2个地址。按照开门关门举例子:
using System.IO.Ports;
using System.ComponentModel;
public partial class MainForms : Form
{
// 这里的数字都是16进制
private readonly byte[] open = { 0x99, 0x03, 0xXX, 0xXX, 0xXX, 0xXX, 0x99 };
private readonly byte[] close = { 0x99, 0x03, 0xXX, 0xXX, 0xX2, 0xXX, 0x99 };
private readonly SerialPort _serialPort;
private readonly IContainer _components;
public MainForms()
{
_components = new Container();
_serialPort = new SerialPort(_components);
InitializeComponent();
}
private async Task DoorControl(byte[] open, byte[] close)
{
try
{
_serialPort.BaudRate = 9600; //波特率
_serialPort.DataBits = 8; //数据位
_serialPort.StopBits = StopBits.One;//停止位
_serialPort.Parity = Parity.None; //校验位
//这个是COM口的名称, 名称肯定是COMX 如果不知道可以通过SerialPort.GetPortNames() 来获得COM口的名称List
_serialPort.PortName = "COM1";
WriteLog(txtLogs, "[COM] 已发送开门信号 \r\n");
_serialPort.Open();
_serialPort.Write(open, 0, 7);
await Task.Delay(3000);
_serialPort.Write(close, 0, 7);
WriteLog(txtLogs, "[COM] 已发送关门信号 \r\n");
}
catch (Exception ex)
{
WriteLog(txtLogs, $"[COM] 开门异常, {ex} \r\n");
}
finally
{
_serialPort.Close();
WriteLog(txtLogs, "[COM] COM口已关闭 \r\n");
}
}
}
在UDP响应时调用DoorControl 方法, 就可以对开关门进行操作了!
中间还遇到了一些其他问题, 比如断联, 断联很麻烦, 需要重新启动应用或者插拔一下设备. 所以我把这个USB设备插到了本地机房. 机房距离这个门的直线距离是10米左右, 加上承重墙和机房门, 响应速度也在毫秒级别.
因为是某宝的商品, 所以我就不放链接了, 如果有需要可以自己去搜索购买.
记录这个事情只是为了我备忘, 这个设备不值钱, 但是这个思路好歹值一个月工资吧!