dql2016

  • 2021-07-26
  • 发表了主题帖: 不吹不黑,SS5是我用过的最流畅最好用的基于eclipse的IDE了

    如题,以前用过各个MCU大厂的基于eclipse的IDE,感觉不是卡顿就是不流畅,或者经常莫名奇怪卡死。。。。 SS5算是颠覆了我对eclipse的认知。。。

  • 回复了主题帖: 【Silicon Labs 开发套件评测】+资料收集

    板卡资源页面,点板卡view Documents即可看到原理图   原理图  

  • 2021-07-25
  • 发表了主题帖: 【Silicon Labs 开发套件评测】+ GPIO特点

    EFM32PG22的A、B、C、D四组管脚通过DBUS Port Mappers可以被分配给任意外设,如GPIO、I2C、SPI、UART的任意信号,这就十分灵活了,相当于管脚可以当任意功能使用,在画板的时候超级灵活,也不懂担心管脚线接反了。

  • 2021-07-23
  • 发表了主题帖: EFM32PG22的两大亮点

    我觉得M33核,16位ADC很不错。

  • 2021-07-21
  • 回复了主题帖: 打算设计一种基于WIFI和BLE的微信小程序

    okhxyyo 发表于 2021-7-21 15:15 感觉不错啊

  • 回复了主题帖: 打算设计一种基于WIFI和BLE的微信小程序

    w494143467 发表于 2021-7-21 16:30 我之前原生安卓有想过一个APP即支持BLE也支持WIFI,因为个人技术的问题没完成,不过感觉你这个想法可行。
    安卓感觉门槛高了点,光有安卓没有ios也不行

  • 回复了主题帖: 打算设计一种基于WIFI和BLE的微信小程序

    蓝雨夜 发表于 2021-7-21 15:19 微信小程序,推荐几本书呗   希望有手机与蓝牙BLE方面的例程
    腾讯官方的文档我觉得不错

  • 回复了主题帖: 为中华之崛起而读书!海南满分学生选择进清华造芯片

    清华的校办企业,紫光集团最近不是破产了吗?嘿嘿。学汉语言文学,考公务员。就不能更好的为人民服务吗

  • 发表了主题帖: 打算设计一种基于WIFI和BLE的微信小程序

    如题,设想是板子上(或者内置)外挂wifi和BLE蓝牙soc,平常的时候板子进入低功耗休眠,蓝牙开启广播,微信小程序通过连接到蓝牙后唤醒板子,板子开启wifi后运行服务器,然后微信小程序切换到wifi连接服务器,从而进行控制指令发送或者是文件上传。不知道这个设想可行性如何,或者有没有更好的方案。

  • 回复了主题帖: 【测评名单公布】米尔MYS-8MMX单板计算机

    本次测评放弃

  • 2021-07-19
  • 上传了资料: USB转串口CH340驱动

  • 回复了主题帖: 基于RSL10的智能物联网学生寝室

    w494143467 发表于 2021-7-19 15:15 最近研究Mesh,比蓝牙难且高级些。以后分享出来~
    向大佬学习

  • 回复了主题帖: 基于RSL10的智能物联网学生寝室

    w494143467 发表于 2021-7-19 14:50 看了视频,是分别进行连接,刚开始在想小程序居然这么先进了。以前有尝试过用安卓程序连接多个设备,不过不 ...
    理论上是可以同时连接多个设备的,不过管理起来太麻烦了

  • 2021-07-18
  • 发表了主题帖: 基于RSL10的智能物联网学生寝室

      基于RSL10的智能物联网学生寝室   作者:dql2016   一、作品简介 学生时代修的是电子信息专业,当时有个想法就是利用所学知识构建一套自己的物联网智能家居系统(我想每个爱折腾的童鞋也许都有过类似想法吧),但由于各种原因耽搁了,正好论坛和安森美给了这样一个机会,本次作品的目的是针对学生寝室生活特点,利用安森美RSL10低功耗蓝牙芯片构建一个物联网智能寝室系统,实现若干功能节点,在控制端采用十分方便的微信小程序进行数据的监控。通过RSL10板卡组成的功能单元进行数据采集或者动作控制,在实现微信小程序监控的功能,本项目是一套简单的智能化控制学生寝室解决方案,可作为相关专业学生课程/毕业设计,亦或是安森美大学计划课件案例。本次作品制作了3个功能节点,照片如下:   二、系统框图   环境监测节点:采用RSL10-SENSE-DB-GEVK实现,充分利用板载传感器,环境光、BME680气体、压力、湿度和温度传感器,INMP522(超低噪声数字麦克风),实现对室内环境数据的采集,板卡预留的一个IO用于控制风扇开关。 照明控制节点:采用RSL10-002GEVB+扩展版实现,扩展板上有RGB灯珠,通过I2C接口RGB恒流驱动芯片SM726EB来驱动,可实现任意颜色控制和灯泡开关。 植物管家节点:采用RSL10-002GEVB+扩展版实现,扩展板上有光敏电阻(通过AD读取数据)用于采集光照,电容式土壤湿度传感器(通过AD读取数据)用于采集土壤湿度,直流小水泵(通过IO控制)用于浇水。 用电管理节点:采用RSL10-002GEVB叠加扩展板实现,扩展板板载贝岭BL0937电能计量芯片用于采集用电量和电流电压有效值参数,继电器用于控制输出断电。 健康管理节点:预留,这个界面功能十分丰富,可以添加多种常见健康测量装置,如心率、血氧、体脂等。后续有时间慢慢研究完善。   三、部分功能说明 环境监测节点:在本节点中RSL10是外网设备实现GATT Server,提供一个自定义服务,该服务包含2个特征值,一个具有通知权限和可读权限,另外一个具有可写权限,周期性采集数据后,将数据以数据包的形式用通知发送给微信小程序(中央设备,实现GATT Client),数据包长度为10字节,依次是温度(1byte)、湿度(1byte)、气压(2byte)、空气质量(2byte) 、光照(2byte)、声音(2byte)。微信小程序节点功能界面提供对采集数据的显示以及图表分析功能以及可以通过采集数据判断自动/手动方式控制风扇开启通风。 RSL10设备端将采集的传感器数据打包发送出去: 接收到微信小程序发送的控制指令后采取的动作,主要是控制IO: 微信小程序端接收到数据进行解析: 调试过程界面如下: 照明控制节点:在本功能节点中,使用到了RSL10-002GEVB的I2C接口,在本节点中RSL10是外网设备实现GATT Server,提供一个自定义服务,该服务包含1个特征值,具有可写权限。微信小程序节点功能界面提供了一个拾色器用于用户选择颜色以及开关按钮用于控制灯泡亮灭。 RSL10设备端接收到数据后进行RGB颜色控制: 微信小程序端获得取色器结果后发送出去: 数据收发过程: 颜色控制效果: 植物管家节点:在本功能节点中,使用到了RSL10-002GEVB的一个GPIO接口(驱动三极管控制直流小水泵)和2路ADC接口(一路A0用于读取光敏电阻处电压得到光照数据,另一路A1用于读取土壤湿度传感器数据),在本节点中RSL10是外网设备实现GATT Server,提供一个自定义服务,该服务包含2个特征值,一个具有通知权限和可读权限,另外一个具有可写权限,周期性采集数据后,将数据以数据包的形式用通知发送给微信小程序(中央设备,实现GATT Client),数据包长度为4字节,依次是光照(2byte)、土壤湿度(2byte)。微信小程序节点功能界面提供了一个图标按钮用于用户控制是否开启直流小水泵进行浇水。 RSL10设备端采集2路AD数据后使用通知方式发送出去,高字节在前: RSL10设备端接收到微信小程序下发的控制数据后进行处理,主要是控制IO: 微信小程序接收到数据就进行显示,并简单判断土壤湿度状态: 用户点击浇水控制图标按钮后将发送数据给RSL10设备端: 用电管理节点:考虑到安全性仅仅设计了原型,没有通电调试。其实功能和其它节点类似,采集数据然后通知上传,接收下发控制指令控制IO控制继电器。   四、作品源码 RSL10端(包含环境监测、照明控制、植物管家3个功能节点): http://download.eeworld.com.cn/detail/dql2016/620211 微信小程序: http://download.eeworld.com.cn/detail/dql2016/620212   五、作品功能演示视频 六、项目总结 (项目文字总结+帖子分享链接汇总。) 通过本次DIY大赛活动,我熟悉了BLE蓝牙及其微信小程序蓝牙功能的开发,在此对板卡提供方安森美半导体及安富利电子、活动举办方EEWorld表示感谢。本次DIY算是完成了BLE蓝牙SoC RSL10与微信小程序之间通过蓝牙相互通信的功能,这里没有采用广播的方式进行数据的传输,而是采用写特征值、订阅通知的方法,由于时间以及本人能力有限,作品比较粗糙,敬请见谅,本项目只是简单的通过一个服务的2个特征值(一个具有读权限和通知权限,另外一个具有写权限)实现了项目的基本功能,实际产品通常会用到多个服务和多个特征值。本次项目充分利用板卡软硬件资源和手头现有硬件模块,实现了环境监测、照明控制、植物管家3个功能节点,其实这些功能都是类似的,抽象起来无非就是蓝牙设备与微信小程序之间的数据收发,不同的功能节点主要就是应用层逻辑功能不同。对于开发而言,在实现微信小程序和RSL10的数据双向收发后,我们可以利用RSL10的超级低功耗特性实现许多智能化的实用产品,例如智能体脂秤、智能水杯等对续航要求较高的产品。   帖子分享链接汇总: 资料查找RSL10-COIN-GEVB:http://bbs.eeworld.com.cn/thread-1162910-1-1.html 资料查找RSL10-SENSE-DB-GEVK:http://bbs.eeworld.com.cn/thread-1162914-1-1.html 固件下载方法:http://bbs.eeworld.com.cn/thread-1162922-1-1.html RSL10官方入门指南中的2处错误:http://bbs.eeworld.com.cn/thread-1162933-1-1.html 资料查找RSL10-002GEVB:http://bbs.eeworld.com.cn/thread-1162909-1-1.html RSL10-002GEVB蓝牙功能测试:http://bbs.eeworld.com.cn/thread-1163866-1-1.html BLE蓝牙基本概念:http://bbs.eeworld.com.cn/thread-1163878-1-1.html RSL10蓝牙SoC手机应用构建一:http://bbs.eeworld.com.cn/thread-1164284-1-1.html RSL10-SENSE-DB-GEVK测试:http://bbs.eeworld.com.cn/thread-1166273-1-1.html RSL10-002GEVB原理图的疑问:http://bbs.eeworld.com.cn/thread-1167285-1-1.html RSL10-002GEVB扩展板设计:http://bbs.eeworld.com.cn/thread-1168442-1-1.html 样板初步调试:http://bbs.eeworld.com.cn/thread-1169552-1-1.html RSL10 adc多通道数据采集:http://bbs.eeworld.com.cn/thread-1169554-1-1.html RSL10 BLE蓝牙广播:http://bbs.eeworld.com.cn/thread-1170122-1-1.html RSL10 RTE添加定时器:http://bbs.eeworld.com.cn/thread-1170272-1-1.html RSL10蓝牙特征值读写:http://bbs.eeworld.com.cn/thread-1170300-1-1.html 微信小程序与RSL10蓝牙双向通信:http://bbs.eeworld.com.cn/thread-1170400-1-1.html RSL10 合并工程后printf无法输出浮点数http://bbs.eeworld.com.cn/thread-1170823-1-1.html RSL10-SENSE-DB-GEVK环境监测节点设计:http://bbs.eeworld.com.cn/thread-1171333-1-1.html RSL10-002GEVB照明控制节点设计:http://bbs.eeworld.com.cn/thread-1172136-1-1.html RSL10-002GEVB植物管家节点设计:http://bbs.eeworld.com.cn/thread-1172725-1-1.html RSL10-002GEVB用电管理节点设计:http://bbs.eeworld.com.cn/thread-1172736-1-1.html 微信小程序设计思路:http://bbs.eeworld.com.cn/thread-1172742-1-1.html   七、其他 在实验过程中发现RSL10的许多硬件特性还是需要深入研究才能应用好的,比如我在使用中发现RSL10的GPIO驱动能力有点弱的问题,有的时候某个IO无法完成驱动换一个就好了。有的时候,似乎程序只有打开RTT调试软件才能运行,断开RTT调试软件程序就停止了。 最后感谢各位管理员和论坛网友的无私分享和奉献。 作品提交文档下载: 微信小程序: RSL10端3个功能节点程序:

  • 上传了资料: 安森美RSL10大赛程序-微信小程序

  • 上传了资料: 安森美RSL10大赛程序-RSL10端

  • 回复了主题帖: RSL10-002GEVB用电管理节点设计

    w494143467 发表于 2021-7-18 15:23 涂鸦的开发板被你用遍了~

  • 发表了主题帖: 微信小程序设计思路

    本帖最后由 dql2016 于 2021-7-18 11:04 编辑 本次项目中的重要环节之一就是微信小程序的设计,系统采集的各种传感器数据都需要送到微信小程序端显示,并进行后续的分析,逻辑控制。由于我是第一次接触小程序设计,期间踩了很多坑,不过掌握诀窍后,只要实现了一个功能的设计,其它类似功能都变得很容易了。 先来看一下系统结构图,本次项目打算设计4个功能节点,分别是照明控制节点、植物管家节点、环境监测节点、用电管理节点,各个节点的设计这里不再啰嗦,之前的帖子说明了各个功能节点的设计过程。既然微信小程序作为功能节点的数据显示和控制的人机交互界面,那么显然有什么功能节点就需要有对应的界面。这里我的设计思路是,一个界面上摆放多个功能模块,点击进去后就是对应的功能节点详细界面。然后需要有一个控制蓝牙连接的界面,方便后续对设备进行一些参数的设定,比如重命名设备(比如,一个设备可能存在多个就需要用户设定不同的名字来区分)。 微信小程序项目的结构如下,小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。一个小程序主体部分由三个文件组成,app.js小程序逻辑,app.json小程序公共配置,app.wxss小程序公共样式表,必须放在项目的根目录。一个小程序页面由四个文件组成,分别是页面逻辑xx.js,页面结构xx.wxml,页面配置xx.json,页面样式表xx.wxss,描述页面的四个文件必须具有相同的路径与文件名(不一定跟文件夹同名)。 如下图是环境监测页面的结构: 设置界面设计如下:主要由4个按钮组成。 点击搜索蓝牙设备按钮后,就开始搜索周围正在广播的蓝牙设备,并出现在蓝牙设备列表中,可以选中一个蓝牙设备进行连接。 选择蓝牙设备后,然后点击连接蓝牙设备按钮,就会去连接蓝牙设备了,一旦连接成功就会获取蓝牙设备的服务列表和特征值列表,若发现有通知权限的特征值,则会注册通知回调函数,这样一来就会收到功能节点采集的传感器数据了。设置页面的js逻辑代码如下: // pages/bluetoothconfig/bluetoothconfig.js const util = require('../../utils/util.js') var event = require('../../utils/event.js') var delayTimer; //用来控制是否持续服务发现 var isFound = false; var app = getApp() Page({ /** * 页面的初始数据 */ data: { logs: [], deviceArray: [], currDeviceID: '请选择...', currDeviceName:'', }, //屏幕打开时执行的函数 onLoad: function () { let that = this; //接收别的页面传过来的数据 event.on('EnvMonitorSendData2Device', this, function(data) { //另外一个页面传过来的data是16进制字符串形式 console.log("要发送给蓝牙设备的数据:"+data); //var buffer = new ArrayBuffer(5) var buffer=that.stringToBytes(data); var dataView = new Uint8Array(buffer) dataView = data; wx.writeBLECharacteristicValue({ deviceId: app.globalData._deviceId,//蓝牙设备 id serviceId: app.globalData._serviceId,//蓝牙特征值对应服务的 uuid characteristicId: app.globalData._writeCharacteristicId,//蓝牙特征值的 uuid value: buffer,//ArrayBuffer 蓝牙设备特征值对应的二进制值 success: function (res) {//接口调用成功的回调函数 console.log('发送成功') }, fail: function(res) {//接口调用失败的回调函数 //发送蓝牙数据失败 console.log('发送失败') } } ) }), //灯光控制页面发来的RGB数据 event.on('LightControlSendData2Device', this, function(data) { //另外一个页面传过来的data是16进制字符串形式 console.log("要发送给蓝牙设备的数据:"+data); var a=data; var b = a.indexOf("(") var c = a.indexOf(")") var d = a.substring(c,b+1)//100,200,230 var e=d.substring(0,d.indexOf(",")); console.log("分词R:"+parseInt(e,10)) var f=d.substring(d.indexOf(",")+1,d.lastIndexOf(",")+1); console.log("分词G:"+parseInt(f,10)) var g=d.substring(d.length,d.lastIndexOf(",")+1); console.log("分词B:"+parseInt(g,10)) var myrgb=this.myStringToHex(parseInt(e,10).toString(16))+this.myStringToHex(parseInt(f,10).toString(16))+this.myStringToHex(parseInt(g,10).toString(16)); console.log("myrgb:"+myrgb) //var buffer = new ArrayBuffer(5) //var dataView = new Uint8Array(buffer) var buffer=that.stringToBytes(myrgb); wx.writeBLECharacteristicValue({ deviceId: app.globalData._deviceId,//蓝牙设备 id serviceId: app.globalData._serviceId,//蓝牙特征值对应服务的 uuid characteristicId: app.globalData._writeCharacteristicId,//蓝牙特征值的 uuid value: buffer,//ArrayBuffer 蓝牙设备特征值对应的二进制值 success: function (res) {//接口调用成功的回调函数 console.log('发送成功') }, fail: function(res) {//接口调用失败的回调函数 //发送蓝牙数据失败 console.log('发送失败') } } ) }) }, onUnload: function() { event.remove('EnvMonitorSendData2Device', this); event.remove('LightControlSendData2Device', this); }, //按钮回调 clickMe: function() { wx.showModal({ title: '确定发送数据吗?', content: "01 02 03", showCancel: true, success (res) { if (res.confirm) { console.log('用户点击确定') //////////////////////////////////////////// var buffer = new ArrayBuffer(3) var dataView = new Uint8Array(buffer) dataView[0] = 1; dataView[1] = 2; dataView[2] = 3; var that =this; wx.writeBLECharacteristicValue({ deviceId: app.globalData._deviceId,//蓝牙设备 id serviceId: app.globalData._serviceId,//蓝牙特征值对应服务的 uuid characteristicId: app.globalData._writeCharacteristicId,//蓝牙特征值的 uuid value: buffer,//ArrayBuffer 蓝牙设备特征值对应的二进制值 success: function (res) {//接口调用成功的回调函数 this.printLog('发送成功') }, fail: function(res) {//接口调用失败的回调函数 //发送蓝牙数据失败 this.printLog('发送失败') } } ) ////////////////////////// } else if (res.cancel) { console.log('用户点击取消') } } }) }, bindPickerChange: function(ret){ var array = this.data.deviceArray; console.log(array[ret.detail.value]); this.setData({ currDeviceID: array[ret.detail.value] }) this.printLog("选中:" + array[ret.detail.value]); }, bleSearchEvent: function(ret){ this.initBLE(); }, bleConfigEvent: function (ret) { var deviceID = this.data.currDeviceID; console.log("选中:" + deviceID); if (util.isEmpty(deviceID) || deviceID == "请选择..."){ util.toastError("请先搜索设备"); return ; } var device = deviceID.split('['); if(device.length <= 1){ util.toastError("请先搜索设备"); return ; } var l=deviceID.split('['); this.printLog("选中蓝牙设备名字:" + l[0]); this.setData({ currDeviceName: l[0] }) var id = device[device.length - 1].replace("]", ""); console.log(id); util.toastError("连接" + id); this.createBLE(id); }, bleCloseEvent: function(ret){ var deviceId = this.data.currDeviceID; wx.showModal({ title: '确定断开设备吗?', content: deviceId, showCancel: true }) var device = deviceId.split('['); var id = device[device.length - 1].replace("]", ""); this.printLog("断开设备:[" + id+"]..."); this.closeBLE(id,null); }, initBLE: function() { this.printLog("启动蓝牙适配器, 蓝牙初始化") this.setData("启动蓝牙适配器, 蓝牙初始化") var that = this; wx.openBluetoothAdapter({ success: function(res) { console.log(res); that.findBLE(); }, fail: function(res) { util.toastError('请先打开蓝牙'); } }) }, findBLE: function() { this.printLog("打开蓝牙成功.") var that = this wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: false, interval: 0, success: function(res) { wx.showLoading({ title: '正在搜索设备', }) console.log(res); delayTimer = setInterval(function(){ that.discoveryBLE() //3.0 //这里的discovery需要多次调用 }, 1000); setTimeout(function () { if (isFound) { return; } else { wx.hideLoading(); console.log("搜索设备超时"); wx.stopBluetoothDevicesDiscovery({ success: function (res) { console.log('连接蓝牙成功之后关闭蓝牙搜索'); } }) clearInterval(delayTimer) wx.showModal({ title: '搜索设备超时', content: '请检查蓝牙设备是否正常工作,Android手机请打开GPS定位.', showCancel: false }) util.toastError("搜索设备超时,请打开GPS定位,再搜索") return } }, 15000); }, fail: function(res) { that.printLog("蓝牙设备服务发现失败: " + res.errMsg); } }) }, discoveryBLE: function() { var that = this wx.getBluetoothDevices({ success: function(res) { var list = res.devices; console.log(list); if(list.length <= 0){ return ; } var devices = []; for (var i = 0; i < list.length; i++) {    //that.data.inputValue:表示的是需要连接的蓝牙设备ID, //简单点来说就是我想要连接这个蓝牙设备, //所以我去遍历我搜索到的蓝牙设备中是否有这个ID /*var name = list.name || list.localName; if(util.isEmpty(name)){ continue; } if(name.indexOf('MI') >= 0 && list.RSSI != 0){ console.log(list); devices.push(list); }*/ var deviceId = list.deviceId; if(util.isEmpty(deviceId)){ continue; } if(list.RSSI != 0){ console.log(list); devices.push(list); } } console.log('总共有' + devices.length + "个设备需要设置") if (devices.length <= 0) { return; } that.connectBLE(devices); }, fail: function() { util.toastError('搜索蓝牙设备失败'); } }) }, connectBLE: function(devices){ this.printLog('总共有' + devices.length + "个设备需要设置") var that = this; wx.hideLoading(); isFound = true; clearInterval(delayTimer); wx.stopBluetoothDevicesDiscovery({ success: function (res) { that.printLog('搜索蓝牙设备成功之后关闭蓝牙搜索'); } }) //两个的时候需要选择 var list = []; for (var i = 0; i < devices.length; i++) { var name = devices.name || devices.localName; list.push(name + "[" + devices.deviceId + "]") } this.setData({ deviceArray: list }) //默认选择 this.setData({ currDeviceID: list[0] }) }, createBLE: function(deviceId){ var app = getApp() this.printLog("全局变量av0="+ app.globalData.av0); this.printLog("连接: [" + deviceId+"]..."); var that = this; //连接之前,先断开一下,防止设备已连接了 this.closeBLE(deviceId, function(res){ console.log("预先关闭,再打开"); setTimeout(function(){ wx.createBLEConnection({ deviceId: deviceId, success: function (res) { that.printLog("设备连接成功!"); event.emit('deviceConnectStatus',"在线"); app.globalData.deviceMac=deviceId; that.getBLEServiceId(deviceId); }, fail: function (res) { that.printLog("设备连接失败:" + res.errMsg); } }) }, 2000) }); }, //获取服务UUID getBLEServiceId: function(deviceId){ this.printLog("获取设备[" + deviceId + "]服务列表") var that = this; wx.getBLEDeviceServices({ deviceId: deviceId, success: function(res) { console.log(res); var services = res.services; if (services.length <= 0){ that.printLog("未找到主服务列表") return; } that.printLog('找到设备服务列表个数: ' + services.length); if (services.length == 1) { var service = services[0]; that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary); that.getBLECharactedId(deviceId, service.uuid); } else//多个主服务 { for(var i=0;i<services.length;i++) { if(services.uuid=="E093F3B5-00A3-A9E5-9ECA-40016E0EDC24") { var service = services; that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary); app.globalData._deviceId=deviceId; app.globalData._serviceId=service.uuid; that.getBLECharactedId(deviceId, service.uuid); } } } }, fail: function(res){ that.printLog("获取设备服务列表失败" + res.errMsg); } }) }, getBLECharactedId: function(deviceId, serviceId){ this.printLog("获取设备特征值") var that = this; wx.getBLEDeviceCharacteristics({ deviceId: deviceId, serviceId: serviceId, success: function(res) { console.log(res); //这里会获取到两个特征值,一个用来写,一个用来读 var chars = res.characteristics; if(chars.length <= 0){ that.printLog("未找到设备特征值") return ; } that.printLog("找到"+serviceId+"特征值个数:" + chars.length); if(chars.length >=1){ for(var i=0; i<chars.length; i++){ var char = chars; that.printLog("特征值[" + char.uuid + "]") var prop = char.properties; if(prop.notify == true) { that.printLog("该特征值属性: Notify"); that.recvBLECharacterNotice(deviceId, serviceId, char.uuid); } else if(prop.write == true) { that.printLog("该特征值属性: Write"); app.globalData._writeCharacteristicId=char.uuid; that.sendBLECharacterNotice(deviceId, serviceId, char.uuid); } else if(prop.read == true) { that.printLog("该特征值属性: Read"); that.sendBLECharacterNotice(deviceId, serviceId, char.uuid); } else if(prop.indicate == true) { that.printLog("该特征值属性: Indicate"); that.sendBLECharacterNotice(deviceId, serviceId, char.uuid); } else { that.printLog("该特征值属性: 其他"); } } }else{ //TODO } }, fail: function(res){ that.printLog("获取设备特征值失败") } }) }, recvBLECharacterNotice: function(deviceId, serviceId, charId){ //接收设置是否成功 this.printLog("注册Notice 回调函数"); var that = this; //设备一旦发送数据在此通道,就会立刻收到通知 wx.notifyBLECharacteristicValueChange({ deviceId: deviceId, serviceId: serviceId, characteristicId: charId, state: true, //启用Notify功能 success: function(res) { wx.onBLECharacteristicValueChange(function(res){ console.log(res); that.printLog("收到Notify数据: " + that.ab2hex(res.value)); //var app = getApp(); var tmp =that.ab2hex(res.value); //app.globalData.av0=parseInt(tmp,16); //event.emit('DataChanged',app.globalData.av0); var cdn = that.data.currDeviceName; that.printLog("当前蓝牙设备名字: " + cdn); //发送数据到其它页面 if(cdn=='环境监测') { event.emit('environmetDataChanged',tmp); } else if(cdn=='用电管理') { event.emit('energyManageDataChanged',tmp); } else if(cdn=='照明控制') { event.emit('lightControlDataChanged',tmp); } else if(cdn=='植物管家') { event.emit('plantKeeperDataChanged',tmp); } //关闭蓝牙 /*wx.showModal({ title: '配网成功', content: that.ab2hex(res.value), showCancel: false })*/ }); }, fail: function(res){ console.log(res); that.printLog("特征值Notice 接收数据失败: " + res.errMsg); } }) }, sendBLECharacterNotice: function (deviceId, serviceId, charId){ var that = this; var buffer = this.string2buffer(JSON.stringify(cell)); setTimeout(function(){ wx.writeBLECharacteristicValue({ deviceId: deviceId, serviceId: serviceId, characteristicId: charId, value: buffer, }) }, 1000); }, closeBLE: function(deviceId, callback){ var that = this; wx.closeBLEConnection({ deviceId: deviceId, success: function(res) { that.printLog("断开设备[" + deviceId + "]成功."); event.emit('deviceConnectStatus',"离线"); console.log(res) }, fail: function(res){ //that.printLog("断开设备[" + deviceId + "]失败!"); }, complete: callback//接口调用结束的回调函数(调用成功、失败都会执行) }) }, printLog: function(msg){ var logs = this.data.logs; logs.push(msg); this.setData({ logs: logs }) }, /** * 将字符串转换成ArrayBufer */ string2buffer(str) { if (!str) return; var val = ""; for (var i = 0; i < str.length; i++) { val += str.charCodeAt(i).toString(16); } console.log(val); str = val; val = ""; let length = str.length; let index = 0; let array = [] while (index < length) { array.push(str.substring(index, index + 2)); index = index + 2; } val = array.join(","); // 将16进制转化为ArrayBuffer return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) { return parseInt(h, 16) })).buffer }, /** * 将ArrayBuffer转换成字符串 */ ab2hex(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join(''); }, stringToBytes(str) { var array = new Uint8Array(str.length); for (var i = 0, l = str.length; i < l; i++) { array = str.charCodeAt(i); } console.log(array); return array.buffer; }, myStringToHex(str){ var a=''; if(str.length == 1){ a += "0" + str; } else{ a=str; }     return a.toUpperCase();// 统一大写格式输出   }, inputSSID: function(res) { var ssid = res.detail.value; this.setData({ ssid: ssid }) }, inputPASS: function(res) { var pass = res.detail.value; this.setData({ pass: pass }) } }) 设置页面的逻辑代码除了控制蓝牙连接断开外,还会接收其它页面发来的数据(发给蓝牙设备),一开始在如何实现小程序不同页面之间的通信的时候踩了许多坑,后来在github上找到了一个很好用的开源库,用类似mqtt发布订阅的方式,一个页面订阅某个topic然后注册回调函数,另一个页面直接往这个topic发数据就行了。   首页用九宫格的方式展示各个功能节点,如下图所示: 点击各个九宫格就可以跳转到对应的功能界面,如下图是环境监测功能界面:提供了温度、湿度、气压、空气质量、光照、声音6个表征环境的参数。还提供了一个按钮用于控制风扇运转,模拟通风功能。 环境监测功能界面各个图标点击后就会进入对应数据的曲线图界面(由于暂时还没有实现数据库存储采集数据的功能,这里曲线所用数据均为模拟数据):           照明控制页面提供了3个按钮,2个按钮分别独立控制寝室灯和卫生间灯,另一个图标按钮则用于控制所有灯的开关。 氛围灯的颜色控制通过一个拾色器实现,点击后弹出拾色器,选择颜色后及时将数据发送给蓝牙设备。拾色器也不是微信小程序原生的功能,这里也是使用了github上的开源库。 植物管家界面提供了土壤湿度的显示,光照的显示,以及一个按钮用于控制浇水。 用电管理界面提供了电压、电流、功率的展示,并提供一个按钮用于总电源的通断,点击图标可进入曲线统计界面,可以显示最近用电量报表。 健康管理界面目前设想的几个功能点如下,限于时间和资源原因,仅仅设计好了微信小程序原型,没有实现相应的设备端。   以上就是本次项目微信小程序各个界面的说明,其中的难点主要有3个,一是如何与蓝牙设备进行通信、读写特征值、读取通知数据、发送数据;二是不同页面间的通信,比如我在设置界面进行蓝牙数据收发,这个数据如何跟其它的页面传递;三是九宫格展示各个功能节点,点击后进入各个界面,之前一直找不到思路,直到在尝试使用echarts开源库进行曲线图表的绘制时候,发现echarts的demo就是九宫格,查看了一下源码廓然开朗。 首页九宫格实现代码主要如下:   在index.wxml中绘制图标按钮,指定回调函数open并将index.js中定义的页面id作为参数传进去。 index.js的回调函数open中就根据id跳转到指定页面,这里的id值就是各个page的名字。 以环境监测界面为例看看逻辑功能如何实现: // index.js //加载事件通知库,用于不同页面发布和订阅事件 var event = require('../../utils/event.js') var app=getApp() Page({ data: { charts: [{ id: 'wendu', name: '温度', data:'0',//温度值 unit:'℃'//温度单位 }, { id: 'shidu', name: '湿度', data:'0', unit:'%' }, { id: 'pressure', name: '气压', data:'0', unit:'' }, { id: 'air', name: 'AQI', data:'0' }, { id: 'lux', name: '光照', data:'0', unit:'Lux' }, { id: 'dmic', name: '声音', data:'0' }], /* chartsWithoutImg: [{ id: 'aa', name: '今日提醒' }, { id: 'bb', name: '移动侦测' }],*/ device_id:123, device_status:"在线",// 显示是否在线的字符串 checked: false,//风扇的状态,默认关闭 fanIcon:"/utils/img/fanOff.png",//显示风扇图标的状态,默认是关闭状态图标 }, //点击图标的回调函数,这里就触发跳转到对应的曲线图界面 open: function (e) { wx.navigateTo({ url: '../' + e.target.dataset.chart.id + '/' + 'line' }); }, //屏幕打开时执行的函数 onLoad: function () { //接收别的页面传过来的数据 event.on('deviceConnectStatus', this, function(data) { //另外一个页面传过来的data是bool console.log("蓝牙设备连接状态:"+data) this.setData({ device_status:data }); }) //接收别的页面传过来的数据 event.on('environmetDataChanged', this, function(data) { //另外一个页面传过来的data是16进制字符串形式 console.log("接收到蓝牙设备发来的数据:"+data) //温度 1byte var a=parseInt(data[0]+data[1],16); //将温度放到云数据库,供曲线图界面读取 var newarray = [{ timestamp:"10:15", v:89 }]; app.globalData.wendus.push(newarray); //湿度 1byte var b=parseInt(data[2]+data[3],16); //气压 4byte var c=parseInt(data[4]+data[5],16); var d=parseInt(data[6]+data[7],16); var e=c*256+d; //空气质量 4byte var f=parseInt(data[8]+data[9],16); var g=parseInt(data[10]+data[11],16); var h=f*256+g; //光照 4byte var i=parseInt(data[12]+data[13],16); var j=parseInt(data[14]+data[15],16); var k=i*256+j; //声音 4byte var l=parseInt(data[16]+data[17],16); var m=parseInt(data[18]+data[19],16); var n=l*256+m; //实时修改显示值 var up0 = "charts[" + 0 + "].data"; var up1 = "charts[" + 1 + "].data"; var up2 = "charts[" + 2 + "].data"; var up3 = "charts[" + 3 + "].data"; var up4 = "charts[" + 4 + "].data"; var up5 = "charts[" + 5 + "].data"; this.setData({ //wendu:app.globalData.v,//赋值全局变量 [up0]:a, [up1]:b, [up2]:e, [up3]:h, [up4]:k, [up5]:n, }); }) }, onUnload: function() { event.remove('environmetDataChanged', this); event.remove('deviceConnectStatus', this); }, //控制风扇的函数,小滑块点击后执行的函数 onChange({ detail }){ this.setData({ checked: detail, }); if(detail == true){ //发送'fefe'给蓝牙设备 开 event.emit('EnvMonitorSendData2Device','fefe'); this.setData({ fanIcon: "/utils/img/fanOn.png", }); }else{ //发送'0101'给蓝牙设备 关 event.emit('EnvMonitorSendData2Device','0101'); this.setData({ fanIcon: "/utils/img/fanOff.png", }); } }, }) 启动后注册设置页面蓝牙数据通知的回调,接收到通知数据后就解析数据,主要是注意数据格式的问题,蓝牙设置页面传过来的数据是16进制字符串形式。发送数据给蓝牙设备则是调用不同页面通信机制 event.emit('EnvMonitorSendData2Device','fefe');实现。由于各个图标点击后需要跳转到各个曲线图界面,因此这里的还是相当于一个”九宫格“。实现原理就不再赘述。  

  • 2021-07-17
  • 回复了主题帖: RSL10-002GEVB植物管家节点设计

    Jacktang 发表于 2021-7-17 20:47 楼主的植物管家还行吧,很不错 RSL10的IO驱动确实不行,比较常用的继电器模块无法驱动是个小不足 &nb ...
    是的,这个IO还是太少了,arduino接口上好几个空的

  • 回复了主题帖: 【环境专家之智能手表】Part20:作品提交

    学习了,不错

最近访客

< 1/6 >

统计信息

已有182人来访过

  • 芯币:361
  • 好友:2
  • 主题:136
  • 回复:638
  • 课时:5
  • 资源:12

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言