当前位置: 首页 > news >正文

Renesa Version Board开发RT-Thread 之Client(WIFI)和上位机的数据传输

目录

概述

1 系统框架

1.1  模块介绍

1.1 Version-Board 开发板

1.1.1 Vision-Board简介

1.1.2 Vision-Board的资源

1.2 框架介绍

2 上位机App

2.1 UI设计

 2.2 代码实现

3 功能测试

3.1 网络连接

3.2 功能测试


概述

本文主要Renesa Version Board开发RT-Thread 之Client,使用C#语言开发一个上位机App实现Server功能。Renesa Version Board将Sensor数据(温度和湿度数据,环境光照数据, SR04 测量距离)通过WIFI上传给上位机。上位机将这些数据通过UI呈现出来。

1 系统框架

硬件实物图:

软件运行UI图:

1.1  模块介绍

1) 温湿度传感器: SHT20 采集环境温度和湿度数据

2)光照传感器: ISL2003S 采集环境光照数据

3)超声波测距传感器:SR04 测量距离

4) OLED 显示屏: 实时显示温度、湿度、光照和距离参数

关于这些模块的应用程序设计,参考如下文章: 

Renesa Version Board开发RT-Thread 之I2C驱动应用(ISL29035)_rt-thread i2c-CSDN博客

Renesa Version Board开发RT-Thread 之超声波测距模块(HC-SR04)-CSDN博客

Renesa Version Board开发RT-Thread 之I2C驱动应用(OLED)_rt-thread软件实现i2c-CSDN博客

Renesa Version Board开发RT-Thread 之I2C驱动应用(SHT20)-CSDN博客

1.1 Version-Board 开发板

1.1.1 Vision-Board简介

Vision-Board 开发板是 RT-Thread 推出基于瑞萨 Cortex-M85 架构 RA8D1 芯片,为工程师们提供了一个灵活、全面的开发平台,助力开发者在机器视觉领域获得更深层次的体验。

Vision Board搭载全球首颗 480 MHz Arm Cortex-M85芯片,该芯片拥有Helium和TrustZone技术的加持。官方提供的SDK包里集成了OpenMV机器视觉例程,配合MicroPython 解释器,使其可以流畅地开发机器视觉应用。

1.1.2 Vision-Board的资源

Vision-Board基于瑞萨R7FA8D1BH MCU设计,存储器:板卡搭载8M Bytes容量的Flash, 32M Bytes RAM。还支持摄像头接口,LCD接口。通信接口主要是WIFI。   

该板块自带DAP-LINK,无需外接调试器,使用一条USB线即可开发,这一点对于开发者非常友好。

其具体资源列表如下:

板卡正面资源信息:

板卡反面资源信息:

1.2 框架介绍

如下三个模块挂载到Renesa Version Board 的I2C接口上

1) 温湿度传感器

2)光照传感器

3) OLED 显示屏

IO通用接口:

SR04超声波测模块挂载到IO接口上,通过MCU内部的定时器和IO的 外部中断测出距离数据

 WIFI接口

Renesa Version Board  自带WIFI通信模块,这里只需使能该模块,然后建立Socket通信Client, 上位机实现Server功能。

Renesa Version Board  WIFI模块使用方法,可参考文章: 

Renesa Version Board开发RT-Thread 之WIFI创建Client-CSDN博客

2 上位机App

2.1 UI设计

上位机实现功能如下:

1) 上位机实现Server功能,Renesa Version Board 实现 Client功能,二者之间通过WIFI网络通信

2) 上位机实时显示Renesa Version Board 上传的Sensor数据,包括温度,湿度,光照,和距离

3)上位机可以配置小车的操作模块:手动模式/自动模式

4)在手动模式下,可以通过button控制小车的运行状态。

 上位机使用C#语言编写,其UI框架如下:

 2.2 代码实现

1) 使用C# WINFrom框架设计UI 

2)功能代码实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace RT_ThreadApp
{public partial class MianWindows : Form{Socket sokWatch = null;         //负责监听 客户端段 连接请求的  套接字Thread threadWatch = null;      //负责 调用套接字, 执行 监听请求的线程ManualResetEvent allDone = new ManualResetEvent(false);Boolean b_watchCilent = false;   //使能监听Boolean b_connectSuccess = false;Boolean b_ClosingTCP = false;Boolean b_ListeningTCP = false;String uid = "RT_Thread";public MianWindows(){InitializeComponent();}private void MianWindows_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;var array = LOCALIpAddress.GetSpecifiedIpAddress(AddressFamily.InterNetwork);cbx_SerIP.Items.AddRange(array);if (cbx_SerIP.Items.Count >= 1){cbx_SerIP.SelectedIndex = 0;}radioButton_manual.Checked = true;}private void btn_Connect_Click(object sender, EventArgs e){//实例化 套接字 (ip4寻址协议,流式传输,TCP协议)sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建 ip对象IPAddress address = IPAddress.Parse(cbx_SerIP.Text.Trim());//创建网络节点对象 包含 ip和portIPEndPoint endpoint = new IPEndPoint(address, int.Parse(tbx_ServerPort.Text.Trim()));cbx_SerIP.Enabled = false;tbx_ServerPort.Enabled = false;try{//将 监听套接字  绑定到 对应的IP和端口sokWatch.Bind(endpoint);//设置 监听队列 长度为10(同时能够处理 10个连接请求)sokWatch.Listen(10);threadWatch = new Thread(StartWatch);threadWatch.IsBackground = true;threadWatch.Start();b_watchCilent = true;rtb_RecMonitor.AppendText("启动服务器成功......\r\n");btn_Connect.Enabled = false;btn_disConnect.Enabled = true;b_ListeningTCP = true;b_ClosingTCP = false;}catch (Exception ex){Console.WriteLine(ex.Message);}}/// <summary>/// 被线程调用 监听连接端口/// </summary>void StartWatch(){while (b_watchCilent){try{allDone.Reset();sokWatch.BeginAccept(new AsyncCallback(AcceptCallback), sokWatch);allDone.WaitOne();}catch (Exception ex){Console.WriteLine(ex.Message);}}}public Dictionary<string, StateObject> dictConnL = new Dictionary<string, StateObject>();public void AcceptCallback(IAsyncResult ar){try{allDone.Set();Socket listener = (Socket)ar.AsyncState;Socket handler = listener.EndAccept(ar);StateObject state = new StateObject();state.workSocket = handler;handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);MonitorShowMsg(handler.RemoteEndPoint.ToString() + ":" + "连接成功", true);}catch (Exception ex){Console.WriteLine(ex.Message);}}void MonitorShowMsg(string str, Boolean flag){string dStr;DateTime day = DateTime.Now;dStr = "【" + day.Date.ToShortDateString() + "  " + day.ToLongTimeString() + "】" + "  " + str + "\r\n";if (flag)   //接受区监控{rtb_RecMonitor.Text += dStr;}else{rtb_RecMonitor.Text += dStr;}}public void ShowMsg(string msgStr){rtb_RecMonitor.AppendText(msgStr + "\r\n");}public void EndAcceptCallBack(IAsyncResult ar){threadWatch.Abort();Socket lenter = (Socket)ar.AsyncState;Socket handler = lenter.EndAccept(ar);handler.Dispose();lenter.Dispose();sokWatch.Dispose();sokWatch = null;}public void ReadCallback(IAsyncResult ar){try{String content = String.Empty;StateObject state = (StateObject)ar.AsyncState;Socket handler = state.workSocket;int DataLength = handler.EndReceive(ar);byte[] TempBuff = new byte[DataLength];string str_recv = "";string[] str_Msg;Buffer.BlockCopy(state.buffer, 0, TempBuff, 0, TempBuff.Length);if (DataLength > 0){if (!dictConnL.ContainsKey(uid)){dictConnL.Add(uid, state);}else{dictConnL[uid] = state;}handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);// 显示logString str = DateTime.Now.ToString();str_recv = System.Text.Encoding.ASCII.GetString(state.buffer);ShowMsg(str + " " + str_recv);// 显示数据str_Msg = str_recv.Split(',');textBox_humidity.Text = str_Msg[0];textBox_temp.Text = str_Msg[1];textBox_lux.Text = str_Msg[2];textBox_SR40.Text = str_Msg[3];Console.WriteLine(str_Msg);}}catch (Exception ex){Console.WriteLine(ex.Message);}}private void send_wifi_Cmd(byte cmd ){byte mode = 0;byte[] cmdList = { cmd ,0};if (radioButton_manual.Checked){mode = 0x02;}else if (radioButton_auto.Checked){mode = 0x01;}cmdList[1] = mode;SendCmdBuf(dictConnL, uid, cmdList, cmdList.Length);}private void btn_disConnect_Click(object sender, EventArgs e){cbx_SerIP.Enabled = true;tbx_ServerPort.Enabled = true;Net_Disconnect();dictConnL.Clear();}private void button_up_Click(object sender, EventArgs e){byte cmd;cmd = 0x01;send_wifi_Cmd( cmd );}private void button_left_Click(object sender, EventArgs e){byte cmd;cmd = 0x03;send_wifi_Cmd(cmd);}private void button_stop_Click(object sender, EventArgs e){byte cmd;cmd = 0x05;send_wifi_Cmd(cmd);}private void button_right_Click(object sender, EventArgs e){byte cmd;cmd = 0x04;send_wifi_Cmd(cmd);}private void button_down_Click(object sender, EventArgs e){byte cmd;cmd = 0x02;send_wifi_Cmd(cmd);}private void Net_Disconnect(){try{if (b_watchCilent){if (sokWatch != null){b_ListeningTCP = false;b_connectSuccess = false;b_watchCilent = false;btn_Connect.Enabled = true;btn_disConnect.Enabled = false;sokWatch.Dispose();sokWatch.Close();GC.Collect();foreach (var v in dictConnL){v.Value.workSocket.Close();}}}rtb_RecMonitor.Clear();}catch (Exception ex){Console.WriteLine(ex.Message);}}public void SendCmdBuf(Dictionary<string, StateObject> dic, string UID, byte[] sendbyte, int length){try{if (b_ListeningTCP){Send(dic[UID].workSocket, sendbyte, length);}}catch (Exception ex)  {Console.WriteLine(ex.Message);}}private void Send(Socket handler, byte[] data, int length){try{if (b_ListeningTCP)handler.BeginSend(data, 0, length, 0, new AsyncCallback(SendCallback), handler);}catch (Exception ex){Console.WriteLine(ex.Message);}}private void SendCallback(IAsyncResult ar){try{Socket handler = (Socket)ar.AsyncState;int bytesSent = handler.EndSend(ar);}catch (Exception ex){Console.WriteLine(ex.Message);}}private void radioButton_auto_CheckedChanged(object sender, EventArgs e){if (radioButton_auto.Enabled){button_up.Enabled = false;button_down.Enabled = false;button_left.Enabled = false;button_right.Enabled = false;button_stop.Enabled = false;send_wifi_Cmd(0);}}private void radioButton_manual_CheckedChanged(object sender, EventArgs e){button_up.Enabled = true;button_down.Enabled = true;button_left.Enabled = true;button_right.Enabled = true;button_stop.Enabled = true;}}public class LOCALIpAddress{/// <summary>/// 获取指定地址族的ip地址/// </summary>/// <param name="addressFamily"></param>/// <returns></returns>public static IPAddress[] GetSpecifiedIpAddress(AddressFamily addressFamily){var addressList = GetIpAddresses();var ipv4Addresses = addressList.Where(x => x.AddressFamily == addressFamily).ToArray();return ipv4Addresses;}/// <summary>/// 获取本机的所有ip地址/// </summary>/// <returns></returns>public static IPAddress[] GetIpAddresses(){var hostName = Dns.GetHostName();var hostEntry = Dns.GetHostEntry(hostName);return hostEntry.AddressList;}/// <summary>/// 获取指定地址族的第一个ip地址/// </summary>/// <param name="addressFamily"></param>/// <returns></returns>public static IPAddress GetFirstSpecifiedIpAddress(AddressFamily addressFamily){var addressList = GetIpAddresses();var ipv4Address = addressList.First(x => x.AddressFamily == addressFamily);return ipv4Address;}}public class StateObject{// Client socket.     public Socket workSocket = null;// Size of receive buffer.     public const int BufferSize = 1024 * 1024 * 5;// Receive buffer.     public byte[] buffer = new byte[BufferSize];// Received data string.     public StringBuilder sb = new StringBuilder();}
}

3 功能测试

3.1 网络连接

1)编译和运行上位机,点击监听按钮,等待Client连接

2)启动Version board下位机, 连接网络

 当出现如下信息,说明Version board  client已经连接上Server

3.2 功能测试

1)数据上传和UI展示

2)App发送控制命令给Version Board

测试项一: 选择手动模式后,控制按键不能操作

测试项二:

选择手动模式后,可通过发送控制命令给下位机, Version Board也能正确的接收到这些命令

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何使用小乌龟清除认证缓存、还原版本、定位及常用开发工具集成
  • 中间件解析漏洞
  • 领衔登榜!凯伦股份入选2024年度市级工业设计中心名单
  • 【弱监督时间动作定位】Probabilistic Vision-Language Representation for WSTAL 论文阅读
  • VBA进行excel坐标转换
  • JavaScript 条件分支语句if...else
  • 内核链表
  • Python作为客户端连接websocket
  • Webview Android性能优化
  • html+css网页设计 合十文化2个页面
  • adb remount Now reboot your device for settings to take effect
  • 中间件解析漏洞(附环境搭建教程)
  • 俄国留学生vs国内计算机本硕博
  • 基于STM32设计的智能安防系统(微信小程序)(218)
  • WPF 中常用 `Transform` 类的介绍、使用示例和适用场景
  • Asm.js的简单介绍
  • download使用浅析
  • ES2017异步函数现已正式可用
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Js基础知识(四) - js运行原理与机制
  • miaov-React 最佳入门
  • Promise面试题,控制异步流程
  • Service Worker
  • 分布式事物理论与实践
  • - 概述 - 《设计模式(极简c++版)》
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 爬虫模拟登陆 SegmentFault
  • 前端之React实战:创建跨平台的项目架构
  • 区块链共识机制优缺点对比都是什么
  • 如何学习JavaEE,项目又该如何做?
  • 进程与线程(三)——进程/线程间通信
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • $().each和$.each的区别
  • $GOPATH/go.mod exists but should not goland
  • $jQuery 重写Alert样式方法
  • (11)MATLAB PCA+SVM 人脸识别
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (4)事件处理——(7)简单事件(Simple events)
  • (C#)获取字符编码的类
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .Net Core中Quartz的使用方法
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 快速重构概要1
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @Valid和@NotNull字段校验使用
  • [023-2].第2节:SpringBoot中接收参数相关注解
  • [2016.7 test.5] T1
  • [2019红帽杯]Snake