FXL - 检测温度,再通过蓝牙控制LED灯
利用编程实现测量温度参数,如果超过一定值之后通过蓝牙控制LED灯做警报
标签
显示
理工男
更新2021-02-09
785

蓝牙基本概念(功能和代码片段)

蓝牙分类(按照应用和支持协议划分)

  • 经典蓝牙模块(BT):- 泛指支持蓝牙协议在0以下的模块,一般用于数据量比较大的传输,如:语音、音乐等较高数据量传输。经典蓝牙模块可再细分为:传统蓝牙模块和高速蓝牙模块。传统蓝牙模块在2004年推出,主要代表是支持蓝牙2.1协议的模块,在智能手机爆发的时期得到广泛支持。高速蓝牙模块在2009年推出,速率提高到约24Mbps,是传统蓝牙模块的八倍,可以轻松用于录像机至高清电视、PC至PMP、UMPC至打印机之间的资料传输
  • 低功耗蓝牙模块(BLE):是指支持蓝牙协议0或更高的模块,也称为BLE模块,最大的特点是成本和功耗的降低,应用于实时性要求比较高的产品中,比如:智能家居类(蓝牙锁、蓝牙灯)、传感设备的数据发送(血压计、温度传感器)、消费类电子(电子烟、遥控玩具)等。

 

BLE分层:

FqFHsjRAMsSUafAmCCtcfWdC5lXh

 

BLE的状态以及基本连接过程:

链路层一共有5个状态,分别为就绪态(Standby),广播态(Advertsing),扫描态(Scanning),发起态(Initiating),连接态(Connection),而扫描态又分为主动扫描和被动扫描,连接态又分为主机和从机。

  • 待机状态(standby):没有连接任何设备,没有传输和发送数据。
  • 广播状态(Advertiser/advertising):周期性广播状态。
  • 扫描状态(Scanner/scanning):主动寻找正在广播的设备。
  • 发起连接状态(Initiator/initiating):主动发起连接。
  • 连接状态(connected):已经连接。

 

BLE信道:

  • BLE的物理信道一共40个
  • BLE的这40个物理信道是分成了两组的,一组是Advertising信道(3个),一组是Data信道(37个)

FkpUWqYBWA47d9XXa9jFnG8mHptr

 

BLE的广播、扫描和连接:

广播和扫描回应的数据格式

FkBxTD9Ul2n5NVBw7jN0V_pjhjix

 

用户定义广播包和扫描回应包最多能有31个字节,每个包分为有效数据和无效数数两部分。

1. 有效数据部分,由若干个AD Structure单元组成

      ◆Length:表示DATA(AD Type和AD Data)的长度,不包含Length。

      ◆AD Type:表示广播内容的类型。

      ◆AD Data:表示广播的内容。

2. 无效数据部分,广播包必须有31字节,如果有效数据部分达不到31字节,剩下所有补0.

 

广播事件分类

  • 通用广播:最常用的广播方式,可以被扫描,接收到连接请求时可以作为从设备进入一个连接。
  • 定向广播:针对于快速建立连接的需求,定向广播会占满整个广播信道,数据净荷只包含广播者和发起者地址,发起者收到发给自己的定向广播后,会立即发送连接请求。
  • 不可连接广播:广播数据,而不进入连接状态。
  • 可发现广播:不可连接,但可以响应扫描。

BLE广播间隔:是指两次广播时间之间的最小时间间隔,一般取值范围在20ms-10.24s之间,链路层会在每次广播时间期间产生一个随机广播延时时间(0ms-10ms)

 

扫描事件

每次扫描,设备打开接收器去监听广播设备,这称为一个扫描事件,扫描事件有两个时间参数:扫描窗口和扫描间隔:

  • 扫描窗口(scan window):一次扫描进行的时间宽度。
  • 扫描间隔(scan interval):两个连续的扫描窗口的起始时间之间的时间差,包括扫描休息的时间和扫描进行的时间。

FsXYGqLz8E6btjFdQD4LkOZTsNCe

 

连接事件

  • 一个连接事件是指主设备和从设备之间相互发送数据包的过程
  • 所有的数据交换都是通过连接事件来完成
  • 每个事件发生在某个数据通道(0-36)
  • 一个连接中,主从设备依靠连接事件交换数据
  • 设备连接后,无论有无数据收发,连接事件都在按照设置的连接参数周而复始的进行着,知道一方停止响应
  • 主机与从机可在单次连接事件进行多次数据传输

FgKGcd4kfFDMJlz-7jv-o-r0nMe-

 

BLE通信:

从GATT角度来看,当两个设备建立连接后,他们处于以下两种角色之一:

GATT服务器: 它是为GATT客户端提供数据服务的设备

GATT客户端: 它是从GATT服务器读写应用数据的设备

 

GATT包含若干个Profile,一个Profile包含若干个Services,一个Service包含若干个Characteristics,一个Characteristic包含Properties字段和若干个Descriptor(可选)。

GATT调用下层的ATT,ATT的attirbute在GATT中表现为Characteristic。

 

一个设备可以有多个服务,每一个服务可以包含多个特征值。为了方便操作,每个特征值都有他的属性,例如长度(size),权限(permission),值(value),描述(descriptor),比如:

FiXa9no0ANKK59zPIkrENXz8DkCs

FnN_Cqo_ZrA2FykA8DiyuRT6gZSo

 

蓝牙4.0版本推出了低功耗规范,引入了两个核心协议:ATTAttribute ProtocolGATTGeneric Attribute Protocol.这两个协议主要目标是BLE,但是也可以运行在传统蓝牙上(BR/EDR)。

 

属性协议:

决定了客户端如何获取和使用属性。

对属性的操作称为协议方法,包括:命令(Command),请求(Request),响应(Response),通知(Notification),指示(Indication)和确认(Confirmation),某些属性PDU还涉及授权签名方法。

属性PDU有六类:

属性PDU

方向

触发响应

Command

Client -> Server

Request

Client -> Server

Response

Response

Server -> Client

Notification

Server -> Client

Indication

Server -> Client

Confirmation

Confirmation

Client -> Server

属性PDU格式如下:

字段

Opcode

Parameter

Authentication Signature

长度

1 octet

0 – (ATT_MTU-X) octets

0 or 12 octets

 

客户端->>服务器: 请求(Request)

服务器->>客户端: 响应(Response)

客户端->>服务器: 命令(Command)

请求和命令的区别在于:请求需要响应,而命令不需要。

服务器->>客户端: 指示

客户端->>服务器: 确认

服务器->>客户端: 通知

通知和指示的区别在于:通知不需要确认,而指示需要。

 

 

代码片段

温度大于22度,点亮LED灯,否则关闭LED。

服务器端读取温度值,当超过22度时,向服务器写数据,点亮LED。

 

方案一:

Thunderboard(master)+BG22(slave)

修改安卓端Thunderboard源码,加入如上判断。

//获取温度同时设置是否需要点亮LED标志alarm_state

public void setTemperature(float temperature, int temperatureType) {

        if (isEnabled()) {

            textView.setText(String.format(

                    temperatureType == ThunderBoardPreferences.TEMP_FAHRENHEIT ?

                            getContext().getString(R.string.environment_temp_f) :

                            getContext().getString(R.string.environment_temp_c),

                    temperatureType == ThunderBoardPreferences.TEMP_FAHRENHEIT ?

                            temperature * 1.8f + 32f : temperature));

 

            if(temperatureType != ThunderBoardPreferences.TEMP_FAHRENHEIT ) {

 

                if (temperature > 22.0){

                    alarm_state = 1;

                }

            else{

                    alarm_state = 0;

                }

            }

        } else {

            textView.setText(R.string.environment_not_initialized);

        }

}

 

//对LED进行操作

 static public void alarm_set_led(){

        boolean submitted = BleUtils.writeCharacteristics(

                BleManager.gatt,

                ThunderBoardUuids.UUID_SERVICE_AUTOMATION_IO,

                ThunderBoardUuids.UUID_CHARACTERISTIC_DIGITAL,

                alarm_state, BluetoothGattCharacteristic.FORMAT_UINT8,

                0

        );

    }

 

//调用函数,对LED进行写0或1

public void setHallStrength(float hallStrength) {

        if (isEnabled()) {

            textView.setText(getContext().getString(R.string.environment_hall_strength_measure, hallStrength));

        } else {

            textView.setText(R.string.environment_not_initialized);

        }

 

        hallStrengthMeter.setValue(hallStrength, isEnabled());

        DemoEnvironmentTemperatureControl.alarm_set_led();

 }

 

方案二(补充):

一款国产蓝牙芯片(master)++BG22(slave)

原理同方案一类似,根据address选择连接的slave,读取温度值,超过22,写LED。

硬件平台:phyplus6212

软件平台:PHY62XX_SDK_2.1.0\example\ble_central\simpleBleCentral\

//指定要连接的蓝牙设备地址

void SimpleBLECentral_Init( uint8 task_id )

{

...

  simpleBlePeerTarget.addr[5]=0x84;

  simpleBlePeerTarget.addr[4]=0x2e;

  simpleBlePeerTarget.addr[3]=0x14;

  simpleBlePeerTarget.addr[2]=0x31;

  simpleBlePeerTarget.addr[1]=0xc3;

  simpleBlePeerTarget.addr[0]=0x4f;

}

//读取温度

bool rd_and_wr = FALSE;

static void simpleBLECentral_ReadWriteNotifyTest(void)

{

...

      if(rd_and_wr == FALSE)

      {

            pReqread = osal_mem_alloc(sizeof(attReadReq_t));

            pReqread->handle = 0x23;

            bStatus_t status = GATT_ReadCharValue( simpleBLEConnHandle, pReqread, simpleBLETaskId );

            osal_mem_free(pReqread);

      }

...

}

//温度判断

bool alarm_state = FALSE;

static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )

{

...

      curr_temp = pMsg->msg.readRsp.value[0] + ((pMsg->msg.readRsp.value[1]<<8)&0xFF00);

      LOG("current tempature:%d\n",curr_temp);

      if(curr_temp >2200)

      {

            alarm_state = TRUE;

      }

      else

      {

            alarm_state = FALSE;

      }

...

}

//点亮LED

static void simpleBLECentral_ReadWriteNotifyTest(void)

{

...

      if(rd_and_wr == TRUE)

      {

            pReq = osal_mem_alloc(sizeof(attWriteReq_t));

            pReq->sig = 0;

            pReq->cmd = 0;

            pReq->handle = 0x35;

            pReq->len = 1;

            pReq->value[0] = alarm_state;

            bStatus_t status = GATT_WriteCharValue(simpleBLEConnHandle, pReq, simpleBLETaskId);

            osal_mem_free(pReq);

      }

...

}

 

 

心得体会

总体感觉非常棒,希望类似活动能够一直搞下去。希望硬禾知名度不断扩大,更多方式盈利,给热爱电子的小伙伴带来更多好玩的东东。

微信交流群氛围很好,小伙伴们很热心,有很多大咖,知识面很广,遇到的问题也都是通过在群中沟通解决的。

虽然是一个简单的任务,但装环境,调试代码,解bug。只有参与了,才知其中滋味。

感谢硬禾,2021,一起加油!

团队介绍
FXL
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号