battery service 修改 52832
来源:互联网 发布:东莞大朗淘宝电商培训 编辑:程序博客网 时间:2024/05/24 04:53
实现 battery 特征值的添加函数,这里电池服务实现是定时周期使用notify方式将电量发送给手机,所以通信方式是跟nus服务中的rx特征值一样的,所以直接拷贝ble_nus.c中的rx_char_add 函数做一下简单修改就可以了
static uint32_tbattery_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init)
{
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_t attr_md;
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.notify = 1;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = &cccd_md;
char_md.p_sccd_md = NULL;
ble_uuid.type = p_nus->uuid_type;
//替换uuid
ble_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 1;
memset(&attr_char_value, 0,sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = BLE_NUS_MAX_RX_CHAR_LEN;
//替换存储 特性的结构体指针
returnsd_ble_gatts_characteristic_add(p_nus->service_handle,
&char_md,
&attr_char_value,
&p_nus->rx_handles);
}
然后修改ble_nus.c中的
uint32_tble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) 函数 添加 电池特特性创建的函数调用
uint32_t ble_nus_init(ble_nus_t * p_nus,const ble_nus_init_t * p_nus_init)
{
…………………………
…………………………
…………………………
// Add the TX Characteristic.
err_code = tx_char_add(p_nus, p_nus_init);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
//添加电池特性创建服务的调用
err_code =battery_char_add(p_nus, p_nus_init);
if (err_code!= NRF_SUCCESS)
{
returnerr_code;
}
return NRF_SUCCESS;
}
然后实现 电池电量的发送函数。直接拷贝ble_nus.c中的ble_nus_string_send函数并作如下修改。
uint32_t battery_send(ble_nus_t* p_nus, uint8_t*battery_level,uint16_t length)
{
ble_gatts_hvx_params_t hvx_params;
if (p_nus == NULL)
{
return NRF_ERROR_NULL;
}
//去掉是否使能notify的标记判断,因为这里用的是电池通道,
//本来也应该想rx一样做一个是否notify过的标志,例子里为了方便就
//没做
if (p_nus->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
if (length > BLE_NUS_MAX_DATA_LEN)
{
return NRF_ERROR_INVALID_PARAM;
}
memset(&hvx_params, 0,sizeof(hvx_params));
hvx_params.handle =p_nus->battery_handles.value_handle;
hvx_params.p_data =battery_level;
hvx_params.p_len = &length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
returnsd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
}
之后再创建一个定时器来定时发送电量值
app_timer_create(&battery_timer,APP_TIMER_MODE_REPEATED,battery_timer_handler);
注意 main.c中的宏要响应增加1 #define APP_TIMER_MAX_TIMERS (3 + BSP_APP_TIMERS_NUMBER)
定时到期处理函数
void battery_timer_handler(void *p_context){
static uint8_tbattery_level[4];
uint32_t temp;
nrf_adc_start();
while(NRF_ADC->BUSY&1);
float value =(NRF_ADC->RESULT)*1.0;
value = value*1.2/1024.0;
value *= 3;
//将电压值扩大100倍,好发送整数出去。
temp = value * 100;
battery_level[0] = (temp>>24)&0xff;
battery_level[1] = (temp>>16)&0xff;
battery_level[2] = (temp>>8)&0xff;
battery_level[3] = (temp>>0)&0xff;
battery_send(&m_nus,battery_level, 4);
}
并在连接上后就启动定时器。开始 1s 周期发送电量。
Ble_nus.c中修改
extern app_timer_id_t battery_timer;
void ble_nus_on_ble_evt(ble_nus_t * p_nus, ble_evt_t * p_ble_evt)
{
if ((p_nus == NULL) || (p_ble_evt== NULL))
{
return;
}
switch(p_ble_evt->header.evt_id)
{
caseBLE_GAP_EVT_CONNECTED:
on_connect(p_nus,p_ble_evt);
app_timer_start(battery_timer, APP_TIMER_TICKS(1000, 0), NULL);
break;
caseBLE_GAP_EVT_DISCONNECTED:
on_disconnect(p_nus,p_ble_evt);
break;
case BLE_GATTS_EVT_WRITE:
on_write(p_nus,p_ble_evt);
break;
default:
// No implementationneeded.
break;
}
}
这里写的例子比较粗糙。正确的做法应该是,在手机使能电量发送特征值的notify后,从机才开始定时发送。不过这里这样做并不影响现象,因为虽然连接上后就开始周期发送电量,但是因为notify并未被使能,所以发送会失败,但是程序可以继续正常运作。
烧写程序,手机连接上后,找到电池的那个特征值,使能Notify就能收到周期性的电量报告了。
Main函数如下:
int main(void)
{
uint32_t err_code;
bool erase_bonds;
uint8_t start_string[] = START_STRING;
// Initialize.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS,APP_TIMER_OP_QUEUE_SIZE, false);
uart_init();
app_timer_create(&battery_timer,APP_TIMER_MODE_REPEATED,battery_timer_handler);
buttons_leds_init(&erase_bonds);
ble_stack_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();
printf("start\r\n");
nrf_adc_init();
err_code =ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
// Enter main loop.
for (;;)
{
power_manage();
}
return 0;
}- battery service 修改 52832
- Battery
- battery
- SystemUI Battery电池图标定制修改
- Android Porting时由 Battery Service引起的问题
- Android 接收系统广播,开机启动Service,SMS,Battery
- DA1458x BASS 初始化 -- Battery Service 分析(二)
- DA1458x BASS 初始化 -- Battery Service 分析(三)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(6)-Battery Service
- 低功耗蓝牙4.0BLE编程-nrf51822开发(6)-Battery Service
- 低功耗蓝牙4.0BLE编程-nrf51822开发(6)-Battery Service
- MT6735 - battery相关笔记 (充电、电池状态、zvc、driver与service通信)
- DA1458x BASS Database的组成结构 -- Battery Service 分析(一)
- 修改Ubuntu默认启动进入文本模式后,重新启动后停在Checking battery state问题
- laptop battery
- htc battery
- Settings-battery
- Android Battery
- 今天学习spring mybatis整合时遇到一个错误java.lang.Exception: DEBUG STACK TRACE for PoolBackedDataSource.close()
- 新版谷歌浏览器怎么查找和改变编码格式
- css学习总结
- nginx的SSI
- java从入门到入土(log4j)
- battery service 修改 52832
- 使用批处理实现telnet自动登陆并执行ping命令
- 着手使用@AspectJ
- 嵌入式学习日记(十四)
- 海思arm平台AAC音频转码cpu占用高、效率低的问题解决
- 西部开源运维学习unit5
- poj 3468 A Simple Problem with Integers 线段树 成段更新
- 重建二叉树
- 客户端浏览器向服务器发起http请求的全过程