这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32WBA55CG开发板评测】6、ADC上报之微信小程序

共6条 1/1 1 跳转至

【STM32WBA55CG开发板评测】6、ADC上报之微信小程序

助工
2024-12-12 22:23:27     打赏


ADC采集部分请参见:https://forum.eepw.com.cn/thread/388424/1

一、首先在原来ADC采集的基础上规范下数据格式

1、定义一个16字节的数组

uint8_t four_ADC_UpdateCharData[16];

上报数据一次报16字节,而不是之前分4次每次上传4个字节


第一个4字节第二个4字节第三个4字节第四个4字节
模拟参考电压GPIO PA7输入电压采集内部参考电压1.2v片内温度传感器

2、重新编写了数据格式化函数


void formatSendData(uint32_t x,uint8_t pos)
{
uint8_t i;
a_ADC_UpdateCharData[0] = (x >> 24) & 0xFF;  // 最高有效字节
a_ADC_UpdateCharData[1] = (x >> 16) & 0xFF;
a_ADC_UpdateCharData[2] = (x >> 8) & 0xFF;
a_ADC_UpdateCharData[3] = x & 0xFF;          // 最低有效字节
for(i=0;i<4;i++)
{
four_ADC_UpdateCharData[pos*4+i]=a_ADC_UpdateCharData[i];
}
}

3、调用formatSendData函数,最后全部数据写入16字节数组


//Notification
formatSendData(uhADCxConvertedData_VrefAnalog_mVolt,0);//模拟参考电压
formatSendData(uhADCxConvertedData_VoltageGPIO_mVolt,1);//GPIO PA7输入电压采集
formatSendData(uhADCxConvertedData_VrefInt_mVolt,2);//内部参考电压1.2v
formatSendData(hADCxConvertedData_Temperature_DegreeCelsius,3);//片内温度传感器
update_ADC_data_to_char(four_ADC_UpdateCharData);

4、update_ADC_data_to_char

/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/
void update_ADC_data_to_char(uint8_t *updateData)
{
tBleStatus result = BLE_STATUS_INVALID_PARAMS;
SERVICE1_Data_t msg_conf;
msg_conf.p_Payload=updateData;
msg_conf.Length=16;//sizeof(updateData);
result = SERVICE1_UpdateValue(SERVICE1_ADCCHAR, &msg_conf);
if( result != BLE_STATUS_SUCCESS )
{
LOG_INFO_APP("Sending of Report Map Failed error 0x%X\n", result);
}
}
/* USER CODE END FD_LOCAL_FUNCTIONS*/

数据准备完毕可以开始微信小程序的编写。

二、小程序

小程序涉及json、html、css、js的编写,如果熟悉前端很容易上手。

关于BLE小程序编写,建议参考:

1、微信官方的:https://developers.weixin.qq.com/miniprogram/dev/framework/device/ble.html

2、https://esp-document.icce.top/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%BC%80%E5%8F%91/18%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%A2%9E%E5%8A%A0%E8%93%9D%E7%89%99%E9%80%9A%E4%BF%A1%E5%8A%9F%E8%83%BD.html


1、将涉及BLE的部分做成一个组件方便调用

如下bluetooth-comp部分,这部分如何建立请参考前面2个参考连接。

image.png

index.js内容:

// components/bluetooth-comp/index.js
function inArray(arr, key, val) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i][key] === val) {
            return i;
        }
    }
    return -1;
}
// 将字符串转为 ArrayBuffer
function str2ab(str) {
    let buf = new ArrayBuffer(str.length);
    let bufView = new Uint8Array(buf);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}
function intToArrayBuffer(int) {
    // 将整数转换为十六进制字符串
    let hexStr = int.toString(16);
    // 计算需要的字节数,如果十六进制字符串长度为奇数,需要补0以确保字节对齐
    let byteLength = (hexStr.length + (hexStr.length % 2 === 0 ? 0 : 2)) / 2;
    // 创建一个与计算出的字节长度相同的新的ArrayBuffer对象
    let buffer = new ArrayBuffer(byteLength);
    let dataView = new DataView(buffer);
    // 将十六进制字符串中的每个字节转换为无符号8位整数,并写入到ArrayBuffer中
    for (let i = 0; i < hexStr.length; i += 2) {
        let byte = parseInt(hexStr.substr(i, 2), 16); // 将每两个字符转换为一个字节的整数
        dataView.setUint8(i / 2, byte); // 将整数写入ArrayBuffer的适当位置(注意这里假设了整数是按大端序排列的)
    }
    return buffer; // 返回生成的ArrayBuffer对象
}
Component({
    behaviors: ['wx://component-export'],
    /**
     * 组件的属性列表
     */
    properties: {
    },
    /**
     * 组件的初始数据
     */
    // bluetooth-comp/index.js
    data: {
        devices: [],
        connected: false,
        chs: [],
    },
    /**
     * 组件的方法列表
     */
    // bluetooth-comp/index.js
    methods: {
        triggerParentFunction(value) {
            console.log("发送自定义事件");
            this.triggerEvent('customEvent', {
                message: value
            });
        },
        /* 初始化蓝牙模块 */
        openBluetoothAdapter() {
            // 先关闭蓝牙模块再开启 防止断开后点连接连接不上
            this.closeBluetoothAdapter();
            wx.openBluetoothAdapter({
                success: response => {
                    console.log("初始化蓝牙模块成功:openBluetoothAdapter", response);
                    this.startBluetoothDevicesDiscovery();
                },
                fail: err => {
                    if (err.errCode === 10001) {
                        /* 监听蓝牙适配器状态变化事件 */
                        wx.onBluetoothAdapterStateChange(res => {
                            console.log("监听蓝牙适配器状态变化事件:onBluetoothAdapterStateChange", res);
                            res.available && this.startBluetoothDevicesDiscovery();
                        });
                    }
                },
            });
        },
        /* 获取本机蓝牙适配器状态 */
        getBluetoothAdapterState() {
            wx.getBluetoothAdapterState({
                success: res => {
                    console.log("getBluetoothAdapterState", res);
                    if (res.discovering) {
                        // 是否正在搜索设备
                        this.onBluetoothDeviceFound();
                    } else if (res.available) {
                        // 蓝牙适配器是否可用
                        this.startBluetoothDevicesDiscovery();
                    }
                },
            });
        },
        /* 开始搜寻附近的蓝牙外围设备 */
        startBluetoothDevicesDiscovery() {
            // 开始扫描参数
            if (this._discoveryStarted) return;
            this._discoveryStarted = true;
            wx.startBluetoothDevicesDiscovery({
                allowDuplicatesKey: true,
                success: response => {
                    console.log("开始搜寻附近的蓝牙外围设备:startBluetoothDevicesDiscovery", response);
                    this.onBluetoothDeviceFound();
                },
                fail: err => {
                    console.log("搜索设备失败", err);
                    wx.showToast({
                        title: "搜索设备失败",
                        icon: "none"
                    });
                },
            });
        },
        /* 停止搜寻附近的蓝牙外围设备。*/
        stopBluetoothDevicesDiscovery() {
            console.log("停止搜寻附近的蓝牙外围设备");
            wx.stopBluetoothDevicesDiscovery();
        },
        /* 监听搜索到新设备的事件 */
        onBluetoothDeviceFound() {
            wx.onBluetoothDeviceFound(res => {
                res.devices.forEach(device => {
                    if (!device.name && !device.localName) {
                        return;
                    }
                    const foundDevices = this.data.devices;
                    const idx = inArray(foundDevices, "deviceId", device.deviceId);
                    const data = {};
                    if (idx === -1) {
                        data[`devices[${foundDevices.length}]`] = device;
                    } else {
                        data[`devices[${idx}]`] = device;
                    }
                    this.setData(data);
                });
            });
        },
        /* 连接蓝牙低功耗设备。*/
        createBLEConnection(e) {
            const ds = e.currentTarget.dataset;
            const deviceId = ds.deviceId;
            const name = ds.name;
            wx.createBLEConnection({
                deviceId,
                success: () => {
                    this.setData({
                        connected: true,
                        name,
                        deviceId
                    });
                    wx.showToast({
                        title: "连接蓝牙设备成功",
                        icon: "none"
                    });
                    this.getBLEDeviceServices(deviceId);
                },
                fail: e => {
                    console.log("连接失败", e.errMsg);
                    wx.showToast({
                        title: "连接失败,错误信息: " + e.errMsg,
                        icon: "none"
                    });
                },
            });
            // 停止搜寻蓝牙设备
            this.stopBluetoothDevicesDiscovery();
        },
        /* 断开与蓝牙低功耗设备的连接。 */
        closeBLEConnection() {
            console.log("断开与蓝牙低功耗设备的连接");
            wx.showToast({
                title: "已断开和蓝牙设备的连接",
                icon: "none"
            });
            wx.closeBLEConnection({
                deviceId: this.data.deviceId
            });
            this.setData({
                connected: false,
                chs: [],
                canWrite: false
            });
        },
        /* 获取蓝牙低功耗设备所有服务 (service) */
        getBLEDeviceServices(deviceId) {
            wx.getBLEDeviceServices({
                deviceId,
                success: res => {
                    for (let i = 0; i < res.services.length; i++) {
                        if (res.services[i].isPrimary) {
                            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
                            return;
                        }
                    }
                },
            });
        },
        /* 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)。 */
        getBLEDeviceCharacteristics(deviceId, serviceId) {
            wx.getBLEDeviceCharacteristics({
                deviceId,
                serviceId,
                success: res => {
                    console.log("获取蓝牙低功耗设备某个服务中所有特征:getBLEDeviceCharacteristics");
                    for (let i = 0; i < res.characteristics.length; i++) {
                        let item = res.characteristics[i];
                        if (item.properties.read) {
                            wx.readBLECharacteristicValue({
                                deviceId,
                                serviceId,
                                characteristicId: item.uuid
                            });
                        }
                        if (item.properties.write) {
                            this.setData({
                                canWrite: true
                            });
                            this._deviceId = deviceId;
                            this._serviceId = serviceId;
                            this._characteristicId = item.uuid;
                            //   this.writeBLECharacteristicValue();
                        }
                        if (item.properties.notify || item.properties.indicate) {
                            wx.notifyBLECharacteristicValueChange({
                                deviceId,
                                serviceId,
                                characteristicId: item.uuid,
                                state: true,
                                success(res) {
                                    console.log("notifyBLECharacteristicValueChange success", res);
                                },
                            });
                        }
                    }
                },
                fail(res) {
                    console.error("getBLEDeviceCharacteristics", res);
                },
            });
            // 操作之前先监听,保证第一时间获取数据
            wx.onBLECharacteristicValueChange(characteristic => {
                // TODO 收到的信息为ArrayBuffer类型,可根据自己的需要转换 可发送给父组件用来回显
                console.log("收到原始的数据", characteristic, characteristic.value, characteristic.characteristicId);
                if (characteristic.characteristicId == "00000002-0000-1000-8000-00805F9B34FB") {
                    console.log("特征值正确");
                    this.triggerParentFunction(characteristic.value);
                }
                // 测试向设备发送数据
                // this.writeBLECharacteristicValue(JSON.stringify({"FAN":"OFF"}))
            });
        },
        /* 向蓝牙低功耗设备特征值中写入二进制数据 */
        writeBLECharacteristicValue(jsonStr) {
            let arrayBufferValue = str2ab(jsonStr);
            console.log("发送数据给蓝牙", "原始字符串", jsonStr, "转换arrayBuffer", arrayBufferValue);
            wx.writeBLECharacteristicValue({
                deviceId: this._deviceId,
                serviceId: this._serviceId, // 微信文档上是错误的
                characteristicId: this._characteristicId,
                value: arrayBufferValue, // 只能发送arrayBuffer类型数据
                success(res) {
                    console.log("消息发送成功", res.errMsg);
                    wx.showToast({
                        title: "消息发送成功",
                        icon: "none"
                    });
                },
                fail(e) {
                    i
                    console.log("发送消息失败", e);
                    i
                    wx.showToast({
                        title: "发送消息失败,错误信息: " + e.errMsg,
                        icon: "none"
                    });
                },
            });
        },
        /* 向蓝牙低功耗设备特征值中写入十进制数据 */
        writeBLECharacteristicValue1(i) {
            let arrayBufferValue = intToArrayBuffer(i);
            console.log("发送数据给蓝牙", "原始字符串", i, "转换arrayBuffer", arrayBufferValue);
            wx.writeBLECharacteristicValue({
                deviceId: this._deviceId,
                serviceId: this._serviceId, // 微信文档上是错误的
                characteristicId: this._characteristicId,
                value: arrayBufferValue, // 只能发送arrayBuffer类型数据
                success(res) {
                    console.log("消息发送成功", res.errMsg);
                    wx.showToast({
                        title: "消息发送成功",
                        icon: "none"
                    });
                },
                fail(e) {
                    console.log("发送消息失败", e);
                    wx.showToast({
                        title: "发送消息失败,错误信息: " + e.errMsg,
                        icon: "none"
                    });
                },
            });
        },
        closeBluetoothAdapter() {
            console.log("关闭蓝牙模块");
            wx.closeBluetoothAdapter();
            this._discoveryStarted = false;
        },
    }
})


   

   其中,下面代码负责对收到的notify数据进行处理:

1、所有的notify数据都在前面的代码中,被手机订阅

2、所以手机可以收到所有ble设备的notfiy,通过判断characteristicId,看是否是期待的ADC数据

3、如果是,调用triggerParentFunction函数,向上级模块发送事件及数据,提醒上级处理。

// 操作之前先监听,保证第一时间获取数据
    wx.onBLECharacteristicValueChange(characteristic => {
        // TODO 收到的信息为ArrayBuffer类型,可根据自己的需要转换 可发送给父组件用来回显
        console.log("收到原始的数据", characteristic, characteristic.value, characteristic.characteristicId);
        if (characteristic.characteristicId == "00000002-0000-1000-8000-00805F9B34FB") {
            console.log("特征值正确");
            this.triggerParentFunction(characteristic.value);
        }
    });


 triggerParentFunction调用自定义事件函数:

triggerParentFunction(value) {  
            console.log("发送自定义事件");  
            this.triggerEvent('customEvent', {  
                message: value  
            });  
        },


2、新建一个自己的page

image.png

STM32WBA55CG.wxml文件内容如下,这部分语法类似于HTML,定义一个页面


<!--pages/WBA55/STM32WBA55CG.wxml-->
<view class="volt-view vn1"><text class="volt-name ">模拟参考:</text><text class="volt-text ">{{VrefAnalogvolt}}V</text></view>
<view class="volt-view vn2"><text class="volt-name ">输入电压:</text><text class="volt-text ">{{VoltageGPIO}}V</text></view>
<view class="volt-view vn3"><text class="volt-name ">内部参考:</text><text class="volt-text ">{{refvolt}}V</text></view>
<view class="volt-view vn4"><text class="volt-name ">芯片温度:</text><text class="volt-text  ">{{Temperature_DegreeCelsius}}°C</text></view>
<view><bluetoothcomp id="bluetoothid"  bind:customEvent="handleCustomEvent"></bluetoothcomp></view>


STM32WBA55CG.wxss文件内容如下,这部分是样式,类似于CSS


/* pages/WBA55/STM32WBA55CG.wxss */
.volt-view{  height: 156rpx; display: block; box-sizing: border-box;  margin-top: 10rpx;  }
.volt-name{  font-size:32pt;  color:azure;  padding-left:20rpx;}.vn1{  background-color:blue;  }.vn2{  background-color:green;  }.vn3{  background-color: rgb(250, 29, 0);}
.vn4{  background-color:indigo;}
.volt-text{  padding-left: 20rpx;  font-size:32pt;  color:azure;  font-family:sans-serif; }

STM32WBA55CG.json如下,说明包括前面自定义的BLE组件

{  "usingComponents": {
    "bluetoothcomp":"/components/bluetooth-comp/index"  }}


STM32WBA55CG.js是控制部分:

// pages/WBA55/STM32WBA55CG.js

Page({
  /**   * 页面的初始数据   */  
data: {    
message:[],    
VrefAnalogvolt:0.000,    
VoltageGPIO:0.000,    
refvolt:0.000,    
Temperature_DegfreeCelsius:0, 
 },
  /**   * 生命周期函数--监听页面加载   */  onLoad(options) {
  },
  /**   * 生命周期函数--监听页面初次渲染完成   */  onReady() {
  },
  /**   * 生命周期函数--监听页面显示   */  onShow() {
  },
  /**   * 生命周期函数--监听页面隐藏   */  onHide() {
  },
  /**   * 生命周期函数--监听页面卸载   */  onUnload() {
  },
  /**   * 页面相关事件处理函数--监听用户下拉动作   */  onPullDownRefresh() {
  },
  /**   * 页面上拉触底事件的处理函数   */  onReachBottom() {
  },
  /**   * 用户点击右上角分享   */  onShareAppMessage() {
  },  
handleCustomEvent(e) {    
console.log("收到自定义事件");    
console.log(e.detail.message); // 输出 "Hello from child"    // 可以在这里调用父级的其它函数   // this.data.message=e.detail.message;   
 let dataView = new DataView(e.detail.message);    
console.log(dataView.getInt32(0, false));    
console.log(dataView.getInt32(4, false));    
console.log(dataView.getInt32(8, false));   
console.log(dataView.getInt32(12, false));    
this.setData({VrefAnalogvolt:dataView.getInt32(0, false)/1000});   
this.setData({VoltageGPIO:dataView.getInt32(4, false)/1000});   
this.setData({VrefInt:dataView.getInt32(8, false)/1000});   
this.setData({Temperature_DegreeCelsius:dataView.getInt32(12, false)});
  
  }})

handleCustomEvent(e) 是接收到自定义的BLE组件的消息事件的处理函数。

e.detail.message为蓝牙NOTIFY的16字节数据,

使用dataView.getInt32将数据解析为4个数字,

this.setData更新成员变量,界面随之自动更新。



三、运行效果

模拟参考和温度数据是对的,中间两个数据处理部分可能还要调一调:

3.jpg




关键词: STM32WBA55CG     评测    

专家
2024-12-13 00:21:09     打赏
2楼

感谢楼主分享


菜鸟
2024-12-13 04:57:22     打赏
3楼

66666


专家
2024-12-13 05:06:03     打赏
4楼

学习一下


工程师
2024-12-13 09:19:20     打赏
5楼

666666


菜鸟
2024-12-15 17:00:21     打赏
6楼

感谢分享


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]