本篇文章验证Python作为服务器接收ME3616 TCP数据并进行简单过滤。内容包括Python服务器窗口搭建(重点描述),Python服务器通信示例,ME3616通信示例,IP地址映射问题解决。文章会作为一个跳板,以便后期使用ME3616_G3A进行跟踪定位并发送数据给到服务器,然后整机装载到自己的踏板车上,以后骑踏板车去图书馆就不怕丢了。
一、wxPython服务器窗口搭建
服务器窗口几个主要界面,接收窗口,发送窗口,IP、端口输入窗口,发送按钮。也没有详细概念,所以布局就参考最常用的"网络调试助手"
1.1 界面搭建
在本节将搭建TCP服务器界面,工具使用wxPython图形界面编程,每行代码包含详细注释方便以后复习&修改。
1.1.1 导入窗体
图形用户界面主要是由窗口&窗口中的控件构成,编写wxPython就是创建窗口和添加控件的过程。wxPython的窗口使用wx.Frame(对象),关闭窗口使用wx.App对象,wx.App对象代表当前应用程序。
1.1.2 添加按键
这里引入2个概念,panel和事件。
当按钮(事件源)按下(事件类型)时,一般希望响应特定函数(事件处理者),此时就用到了Bind()方法:Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)。event事件类型,handler事件处理者,对应事件处理类中特定方法;source事件源;id事件源标识,可省略source绑定id事件源;id2设置要绑定事件源的范围。
1.1.3 布局管理
之前的图形界面按钮的位置固定,当放大、缩小整个界面时按钮不会跟着移动,显示效果不友好。为了正常的缩放(水平&垂直),需要使用wx.BoxSizer布局器,将按钮等需要缩放的控件添加到BoxSizer中就可以正常缩放了。
box是需要嵌套的,这里将按钮的位置信息去掉,然后使用box布局管理器重新布局处理
1.1.4 添加数据显示
数据显示在最上面,结合刚刚的vbox,创建一个TextCtrl整合即可
这里重新认识了wx.EXPAND,wx.TOP...ALL原来是配合border设置对应边界的。
1.1.5 左侧参数布局
界面的左侧(左上角)需要添加显示IP、端口号,添加对应的文本框然后box调整布局
这里新增了wx.StaticBox--静态文本框,同时使用StaticBoxSizer将文本框、文本、输入框包裹起来
至此,服务器界面的基本框架已经搭建完成,后面就看如何将TCP的数据与这个框架相结合了。
二、TCP服务器、客户端程序编写
TCP服务器、客户端的程序网上搜索非常多,这里直接参考CSDN的文章并验证可正常通信,链接:https://blog.csdn.net/qq_26442553/article/details/94469527,程序代码在作者基础上只做格式调整。
需要注意的是客户端发送3次后退出,调用tcp_socket.close()之后会发送部分内容,服务器收到之后跳出new_client_socket.recv(1024)循环,并且能够识别是关闭socket的底层协议,跳转到else后break本次通信链接。
三、窗口UI & 底层TCP拼接
上面单独UI和TCP通信已经完成,要使UI界面显示对应数据就要将2个程序整合了。UI只编写服务器的,客户端后期使用ME3616 NB模组发送TCP程序,所以不需要编写UI。
3.1 程序拼接
该部分难点在于服务器接收端如何持续监听&刷新接收窗口。找了很多网上资料都是Client方法,而且在按钮发送中执行(不和逻辑),在《Python项目案例开发从入门都时间》-郑秋生、夏敏洁的书中看到,他们把服务器、客户端的代码封装为一个方法,然后创建一个线程,启动接收(这里如果不创建线程,while循环监听会导致UI界面死机)。
3.1.1 创建线程
threading.Thread(target=None, name=None, args=()),target传入自定义函数,这里就是TCP的方法了,name可以为线程定义一个名字(可省略),args可以传入target的参数(如果target方法有参数的话)
3.1.2 TCP服务器接收程序
TCP服务器接收程序直接在Frame中定义方法,重新命名就行了
3.1.3 APP子类启动
这里子类启动线程(调用startNewThread)方法,如果直接调用rcvMessage方法而不是线程会造成系统死机,因为rcvMessage方法是while循环,就无法刷新窗口了
调试代码,图形界面可正常显示,下面printf也可以正常打印,说明并行运行没有问题,后面将数据调用到显示接口就行了。
3.1.4 UI显示接收数据
UI界面显示就是将刚刚的接收数据recv_data显示到接收窗口来,调试发现rcvMessage()方法需要调用tcSend文本控制参数,所以将tcSend重新定义为self.tcSend以便类中所有方法共用。其他直接调用拼接字符串self.tcRcv.AppendText(str(recv_data)+"\r\n")就行了。注意及时recv_data是字符串这里也要加入str()进行修饰
需要注意AppendText参数中需要传入字符串,recv_data不能直接传入,需要加str()进行转换,运行结果如下
为了优化显示效果,类似串口/网络调试助手每次接收时显示时间参数,这里加入time类。为了单独验证时间以字符格式输出,使用python shell调试验证
将datetime整合到现有输出格式下
四、ME3616 模组TCP通信 & GPS连接
ME3616模组TCP通信过于简单,串口按照流程发送AT指令就可以了,这里将GPS操作同步说明。
4.1 TCP通信流程
参考文章《ME3616 TCP&UDP通信》,使用串口根据流程发送对应指令即可,高新兴全系列模组支持TCP通信,都可以进行测试。
4.2 GPS使用流程
参考文章《ME3616 NBIOT GNSS(GPS+北斗)定位应用示例》,建议入网之后,在开启GPS,GPS位置信息获取后就可以发送数据了。
五、ME3616对接Python TCP服务器
写到这里发现文章的结构和wxPython添加BOX一样,单独模块功能验证完成后进行拼接^▽^。
5.1 内网穿透地址映射
ME3616使用TCP通信直接发送数据到Python服务器的IP是无法进行传输的,具体可参考文章https://blog.csdn.net/songshiMVP1/article/details/51519767《内网与外网之间的通信(端口映射原理)》或者之前发布的文章《ME3616—TCP调试公网IP端口映射的解决方法》,因为花生壳开始实名认证(手拿身份证拍照)所以不在使用(大家也不推荐用花生壳),找其他解决方案,百度搜了搜内网穿透的文章参考"https://www.jianshu.com/p/0342d083e17b"最终使用:natapp !
NatApp个人免费版在注册&下载有几个细节:1. 所有的流程参考官网上的"NATAPP1分钟快速新手图文教程" 2.下载natapp.exe之后要将config.ini放在同级目录,config.ini只填写authtoken,其他几个选项默认为空即可。最终映射操作:
5.2 ME3616通信对接
这里给出完整的打开顺序,然后进行AT指令通信
5.2.1 填写Python服务器待映射的IP
5.2.2 获取映射后的IP
5.2.3 打开Python服务器,ME3616连接
打开Python服务器,按照正常的TCP流程,连接这个IP&端口
六、结束
文章到此先结束了,第2篇文章在完善GPS定位信息传入的关键字处理&分类,同时Python程序多文件调用、地图调用、Python服务器脱离编译器发布需要验证。后续第3篇文章应该就可以加入硬件处理了(三轴、电池取电方式、PCB画板、最终安装&应用)。