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

Renesa Version Board和微信小程序通信

目录

概述

1. 系统框架结构

1.1 功能介绍

1.2 系统框图

2 微信小程序开发

2.1 UI介绍

2.2  代码实现

3 功能实现

3.1 通信协议

3.2 系统测试


概述

本文主要介绍基于Renesa Version Board,采集多个传感器数据,并将这些数据通过蓝牙模块发送微信小程序上。笔者还介绍微信小程序App的源代码,并介绍app和下位机的通信协议。

1. 系统框架结构

1.1 功能介绍

Renesa Version Board实现功能:

1)读取Sensor数据

1)通过I2C和SH20温湿度传感器通信,读取该sensor上的温度和湿度值

2)通过I2C和ISL2003L光照传感器通信,读取该sensor上的lux值

3)通过IO接口读取SR04超声波测距数据

2)传输数据

Renesa Version Board通过UART接口将采集到的数据传送到STM32F103板卡,该板卡主要实现数据转发功能。

3)蓝牙模块数据传输

STM32F103板卡接收到Renesa Version Board传递的sensor数据后,对这些数据进行打包,然后将该数据包通过蓝牙接口发送出去。

4)微信小程序

微信小程序主要实现接收下位机蓝牙模块发送的数据,并对该数据包进行解析,然后通过UI将数据呈现出来。

1.2 系统框图

2 微信小程序开发

2.1 UI介绍

接收数据:

1) 显示温度和湿度数据

2) 显示光照数据

3) 显示SR04超声波测距数据

发送端数据:

通过4个按钮控制小车的行为 

2.2  代码实现

1)创建detail.wxml文件,实现UI框架

详细代码如下:

<view class="connect_box"><text class='connect_device_name'>{{deviceName}}</text><text wx:if="{{connected}}" class="connect_state" catchtap="DisConnectTap">已连接</text><text wx:else class="connect_state" catchtap="DisConnectTap" >未连接</text>
</view><view class="block-content"><view class="block-item column"><view class="item-row slider-box"><view class="item-title" ><image class="item-title-icon" src="/images/light_s.png" />温度(℃)</view><view class="input-unit"></view><view class="item-title" style="position: relative;  left: 30rpx; "><image class="item-title-icon" src="/images/light_s.png" />湿度(%)</view><view class="input-unit"></view></view><view class="item-row"><view class="input-value"><input type="digit" value="{{temphtValue}}" disabled="false"/></view><view class="input-value" style="position: relative;  left: -90rpx; "><input type="digit" value="{{humidityValue}}" disabled="false"/></view></view></view> <view class="block-item column"><view class="item-row slider-box"><view class="item-title"><image class="item-title-icon" src="/images/light_s.png" />光照(lux)</view><view class="input-unit"></view><view class="item-title" style="position: relative;  left: 60rpx; "><image class="item-title-icon" src="/images/light_s.png" />SR测距(cm)</view><view class="input-unit"></view></view><view class="item-row"><view class="input-value" ><input type="digit" value="{{luxValue}}" disabled="false"/></view><view class="input-value" style="position: relative;  left: -90rpx; "><input type="digit" value="{{srValue}}" disabled="false"/></view></view></view> <view class="block-item column" style="width: 750rpx; height: 507rpx; display: flex; box-sizing: border-box; left: 0rpx; top: 0rpx; position: relative"><button type="primary" bindtap="run_up" plain="true" style="position: relative; left: 3rpx; top: 5rpx; width: 183rpx; height: 357rpx; display: block; box-sizing: border-box">前进</button><button type="primary" bindtap="run_up" plain="true" style="position: relative; left: 0rpx; top: 263rpx; width: 188rpx; height: 326rpx; display: block; box-sizing: border-box">后退</button><button type="primary" bindtap="run_up" plain="true" style="position: relative; left: -247rpx; top: 3rpx; width: 183rpx; height: 361rpx; display: block; box-sizing: border-box">左转</button><button type="primary" bindtap="run_up" plain="true" style="position: relative; left: 256rpx; top: -82rpx; width: 183rpx; height: 343rpx; display: block; box-sizing: border-box">右转</button><button type="primary" bindtap="run_up" plain="true" style="position: relative; left: 5rpx; top: -173rpx; width: 179rpx; height: 361rpx; display: block; box-sizing: border-box">停止</button></view> 
</view>

2)样式文件

详细代码如下:

.connect_box {width: 100%;height: 30px;line-height: 30px;font-size: 32rpx;color: #666;background-color: antiquewhite;font-family: "Microsoft YaHei";
}
.connect_device_name{float: left;padding-left: 10px;color: #39beff;
}.connect_state {float: right;padding-right: 10px;text-decoration: underline;color: #39beff;
}page {min-height: 100%;}.container {height: 100%;display: flex;flex-direction: column;align-items: center;justify-content: space-between;box-sizing: border-box;background-color: cadetblue;}.block {padding: 15px;width: 100%;box-sizing: border-box;}.block-title {font-size: 20px;margin-bottom: 30px;}.block-subtitle {margin: 15px 0;font-size: 14px;color: #666;}.block-item {position: relative;display: flex;justify-content: space-between;align-items: center;margin: 15px 0;padding: 15px;font-size: 18px;border-radius: 8px;background:azure;box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.1);}.block-item:last-child {margin-bottom: 0;}.block-item.column {flex-direction: column;}.item-row {display: flex;justify-content: space-between;align-items: center;width: 100%;}.item-row + .item-row {margin-top: 10px;}.item-column {display: flex;flex-direction: column;justify-content: space-between;align-self: stretch;flex-grow: 1;}.item-title {font-size: 16px;}.item-title-icon {height: 1.2em;width: 1.2em;margin-right: 10px;vertical-align: middle;}.slider-box {flex-grow: 1;}.slider {margin-left: 10px;margin-right: 20px;flex-grow: 1;}.slider-value {display: flex;justify-content: space-around;align-items: center;margin: 15px auto;width: 70%;}.input-unit {text-align: right;font-size: 14px;color: #999;}.input-value {display: inline-block;padding: 0 16px;border: 1px solid #CCCCCC;border-radius: 4px;max-width: 3.5em;font-size: 16px;text-align: center;}

3) JS文件

详细代码如下:

const utils = require('utils.js')
const ble = require('bluetooth.js')
Page({/*** 页面的初始数据*/data: {pageload: false,connected: false,send_hex: false,send_string: true,send_string_val: 'Hex',recv_string: true,recv_string_val: 'Hex',recv_value: '',send_number: 0,recv_number: 0,recv_hex: true,try_cnt:0,rece_string:'',deviceArray: []},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {var that = this; console.log(options);this.setData({pageload:true,connected: false,deviceId: options.id,try_cnt:0,deviceName: options.name});console.log("detail:  onLoad");wx.stopBluetoothDevicesDiscovery({success: function (res) {console.log('停止搜索设备', res)}})that.closeBLEConnection(that.data.deviceId);that.createBLEConnection(that.data.deviceId, that.data.deviceName); }, onHide () {var that = this;// Do something when hide.// 断开连接console.log("detail:  onHide");},onShow:function(){      // var that = this; // connect bluetooth// that.closeBLEConnection(that.data.deviceId);// that.createBLEConnection(that.data.deviceId, that.data.deviceName); },onUnload() {var that = this;this.setData({pageload:true,connected: false,try_cnt:0,});console.log("page:  onUnload  ");that.offBLEMonitor();that.closeBLEConnection(that.data.deviceId);that.closeBluetoothAdapter();wx.showToast({title: '断开蓝牙',icon: 'success',duration: 2000})  },DisConnectTap:function(){var that = this;that.setData({pageload:true,connected: false,try_cnt:0,});ble.openBluetoothAdapter(that.data.deviceId, that.data.deviceName);that.createBLEConnection(that.data.deviceId, that.data.deviceName); },RecvCleanTap: function () {this.setData({recv_value: '',recv_number: 0});},  /*** 创建连接* @param {*} deviceId * @param {*} name */createBLEConnection(deviceId, name) {wx.createBLEConnection({deviceId,  success: (res) => {console.log('createBLEConnection - success: ', res)this.getBLEDeviceServices(deviceId)              },fail: (res) => {console.error('createBLEConnection - fail: ', res)if(res.errCode == 10006 ){this.createBLEConnection(deviceId, name)}else{ble.openBluetoothAdapter(deviceId, name)this.createBLEConnection(deviceId, name)}this.setData({connected: false,})               } })},getBLEDeviceServices(deviceId) {var that = this;wx.getBLEDeviceServices({deviceId,success: (res) => {console.log('getBLEDeviceServices - success: ', res)for (let i = 0; i < res.services.length; i++) {var ergodic_UUID =res.services[i].uuid;      //取出服务里面的UUIDvar UUID_slice = ergodic_UUID.slice(4, 8);   //截取4到8位console.log('getBLEDeviceServices, service ID =  ', res.services[i].uuid);if ( res.services[i].isPrimary && (UUID_slice == "FFE0") ) {that.setData({serviceId: res.services[i].uuid,});break;}}wx.getConnectedBluetoothDevices({services: res.services,success: (res) => {                         console.log("getConnectedBluetoothDevices - success:  " +  res)},fail: (res) => {console.error('getConnectedBluetoothDevices - fail: ', res)ble.openBluetoothAdapter(deviceId, that.data.deviceName)}                    })that.getBLEDeviceCharacteristics(deviceId, that.data.serviceId);},fail: (res) => {console.error('getBLEDeviceServices - fail: ', res)// try it againble.openBluetoothAdapter(deviceId, that.data.deviceName)that.monitor_connected();} });},getBLEDeviceCharacteristics(deviceId, serviceId) {var that = this;let falg = false;wx.getBLEDeviceCharacteristics({deviceId,serviceId,success: (res) => {that.setData({connected: true,})                console.log('getBLEDeviceCharacteristics success', res.characteristics)for (let i = 0; i < res.characteristics.length; i++) {let item = res.characteristics[i]console.log('getBLEDeviceCharacteristics, Characteristics ID =  ', item.uuid)// 该特征值:可读if (item.properties.read) {wx.readBLECharacteristicValue({deviceId,serviceId,characteristicId: item.uuid,})}// 该特征值:可写if (item.properties.write) {this.setData({canWrite: true})this._deviceId = deviceIdthis._serviceId = serviceIdthis._characteristicId = item.uuidthis.writeValue()}if (item.properties.notify || item.properties.indicate) {that.setData({characteristicId: item.uuid});falg = true;break;}}if( falg ){console.debug('getBLEDeviceCharacteristics - deviceId : ', deviceId)console.debug('getBLEDeviceCharacteristics - serviceId : ', serviceId)console.debug('getBLEDeviceCharacteristics - characteristicId: ', that.data.characteristicId)// read device character value that.readBLECharacteristicValue(deviceId, serviceId, that.data.characteristicId)   that.notifyBLECharacteristicValueChange(deviceId, serviceId, that.data.characteristicId) }},fail: (res) => {console.error('getBLEDeviceCharacteristics -- fail: ', res)this.setData({connected: false,})if (res.errCode === 10006){that.offBLEMonitor();that.createBLEConnection(deviceId, that.data.deviceName); }}})},readBLECharacteristicValue(deviceId,serviceId, characteristicId ){wx.readBLECharacteristicValue({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId,success (res) {console.log('readBLECharacteristicValue:', res.errCode)}})},notifyBLECharacteristicValueChange(deviceId,serviceId, characteristicId ){var that = this;wx.notifyBLECharacteristicValueChange({state: true,    // enable notifydeviceId,serviceId,characteristicId,success: (res) => {console.info('notifyBLECharacteristicValueChange success: ', res.errMsg)// read data here // 操作之前先监听,保证第一时间获取数据wx.onBLECharacteristicValueChange(function(res) {that.data.connected = true; console.info('onBLECharacteristicValueChange', res);console.info(`characteristic ${res.characteristicId} has changed, now is ${res.value}`);var result = res.value;var hex = utils.buf2hex(result);var _hex_ss =  utils.hex2string(hex);console.info("hex: " + hex);console.info("string: " + _hex_ss);that.data.rece_string += _hex_ss;var recv_number_1 = that.data.recv_number + _hex_ss.length / 2;var recv_number = Math.round(recv_number_1);if( that.data.rece_string.includes("log:") && that.data.rece_string.includes(":end")){that.setData({recv_number: recv_number,recv_value: that.data.recv_value + that.data.rece_string,});console.info("string: " + that.data.rece_string);let buff =  that.data.rece_string.split(':')console.log(buff)that.data.rece_string = ''let valueList = buff[1].split(',')that.data.recv_value = "";that.data.recv_number = 0;console.log(valueList)if(valueList.length == 4 ){that.setData({temphtValue: valueList[0],humidityValue: valueList[1],luxValue: valueList[2],srValue: valueList[3],});} }     that.monitor_connected();})                                 },fail: (res) => {console.error('notifyBLECharacteristicValueChange fail: ', res)that.monitor_connected();}})    },monitor_connected_action(){var that = this;let deviceId = that.data.deviceId;wx.onBLEConnectionStateChange(function(res) {// 该方法回调中可以用于处理连接意外断开等异常情况console.log( "onBLEConnectionStateChange ----- " +  `device ${res.deviceId} state has changed, connected: ${res.connected}`)if( res.deviceId == deviceId && res.connected == false ){    wx.closeBLEConnection({deviceId,success: (res) => {console.debug('detail: closeBLEConnection success', res);  that.offBLEMonitor();that.createBLEConnection(deviceId, that.data.deviceName); },fail: (res) => {                     console.error('detail: closeBLEConnection fail', res);  if (res.errCode === 10006) {that.offBLEMonitor();that.createBLEConnection(deviceId, that.data.deviceName); }}})that.setData({try_cnt: that.data.try_cnt + 1,})}else{that.data.try_cnt  = 0;}})   },monitor_connected(){var that = this;setTimeout(that.monitor_connected_action, 200);},writeValue( val ) {// 向蓝牙设备发送一个0x00的16进制数据let buffer = new ArrayBuffer(1);let dataView = new DataView(buffer);dataView.setUint8(0, val);console.debug('getBLEDeviceCharacteristics - deviceId : ', this._deviceId)console.debug('getBLEDeviceCharacteristics - serviceId : ', this._serviceId)console.debug('getBLEDeviceCharacteristics - characteristicId: ', this._characteristicId)wx.writeBLECharacteristicValue({deviceId: this._deviceId,serviceId: this._serviceId,characteristicId: this._characteristicId,value: buffer,success: (res) => {console.debug('writeBLECharacteristicValue success', res);  },fail: (res) => {console.error(' writeBLECharacteristicValue fail', res);  this.setData({connected: false,}) }})},closeBluetoothAdapter() {wx.closeBluetoothAdapter({           success (res) {console.log(res)}        })this.setData({connected: false,}),         this._discoveryStarted = false},closeBLEConnection( deviceId ) {wx.closeBLEConnection({deviceId,success: (res) => {console.debug('detail: closeBLEConnection success', res);  },fail: (res) => {console.error('detail: closeBLEConnection fail', res);  }})this.setData({connected: false,canWrite: false,})},run_up:function(){var that = this;var val = 0x18 ;      that.writeValue( val );   }, run_down:function(){var that = this;var val = 0x52;      that.writeValue( val );   },run_left:function(){var that = this;var val = 0x08;      that.writeValue( val );   },run_right:function(){var that = this;var val = 0x5a;      that.writeValue( val );   },whiteLightValueSliderChange:function(e){var that = this;// 向蓝牙设备发送一个0x00的16进制数据var val = Math.random() * 255 | 0;      that.writeValue( val );   },offBLEMonitor(){this.setData({connected: false,}), wx.offBLEPeripheralConnectionStateChanged();wx.offBLEConnectionStateChange();wx.offBLECharacteristicValueChange();wx.offBLEMTUChange();}
})

3 功能实现

3.1 通信协议

发送数据协议如下:

log: %d,%d,...,%d:end

Demo log如下:

log:25.07,60.69,1312,172.76:end

微信小程序log 调试信息

微信小程序端解析数据方法:

代码第313行: 判断数据包的头(log:)和尾部(:end)

代码第320行:解析字符串

3.2 系统测试 

 调试log信息,解析到下位机上传的数据

App上数据显示信息

 

 系统硬件框图:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ubuntu设置为自己需要的屏幕分辨率
  • Unity3D DOTS Component详解
  • IDEA主题的设置
  • 前端数据结构
  • C++学习笔记(4)
  • 贪心算法---不同路径
  • sicp每日一题[1.42]
  • SpringBoot整合Thymleaf实现页面静态化
  • 【数据结构】—— 栈与队列
  • 【Prometheus】Prometheus的特点、数据采集方式、架构、数据模型详解
  • 4、Django Admin对自定义的计算字段进行排序
  • MacOS上升级Ruby版本
  • 儿童护眼大路灯怎么选择?5款儿童护眼落地灯分享
  • Maven介绍
  • 正则表达式优化建议
  • hexo+github搭建个人博客
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 自己简单写的 事件订阅机制
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • [译]Python中的类属性与实例属性的区别
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 2017年终总结、随想
  • Docker: 容器互访的三种方式
  • EOS是什么
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Javascript弹出层-初探
  • javascript面向对象之创建对象
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Laravel 实践之路: 数据库迁移与数据填充
  • Leetcode 27 Remove Element
  • Objective-C 中关联引用的概念
  • 汉诺塔算法
  • 解析 Webpack中import、require、按需加载的执行过程
  • 强力优化Rancher k8s中国区的使用体验
  • 问题之ssh中Host key verification failed的解决
  • 详解NodeJs流之一
  • 一个项目push到多个远程Git仓库
  • 智能合约Solidity教程-事件和日志(一)
  • puppet连载22:define用法
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • # windows 安装 mysql 显示 no packages found 解决方法
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #if等命令的学习
  • #java学习笔记(面向对象)----(未完结)
  • (02)Hive SQL编译成MapReduce任务的过程
  • (160)时序收敛--->(10)时序收敛十
  • (2)(2.10) LTM telemetry
  • (2)nginx 安装、启停
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)
  • (原)Matlab的svmtrain和svmclassify
  • (转)大道至简,职场上做人做事做管理
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • *算法训练(leetcode)第三十九天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离