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也能正确的接收到这些命令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1523041.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

与MySQL邂逅

MySQL安装捏~ 其实每次新学一样东西&#xff0c;安装永远是一个小坎 但是小问题啦 安装MySQL要用root账户&#xff0c;安装后普通用户也可以用捏 要安装MySQL先来看第一步&#xff01; 改bug&#xff01; Centos 卸载不要的环境 先康康有木有捏&#xff1a; mariadb就是…

ElasticSearch-聚合操作

聚合的分类 aggsMetric Aggregation min, max, avg, sumstats, cardinality Bucket Aggregation terms ordertext -> fielddatarangehistogramtop_hits Pipeline Aggregation min_bucketstats_bucketpercentiles_bucketcumulative_sum 聚合的作用范围 Filter, Post Filter,…

AI智能电销机器人的优势是什么,有什么特点?

机器学习、大数据、深度学习、云计算等的发展和应用&#xff0c;机器人完成复杂专业任务的能力越来越强。智能化机器人时代的到来&#xff0c;进一步拓宽了服务机器人的应用场景和服务模式&#xff0c;人工智能机器人的问世&#xff0c;更使电销机器人进入到了电销行业。我们一…

如何禁用USB存储设备|禁用USB储存和连接手机的方法有哪些?深度解析,四招搞定!

在企业网络安全管理中&#xff0c;禁用USB存储设备和限制手机连接至关重要。这不仅可以防止数据泄露&#xff0c;还能阻止恶意软件通过外部设备入侵。 本文将为你推荐四种行之有效的方法&#xff0c;帮助你全面禁用USB存储设备和连接手机的功能&#xff0c;让企业数据安全更有…

【SpringCloud应用框架】GateWay网关

Spring Cloud Alibaba 之初识GateWay网关 文章目录 一、网关介绍二、网关对比三、GateWay基本概念&#xff1a;执行流程&#xff1a; 总结 一、网关介绍 在微服务架构中&#xff0c;一个系统会被拆分为多个微服务。如果没有网关存在&#xff0c;我们只能在客户端记录梅哥为服务…

echarts横向柱状图让Y轴的名字在柱状图上方展示

效果 代码 myEcharts(){// 基于准备好的dom&#xff0c;初始化echarts实例this.myChart echarts.init(this.$refs.rankingList);// 指定图表的配置项和数据var option { title: { }, tooltip: { trigger: axis, axisPointer: { type: shadow } }, legend: { …

中职院校智能物联网应用专业群建设方案

一、引言 随着信息技术的飞速发展&#xff0c;智能物联网&#xff08;IoT&#xff09;作为新一代信息技术的重要组成部分&#xff0c;正深刻改变着人们的生活方式、生产模式和社会形态。为积极响应国家“中国制造2025”和“智慧城市”等战略部署&#xff0c;培养适应未来社会需…

开源 AI 智能名片 S2B2C 商城小程序在社区团购中的应用与价值

摘要&#xff1a;本文探讨了开源 AI 智能名片 S2B2C 商城小程序在社区团购中的重要作用。社区团购的团长角色多元&#xff0c;包括小区店主、水站与快递站站长、宝妈等&#xff0c;其用户基础广泛。优秀团长的专业引导和良好服务至关重要&#xff0c;而开源 AI 智能名片 S2B2C …

YOLOv8改进实战 | 引入混合局部通道注意力模块MLCA(2023轻量级)

YOLOv8专栏导航:点击此处跳转 前言 YOLOv8 是由 YOLOv5 的发布者 Ultralytics 发布的最新版本的 YOLO。它可用于对象检测、分割、分类任务以及大型数据集的学习,并且可以在包括 CPU 和 GPU 在内的各种硬件上执行。 YOLOv8 是一种尖端的、最先进的 (SOTA) 模型,它建立在以前…

YoloV8 single channel train + Onnx trans

yolov8目前不支持单通道图片训练&#xff0c;需要修改后才能支持。本文将介绍如何修改yolov8代码&#xff0c;来训练单通道图的yolov8模型&#xff0c;以及使用onnx进行模型转换的简单实践。 1、修改代码 git diff ultralytics/utils/checks.py diff --git a/ultralytics/utils…

Spire.PDF for .NET【文档操作】演示:创建 PDF 文档

通过代码创建 PDF 文档具有多种优势。例如&#xff0c;您可以轻松合并动态内容&#xff0c;如用户输入、数据库记录或实时数据。基于代码的 PDF 生成允许更大的自定义和自动化&#xff0c;最大限度地减少创建高度定制文档时的手动干预。在本文中&#xff0c;您将学习如何使用Sp…

【陪诊系统-PC管理端】axios的二次封装

二次封装axios 引入axios创建axios实例&#xff0c;添加配置信息&#xff0c;这里主要设置基础url和请求超时时间给上述创建的实例添加拦截器&#xff0c;对请求、响应分别进行拦截 根据接口文档显示&#xff0c;当登录成功后&#xff0c;每次请求陪诊师、订单信息都需要携带t…

fastchat与autogen使用要点澄清

说明&#xff1a; 本文重点是想使用autogen构建智能体&#xff0c;并且想要通过加载本地模型来构建&#xff0c;以灵活使用。但是autogen重点是以API调用支持openai, mistral等大模型使用的&#xff0c;对于使用国内的一些模型不是那么友好方便。然后在查找方法的过程中&#x…

一篇常见第三方库之以及详细使用示例教程

作者&#xff1a;郭震 我们介绍了几个常用的 Python 第三方库,包括 NumPy、Pandas、Matplotlib 和 Requests.本篇将通过一些简单的示例来演示如何有效地使用这些库,以帮助小白理解它们的基本用法.通过这些案例,你可以直观感受到这些库在日常编程中的价值. NumPy NumPy 是一个强…

规控面试复盘

目录 前言 一、京东方 1、CPP和C的区别是什么? 2、讲一下的ROS的话题通信 二、Momenta(泊车部门实习面试) 1、MPC的预测时间步是多少? 2、MPC的代价函数考虑的是什么? 三、九识 1、智能指针有哪些优缺点? 优点: 缺点: 2、Protobuf的数据传输效率为什么更高…

【陪诊系统-PC管理端】动态路由

先说说这里为什么要使用动态路由&#xff1f; 因为前面的菜单管理功能模块中&#xff0c;可以创建或修改不同权限&#xff0c;当前登录账号可以绑定不同的权限&#xff0c;不同权限能访问的功能页面不同&#xff0c;所以使用动态路由来控制。 而登录成功后&#xff0c;服务器…

前端报文加密

前端加密功能 前端提供简单的AES对称加密算法&#xff0c;注意key 和后端网关配置相同&#xff0c;这里打包混淆后&#xff0c;相对安全。 &#xff08;lun-ui\src\store\modules\user.js、base-gateway-dev.yml&#xff09; 后端解密功能 使用hutool提供的工具类进行解密pub…

【无标题】docker-compose一键部署项目,haproxy容器代理多个web或java容器

# 创建脚本&#xff0c;可以在java环境中运行任何的jar包或者war包#!/bin/bash/usr/local/jdk/bin/java -jar /java/src/*.?ar 一、思路分析&#xff1a; &#xff08;1&#xff09;nginx 1、下载镜像&#xff0c;将本地的dist项目的目录挂载在容器的/usr/share/nginx/html/ …

连接型CRM+智能制造,助力医疗器械企业高质量发展

8月29日&#xff0c;由中国医疗器械行业协会智能制造与智慧监管分会主办&#xff0c;纷享销客参与协办的“数字化建设与智能制造助力医疗器械企业高质量发展”研讨会于苏州圆满落幕&#xff0c;国内知名医疗器械企业高层、行业专家及在医疗行业合规前沿的优秀专业人士齐聚一堂&…

【RabbitMQ】基本概念以及安装教程

1. 什么是MQ MQ( Message queue),从字面意思上看,本质是个队列,FIFO 先入先出&#xff0c;只不过队列中存放的内容是消息(message)而已.消息可以非常简单,比如只包含文本字符串,JSON等,也可以很复杂,比如内嵌对象.MQ多用于分布式系统之间进行通信 系统之间的调用通常有两种方式…