百度人脸产品套件————壁虎 4.RS485通讯

本篇效果展示:

曾在第一篇开箱中简要分析过壁虎的外设。在最下侧,配备有1路485,2路继电器和一路韦根。

我已经实现了2路继电器的控制,本篇将进行RS485的串口通讯测试。

首先是物理操作
这里我用到一个USB转485的转接模块,通过接上2根跳线

百度人脸产品套件————壁虎 4.RS485通讯_第1张图片

然后两根跳线跳到壁虎的接线端.接的时候注意AB序

百度人脸产品套件————壁虎 4.RS485通讯_第2张图片

然后基本上就是代码啦。

简单总结一下本篇遇到的问题

Xamarin工程下,对安卓的串口控制属于是安卓系统的特性,无法在.net standard项目,也就是xamarin.forms中去添加。

我的解决方案是:
在安卓工程下,制造主程序入口.然后通过Tab切换通用页和特性页
百度人脸产品套件————壁虎 4.RS485通讯_第3张图片

修改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<SerialController>
    {
        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文件夹,负责放各种内容视图
百度人脸产品套件————壁虎 4.RS485通讯_第4张图片
SerialView:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Name="SerialContentView"
             x:Class="GoJhou.Gekko.Droid.SerialView">
  <ContentView.Content>
        <Grid BindingContext="{x:Reference SerialContentView}">
            <Grid.RowDefinitions>
                <RowDefinition Height="200"/>
                <RowDefinition />
                <RowDefinition Height="50"/>
            Grid.RowDefinitions>
            <Label BackgroundColor="LightGray" 
                   x:Name="MessageReceivedLabel" 
                   Text="{Binding ReceivedMessage,Mode=OneWay}"/>
            
            <Editor Grid.Row="1" 
                    x:Name="MessageSendingBox" 
                    BackgroundColor="DarkGray"  
                    Text="{Binding SendMessage,Mode=TwoWay}"/>
            
            <Button Grid.Row="2" 
                    Text="Send"
                    Command="{Binding SendCommand}"/>
        Grid>
  ContentView.Content>
ContentView>
[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主会再接再厉,在后面的章节中完善他们。

感谢支持!

你可能感兴趣的:(百度人脸产品套件——壁虎)