1 Star 10 Fork 7

小贝比/蓝牙转WIFI计步上位机

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

蓝牙转WIFI计步上位机

1. 设计简介

本上位机采用.NET平台下的WPF实现一个MPU6050数据从蓝牙从机——>蓝牙主机——>WIFI的UDP接收数据传输并可视化的功能。

1.1 运行环境

.Net平台下的WPF。VS2019(需安装C#支持的环境)。拿到源码打开 BluetoothPC.sln 运行正常即可。

设计了一个很好看的UI图标:)

2. 设计流程

2.1 设计框架

前台XAML的UI设计不过多介绍,主要看设计需求,逃不开模板、触发器、动画、样式之类的技术。

后台C#在UI主线程下开了三个子线程:

  1. UDP数据监听接收线程。
  2. 三轴数据UI更新线程。
  3. 计步和进度条数据更新线程。

因没有碰到多个线程访问同一个UI控件或写同一个UI控件,所以没用到锁,但内部加了异步延迟,让UI更新顺滑一些。

2.2 服务器连接设计

UDP端IP地址和端口号需正常且有效,加了错误弹窗,若出现下图请重新输入:

2.3 三轴加速度显示

有硬件:成功连接上之后需配合底层硬件,这里是接收UDP发过来的3轴加速度值。

无硬件:如果没有硬件也行,自行找个网络调试助手,开个UDP服务,本机连接就行,发送的数据需包含以下格式:

  • 任意字符(:1.23938 mG)任意字符。

解释:发送过来的数据必须包含在 :xxxx mG 内,冒号mG不能少,可任意多组,每组代表一轴数据。

2.4 计步显示

利用三轴加速度提供的数据处理步数。需打开左下角计步控制按钮。打开后弹出提示:

本计步算法仅支持手臂摆动的峰峰值计步,若有更好的算法请分享,万分感谢!!!

计步程序如下

/*
 * valueNum - 存放三轴数据(x,y,z)的个数
 * tempValue - 用于存放计算阈值的波峰波谷差值的数组(在这个方法里存放值数组长度为5)
 * isDirectionUp - 是否上升的标志位
 * continueUpCount - 持续上升的次数
 * continueUpFormerCount - 上一点的持续上升的次数,为了记录波峰的上升次数
 * lastStatus - 上一点的状态,上升还是下降
 * peakOfWave - 波峰值
 * valleyOfWave - 波谷值
 * timeOfThisPeak - 此次波峰的时间
 * timeOfLastPeak - 上次波峰的时间
 * timeOfNow - 当前的时间
 * gravityOld - 上次传感器的值
 * initialValue - 动态阈值需要动态的数据,这个值用于这些动态数据的阈值,这个值是由大量数据得来的
 * ThreadValue - 初始阈值,这个值是由大量数据得来的
 * minValue - 初始最小值 计算出来的xyz数值乘重力加速度(9.8),此为手机拿在手里(不摆臂)(由自己多次测试得出的值)
 * maxValue - 初始最大值 自己设定的最大值(我们定位2)乘重力加速度(9.8),此为手机拿在手里(不摆臂)(由自己多次测试得出的值)
 * g - 重力加速度(9.8)
 * thisSteps 步数
*/

	    private int valueNum = 5;
        //private double[] tempValue;
        private List<double> tempValue = new List<double>();
        private Boolean isDirectionUp = false;
        private int continueUpCount = 0;
        private int continueUpFormerCount = 0;
        private Boolean lastStatus = false;
        private double peakOfWave = 0;
        private double valleyOfWave = 0;
        private double timeOfThisPeak = 0;
        private double timeOfLastPeak = 0;
        private double timeOfNow = 0;
        private double gravityOld = 0;
        private double initialValue = 1.7;
        private double ThreadValue = 2.0;
        private double minValue = 11;
        private double maxValue = 19.6;
        private double g = 9.8;
        private double thisSteps = 0;   //当前步数

        private double StepsCopy = 0;   //步数复制


		/// <summary>
        /// 监测新的步数 如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
        /// 符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
        /// </summary>
        /// <param name="_values">加速传感器三轴的平均值</param>
        public void detectorNewStep(double _values)
        {
            if (gravityOld == 0)
            {
                gravityOld = _values;
            }
            else
            {
                if (detectorPeak(_values, gravityOld))
                {
                    timeOfLastPeak = timeOfThisPeak;
                    timeOfNow = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
                    //时间差大于200ms,小于2s
                    if (((timeOfNow - timeOfLastPeak) >= 200) && ((timeOfNow - timeOfLastPeak) <= 2000) && ((peakOfWave - valleyOfWave) >= ThreadValue))
                    {
                        timeOfThisPeak = timeOfNow;
                        //增加步数
                        thisSteps++;
                        //增加步数复制
                        StepsCopy++;
                    }
                    if(((timeOfNow - timeOfLastPeak) >= 200) && ((peakOfWave - valleyOfWave) >= initialValue))
                    {
                        timeOfThisPeak = timeOfNow;
                        double _diffWaveVal = peakOfWave - valleyOfWave;
                        ThreadValue = peak_Valley_Thread(_diffWaveVal);
                    }
                }
                gravityOld = _values;
            }
        }
        /// <summary>
        /// 监测波峰
        /// 以下四个条件判断为波峰
        /// 1.目前点为下降的趋势:isDirectionUp为false
        /// 2.之前的点为上升的趋势:lastStatus为true
        /// 3.到波峰为止,持续上升大于等于2次
        /// 4.波峰值大于minValue,小于maxValue
        /// 记录波谷值
        /// 1.观察波形图,可以发现在出现步子的地方,波谷的下一个就是波峰,有比较明显的特征以及差值
        /// 2.所以要记录每次的波谷值,为了和下次的波峰作对比
        /// </summary>
        /// <param name="_newValue"></param>
        /// <param name="_oldValue"></param>
        /// <returns></returns>
        public Boolean detectorPeak(double _newValue, double _oldValue)
        {
            lastStatus = isDirectionUp;
            if (_newValue >= _oldValue)
            {
                isDirectionUp = true;
                continueUpCount++;
            }
            else
            {
                continueUpFormerCount = continueUpCount;
                continueUpCount = 0;
                isDirectionUp = false;
            }

            if (!isDirectionUp && lastStatus && (continueUpFormerCount >= 2 && (_oldValue >= minValue && _oldValue < maxValue)))
            {
                //满足上面波峰的四个条件,此时为波峰状态
                peakOfWave = _oldValue;
                return true;
            }
            else if (!lastStatus && isDirectionUp)
            {
                //满足波谷条件,此时为波谷状态
                valleyOfWave = _oldValue;
                return false;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 阈值的计算
        /// 1.通过波峰波谷的差值计算阈值
        /// 2.记录4个值,存入tempValue[] 数组中
        /// 3.在将数组传入函数averageValue中计算阈值
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public double peak_Valley_Thread(double _value)
        {
            double _tempThread = ThreadValue;
            List<double> _tempValue = new List<double>(tempValue);
            if (tempValue.Count < valueNum)
            {
                tempValue.Add(_value);
            }
            else
            {
                //tempValue数组长度=valueNum=5
                _tempThread = averageValue(tempValue);

                _tempValue.RemoveAt(0);
                _tempValue.Add(_value);
                tempValue = _tempValue;
            }
            return _tempThread;
        }
        /// <summary>
        /// 梯度化阈值
        /// 1.计算数组的均值
        /// 2.通过均值将阈值梯度化在一个范围里
        /// 这些数据是通过大量的统计得到的
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public double averageValue(List<double> _value)
        {
            if (_value.Count != 0)
            {
                double _ave = 0;
                foreach (double i in _value)
                    _ave += i;
                _ave = _ave / _value.Count;
                if(_ave >= 8)
                {
                    _ave = 4.3;
                }
                else if (_ave >= 7 && _ave < 8)
                {
                    _ave = 3.3;
                }
                else if (_ave >= 4 && _ave < 7)
                {
                    _ave = 2.3;
                }
                else if (_ave >= 3 && _ave < 4)
                {
                    _ave = 2.0;
                }
                else
                {
                    _ave = 1.7;
                }
                return _ave;
            }
            else
            {
                return 1.7;
            }
        }

计步效果如下所示:

开启步数控制按钮后总步数累加,进度条进度为50步,每到达50步距离弹出提示框,计步结束也弹提示框通知。

2.5 倾力UI按钮设计

设计了一组拟物化按钮,目前无任何功能,有需要的小伙伴自行更改设计功能。

3. 总结

本上位机是课程设计的一个附属品,有需要的小伙伴拿去改改,望点个star <- .->!

空文件

简介

这是一个WIFI上位机,接收底层MPU6050数据,途中转蓝牙从机透传,到蓝牙主机直连WIFI,PC端UDP通信,实现三轴加速度数据传送和计步功能。 展开 收起
取消

发行版 (1)

全部

蓝牙转WIFI计步上位机 开源评估指数

productivity 生产力
niche_creation 创新力
robustness 稳健性
collaboration 协作
contributor 贡献者
software 软件

贡献者 (1)

全部

近期动态

3年前推送了新的提交到 master 分支,e421465...024c440
接近4年前推送了新的 UDP计步上位机v1.0 标签
接近4年前推送了新的 master 分支
接近4年前创建了仓库
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/tytokongjian/StepCountingUpperPC.git
git@gitee.com:tytokongjian/StepCountingUpperPC.git
tytokongjian
StepCountingUpperPC
蓝牙转WIFI计步上位机
master

搜索帮助