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

使用Renesas R7FA8D1BH (Cortex®-M85)和微信小程序App数据传输

目录

概述

1 系统架构

1.1 系统结构 

1.2 系统硬件框架结构

 1.3 蓝牙模块介绍

2 微信小程序实现

2.1 UI介绍

2.2  代码实现

3 上位机功能实现

3.1 通信协议

3.2 系统测试 

 4 下位机功能实现

 4.1 功能介绍

4.2 代码实现

4.3 源代码文件

5 测试

5.1 编译和下载代码

5.2 App上数据显示的UI


概述

本文主要介绍设计一个系统实现如下功能:使用Renesas R7FA8D1BH (Cortex®-M85)和微信小程序App数据传输。笔者介绍了系统设计的架构,包括硬件架构,软件架构,以及上位机的实现代码。并在下位机实现数据发送功能,App正确的解析数据,并通过UI显示数据的功能。

1 系统架构

1.1 系统结构 

功能介绍

使用Renesas R7FA8D1BH (Cortex®-M85)的UART端口,与蓝牙模块通信,将数据包发送出去,上位机使用基于微信小程序编写的App,上位机接收到数据之后,解析数据包,并显示在UI上。

1.2 系统硬件框架结构

1)数据采集部分

SHT20:  温湿度传感器,采集环境温度和湿度

ISL29035:  光照传感器,采集环境的光照强度

DS18B20: 高精度温度传感器,设备工作环境温度监测

ADC(Temperatre): MCU内部温度监测

ADC(可调电阻): 模拟数据输入

2)显示部分

OLED: 实时显示传感器的数据 

3)模式切换

KEY-UP:  物理按键,正方向切换UI

KEY-DOWM:  物理按键,反方向切换UI

4)数据传输部分

 使用蓝牙模块发送数据包,该数据包会被微信小程序接收

 1.3 蓝牙模块介绍

       HC-08蓝牙串口通信模块是新一代的基于Bluetooth Specification V4.0 BLE 蓝牙协议的数传模块。无线工作频段为 2.4GHz ISM,调制方式是 GFSK。模块最大发射功率为4dBm,接收灵敏度-93dBm,空旷环境下和 手机可以实现 80 米超远距离通信。

        其和MCU之间通过串口通信,软件设计也简单便捷,且不需要考虑蓝牙协议栈问题,非常适合做速成产品。

蓝牙模块与MCU之间连接图:

2 微信小程序实现

2.1 UI介绍

接收数据:

1) 显示温度和湿度数据

2) 显示光照数据

3 ) 显示MCU内部温度数据

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信息,解析到下位机上传的数据

 4 下位机功能实现

 4.1 功能介绍

1)系统上电之后,首先初始化MCU的资源

2)初始化外围资源,包括各类sensor

3)  实时读取传感器的数据

4)实时通过蓝牙模块上传数据

4.2 代码实现

1) 发送数据接口

代码48行: 判断字符串是否发送完毕

代码51行:使用串口发送数据

2)发送数据函数

代码67行:格式化数组

代码75行:格式化发送数据

代码77行:发送数据

3)实时获取数据函数

代码36行: 读取DS18B20数据

代码47~48行:读取SHT20数据

代码50行:读取ISL29035的数据

代码52~53行: Mcu内部数据

代码55~61行:打包传感器数据

代码65行:上传数据

 

4.3 源代码文件

 获取和传输数据函数

void app_getSensorDataPacket( void )
{static int sec;rtc_time_t get_time;float humidity;float temperature;unsigned int luxValue;uint16_t adc_ch1_value;float adc_temp_value;bool result;result = ds18b20NoBlockingProcess();//DS18B20 if( result ){stru_SensorData.ds18b20_value = st_ds1b20val.temperatureVal;}user_get_currentRtc(&get_time);if( get_time.tm_sec != sec  ){sec = get_time.tm_sec;sht2x_get_humidy(&humidity);sht2x_get_temperature(&temperature);IsL29035_read_lux( &luxValue );adc_basic_get_value( &adc_ch1_value );adc_basic_get_temperature( &adc_temp_value );stru_SensorData.humidity =  humidity;stru_SensorData.temperature = temperature;stru_SensorData.luxValue =  luxValue;// mcu  internel adc and temperature stru_SensorData.mcuTemp_value = adc_temp_value*100;stru_SensorData.adc_RawCnt =  adc_ch1_value;// send log to appbluetooth_sengLog();}
}

蓝牙模块核心应用程序

 /*FILE NAME  :  app_bluetooth.cDescription:  app UIAuthor     :  tangmingfei2013@126.comDate       :  2024/06/03*/
#include "app_bluetooth.h"
#include "app_main.h" 
#include "bluetooth.h" #define PROT_FRAME_LEN       16Stru_BlueCmd stru_BlueCmd;static uint8_t recv_buf[PROT_FRAME_LEN];
static uint8_t rev_cnt = 0;void bluetoothCmd_DataRecvByte(uint8_t data )
{recv_buf[rev_cnt++] =  data;if( rev_cnt >= PROT_FRAME_LEN)rev_cnt = 0;// bluetooth commandstru_BlueCmd.recStatus +=1;if( stru_BlueCmd.recStatus > PROT_FRAME_LEN )stru_BlueCmd.recStatus = 0;if( rev_cnt >= 2 ){rev_cnt = 0;stru_BlueCmd.mcmd = recv_buf[0];stru_BlueCmd.mode = recv_buf[1];}}static void SendInterface(uint8_t* pu8_buf, uint16_t u16_len )
{r_sci_b_uart1_sendArry(pu8_buf, u16_len);
}static void bluetooth_sendString( uint8_t *ss )
{uint8_t buff[2];uint8_t index = 0;while ( ss[index]!='\0' ){buff[0]= ss[index];SendInterface(buff, 1);index++;}
}void bluetooth_sengLog( void )
{static uint8_t step = 0;Struc_SensorPack *pSensorData;uint8_t dataBuff[128];pSensorData = &stru_SensorData;switch( step ){default:case 0:memset((char*)dataBuff, '\0', sizeof(dataBuff));//sprintf((char*)dataBuff, "log:%d,%.2f,", pSensorData->luxValue,pSensorData->sr_value);// bluetooth_sendString( dataBuff );step = 1;break;case 1://memset((char*)dataBuff, '\0', sizeof(dataBuff));sprintf((char*)dataBuff, "log:%.2f,%.2f,%d,%.2f:end", pSensorData->temperature*0.01, pSensorData->humidity*0.01, pSensorData->luxValue,pSensorData->mcuTemp_value*0.01);bluetooth_sendString( dataBuff );step = 0;break;}
}/* End of this file */

5 测试

5.1 编译和下载代码

编译和下载代码

5.2 App上数据显示的UI


http://www.mrgr.cn/news/32902.html

相关文章:

  • 大模型终极指南:零基础到精通,一文搞定!
  • Qt窗口——对话框
  • 61. 旋转链表【 力扣(LeetCode) 】
  • MySQL数据库备份与恢复
  • 库函数模块创建
  • 9.安卓逆向-安卓开发基础-安卓四大组件2
  • C++11标准模板(STL)- 常用数学函数 - 计算e的给定幂 (ex)(std::exp, std::expf, std::expl)
  • hadoop大数据平台操作笔记
  • 酒桌上有三种人,从来不敬酒,反而不能小瞧,他们智商很高
  • JavaWeb_Servlet 学习指南
  • 小时候看的多啦A梦中的哪些是与人工智能相关的道具,现在已经实现了
  • React组件如何暴露自身的方法
  • TestDeploy v3.0构思
  • Hadoop的安装和使用
  • 数据库系统基础概述
  • linux操作系统的基本命令
  • javascript数组的常用方法汇总
  • python-SZ斐波那契数列/更相减损数
  • [数据结构]动态顺序表的实现与应用
  • 怎么制作视频教程?新手速成剪辑教程来袭