百度人脸产品套件-壁虎 4.RS485通讯
goJhou 发布于2019-11 浏览:5773 回复:0
0
收藏

本篇效果展示:

https://jhou-bucket.oss-cn-shanghai.aliyuncs.com/2019-10-18%20%E5%A3%81%E8%99%8E%E6%B5%8B%E8%AF%84/2019-10-30%20RS485/demo.mp4

 

 

曾在第一篇开箱中简要分析过壁虎的外设。在最下侧,配备有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主会再接再厉,在后面的章节中完善他们。

感谢支持!

收藏
点赞
0
个赞
TOP
切换版块