本篇效果展示:
曾在第一篇开箱中简要分析过壁虎的外设。在最下侧,配备有1路485,2路继电器和一路韦根。
我已经实现了2路继电器的控制,本篇将进行RS485的串口通讯测试。
首先是物理操作
这里我用到一个USB转485的转接模块,通过接上2根跳线
然后两根跳线跳到壁虎的接线端.接的时候注意AB序
然后基本上就是代码啦。
简单总结一下本篇遇到的问题
Xamarin工程下,对安卓的串口控制属于是安卓系统的特性,无法在.net standard项目,也就是xamarin.forms中去添加。
我的解决方案是:
在安卓工程下,制造主程序入口.然后通过Tab切换通用页和特性页
修改MainActivity,以使得安卓应用入口的Page为TabPage
protected override void OnCreate(Bundle savedInstanceState) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); //主要修改在这 var app = new App(); app.MainPage = new TabPage(); LoadApplication(app); }
TabPage主要就做了2页,第一页叫常规测试,包含了灯光和继电器控制(因为都是FILE IO操作)。第二页叫特殊测试(包含了安卓系统操作串口的操作器):
private void Button_Clicked(object sender, EventArgs e) { Container.Children.Clear(); Container.Children.Add(new MainPage()); } private void Button_Clicked_1(object sender, EventArgs e) { Container.Children.Clear(); Container.Children.Add(new SerialView()); }
那本篇的重点就变成了:
如何在xamarin项目中使用安卓串口进行通讯!
up主强烈推荐nuget库:Xamarin.Android.SerialPort
该库依赖于monoAndroid,所以一定要在安卓项目下。
这里我新建了一个安卓类库(GoJhou.Gekko.Android.UART)
然后引入了该nuget库。封装了SerialController如下:
public class MessageEventArgs : EventArgs { public readonly string Message; public MessageEventArgs(string msg) { Message = msg; } } public class SerialController: BaseController { private SerialPort.SerialPortWrapper.SerialPort sp; public delegate void OnMessageReceivedEventHandler(MessageEventArgs e); public event OnMessageReceivedEventHandler MessageReceived; private string Message=string.Empty; public SerialController() { sp = new SerialPort.SerialPortWrapper.SerialPort("/dev/ttyS4", 9600, Stopbits.One, Parity.None, ByteSize.EightBits, FlowControl.None, Timeout.SimpleTimeout(-1)); sp.StartReceive(); sp.Flush(); sp.OnReceived += Sp_OnReceived; } public void SendMessage(string msg) { sp.WriteLine(msg); sp.FlushOutput(); } private void Sp_OnReceived(object sender, SerialPort.SerialPortWrapper.SerialPortEventArgs e) { var sp = sender as SerialPort.SerialPortWrapper.SerialPort; string message = Encoding.UTF8.GetString(e.Data); Message += message; if(Message.Contains("|")) { var command = Message.Split('|'); Message = command[1]; string msg = command[0]; MessageReceived?.Invoke(new MessageEventArgs(msg)); } } }
由于研究不透彻,我发现这个库的OnReceived回调不稳定,接收字符长度有波动。只好手动定义了一个命令分隔符’|'来表示一个命令的正式结束。然后自己重新暴露一个MessageReceived的事件表示一个完整的消息。
有了操作类,其他基本上就和之前的一样啦!
在Android项目下新建一个View文件夹,负责放各种内容视图
SerialView:
[XamlCompilation(XamlCompilationOptions.Compile)] public partial class SerialView : ContentView { public SerialController SerialPortController => SerialController.Instance; private string sendMessage; public string SendMessage { get => sendMessage; set { sendMessage = value; OnPropertyChanged(); } } private string receivedMessage; public string ReceivedMessage { get => receivedMessage; set { receivedMessage = value; OnPropertyChanged(); } } public Command SendCommand { get => new Command(new Action(() => { SerialPortController.SendMessage(SendMessage); //SendMessage = string.Empty; })); } public SerialView() { InitializeComponent(); SerialPortController.MessageReceived += (s) => { ReceivedMessage +="|"+ s.Message; }; } }
最后算是实现了壁虎的RS485通讯测试。
ps:up主第一次触摸到xamarin项目,本篇写的着实有些凌乱,可能不符合xamarin的设计模式。希望up主会再接再厉,在后面的章节中完善他们。
感谢支持!