按键值的问题。
你好,Yan
求解一个问题,就是按键值都是单字节,我跟踪发现static uint8 skKeyPressed = 0,不能改成双字节。keyfobapp_HandleKeys的SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys ); 确定了每按一次键,只能是1个字节的键值。我想按一次产生双字节键值,怎么办?还有sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )中读两个字节 case SK_KEYPRESSED_UUID:
*pLen = 2;
pValue[0] = *pAttr->pValue;
pValue[1] ?如何表示,
break;
谢了。万分感谢!
lincoln,
SK_SetParameter( SK_KEY_ATTR, 2, &SK_Keys ); 表示可以发送两个字节。
读两个字节, pValue[1] = *(pAttr->pValue+1);
读两个字节的前提是,你必须修改simplekeys.c中skKeyPressed的定义,改成两字节的数组,同时修改 simplekeysAttrTbl[] 中的skKeyPressed 引用,去掉“&”
最后,如果编译有错,请对应的一一修改。
谢了,yan。按你的要求做了如下改动,能编译通过。
1)SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys );
*skKeyPressed = *((uint8*)pValue);
// See if Notification/Indication has been enabled
GATTServApp_ProcessCharCfg( skConfig, skKeyPressed, FALSE,
simplekeysAttrTbl, GATT_NUM_ATTRS( simplekeysAttrTbl ),
INVALID_TASK_ID );
2)static uint8 sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
case SK_KEYPRESSED_UUID:
*pLen = 2;
pValue[0] = *pAttr->pValue;
pValue[1] = *(pAttr->pValue+1);
改成数组了,编译ok,结果跟uint16定义一样也只得到1个字节内容是对的。另一个00或FF。也没得到。
可能哪里还有问题。
还有几个问题请教:
1)
GATTServApp_ReadCharCfg(0, skConfig);//handle为0,是否只是单机相连接才有效。
GATT_Notification(0, ¬i, FALSE);//handle为0,是否只是单机相连接才有效。
static uint16 gapConnHandle;
GATTServApp_ReadCharCfg(gapConnHandle, skConfig);
GATT_Notification(gapConnHandle, ¬i, FALSE);
GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );//gapConnHandle是否是通过这个函数取得
2)
我用packet sniffer抓包,把广播单独设成37,38,39频道还是抓不到包。(按你讲设置数值1,2,4等)
clock mulitiplier 为1.0是否要修改。
connect to initiator address:设置成被抓包地址,dongle地址
怎能都只是广告包,数据包抓不到,是否可能还有其它什么原因。
万分感谢!
祝好!
Lincoln
yan,你好,*skKeyPressed = *((uint8*)pValue); >>>用osalmemcpy函数能得到2个正确字节了。按键值,在keyfobapp_handlekeys函数得到了。弹起时的键值在哪个函数能得到。其它几个问题也帮我回下。谢了。
lincoln
yan,你好,还一个问题,就是用lightblue测试,总能发现第一个16byte的service uuid。但程序中好象找不到,不知是哪里来的。谢了。
祝好
lincoln
Yan,你好!
帮我一下,除了前面的一太堆问题,还有几个问题:
1)如果自己单独定义service uuid,charateristic uuid,是否要写_readattrcb(****),_writeattrcb(****),还要写其它什么函数吗?
2)我用lightblue能看到manufacturer data,这个是干什么的。
万分感谢。
祝好
lincoln
hi lincon,
1, handle 为0,的确是单连接状态。作为slave,目前也不会有多连接状态。如果作为master的话,连接上多个slave之后,这个数字就会累加。
connection handle可以通过GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );得到。
2.clock multiplier不需要改,代码里面改成37, 38, 或39之后,packet sniffer里面也要设置成相应的频道。
好的,谢了。
1) 是按你讲的在代码与sniffer同时设置的,还是抓不着。不知什么原因,难道很难抓吗?
2)按你所讲,GATTServApp_ProcessCharCfg与GATT_Notification 的区别,GATTServApp_ProcessCharCfg最终会导致master那边调用一个read请求, 然后调用到keyfob这边的sk_ReadAttrCB()。GATT_Notification判断Notification 打开就发给master。我用btool测试,uuid找到handle,加1,在下面写入01:00,抓到的数据是对的。如果不写。好像GATT_Notification也没反应。
3)如果直接跟app通讯。我们这边用GATTServApp_ProcessCharCfg与GATT_Notification 。我们在keyfob这边如何知道app那边是否打开notification了。是在sk_writeAttrCB()回调函数中拦截吗?在keyfob这边有什么办法确认在与手机app通讯后,手机那端notification是打开的。因为app是另一家公司写。我现在这边按你的方式送给它的数据,用btool测试是对的。但跟手机app对不上。因此我想从我这边来判断。
4)蓝牙协议栈1.3.2是否支持android4.3.
谢了
祝好
lincoln
lincon,
1, 很奇怪,我这样设置每次都是能抓到包的。
2. 你说的没错,notification必须被使能之后才能起作用。
3. BTool正常,说明你的代码是正确的。第三方的手机app, 对方并不确定你的notification使能的handle的位置,因此应该无法使能你的notification. 你可以在writeAttrCB()中进行拦截判断是否notification的使能请求被收到。
谢了,yan
确认是app没使能notification,我们有什么办法设置成它需要的handle。
谢谢。
祝好
lincoln
你好,yan
GATTServApp_ProcessCharCfg 最终会导致master那边调用一个read请求, 然后调用sk_ReadAttrCB()。它是靠performperiodicktask()这个函数还是靠sk_writeAttrCB()来处理master的read请求?
谢了。
祝好
lincoln
lincoln,
你需要修改app的代码,能手动修改Handle或者自动搜索到相应handle,进行修改。
lincoln,
GATTServApp_ProcessCharCfg ()是靠 sk_ReadAttrCB()来处理。
谢了,yan
客户想做些功能要求,比如通过读rssi调距离报警开关控制,断开后一直报警或不报警开关控制,按键取消报警开关控制,app那边进行这些设置。我这边想单独用定义service uuid,charateristic uuid来完成这些要求,但不知要写那些相关函数,才能与app那边通讯。是否有类似的例程。
谢谢
祝好
lincoln
你好,yan
app那边没办法stop notify可能是固件这边什么原因。谢了
祝好
lincoln
你好,yan。
客户要求按键时间长短不同,做不同功能要求。我用定时器来判断时间,如下:
void HalKeyPoll (void)
{
uint8 keys = 0;
uint8 notify = 0;
#if defined (CC2540_MINIDK)
if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) /* Key is active low */
{
keys |= HAL_KEY_SW_1;
}
if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) /* Key is active low */
{
keys |= HAL_KEY_SW_2;
}
#else
if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low */
{
keys |= HAL_KEY_SW_6;
}
if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */
{
keys = halGetJoyKeyInput();
}
#endif
/* If interrupts are not enabled, previous key status and current key status
* are compared to find out if a key has changed status.
*/
if (!Hal_KeyIntEnable)
{
if (keys == halKeySavedKeys)
{
/* Exit - since no keys have changed */
return;
}
else
{
notify = 1;
}
}
else
{
/* Key interrupt handled here */
if (keys)
{
notify = 1;
InitT4();//add
}
}
/* Store the current keys for comparation next time */
halKeySavedKeys = keys;
/* Invoke Callback if new keys were depressed */
if (notify && (pHalKeyProcessFunction))
{
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
}
}
//add
int PRESS_KEY_TIME=0
void InitT4()
{
T4CTL &= ~0x10; // 起止控制位 先停中断,假如开
T4CTL |= 0x08 ; //开溢出中断
T4IE = 1; //开总中断和 T4中断
T4CTL|=0XE0; //128 分频,128/16000000*N=0.5S,N=65200
T4CTL &= ~0X03; //自动重装 00->0xff 65200/256=254(次)
T4CTL |=0X10; //启动
EA = 1; //开总中断
}
#pragma vector = T4_VECTOR //定时器 T4
__interrupt void T4_ISR(void)
{
IRCON = 0x00; //清中断标志, 也可由硬件自动完成
if(++count>254) //254 次中断后,约为 0.5 秒
{
count = 0; // 计数清零
PRESS_KEY_TIME++;
}
}//0.5s
void OnBoard_KeyCallback ( uint8 keys, uint8 state )
{
uint8 shift;
(void)state;
// shift key (S1) is used to generate key interrupt
// applications should not use S1 when key interrupt is enabled
shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);
if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
{
// Process SW1 here
if ( keys & HAL_KEY_SW_1 ) // Switch 1
{
}
// Process SW2 here
if ( keys & HAL_KEY_SW_2 ) // Switch 2
{
}
// Process SW3 here
if ( keys & HAL_KEY_SW_3 ) // Switch 3
{
}
// Process SW4 here
if ( keys & HAL_KEY_SW_4 ) // Switch 4
{
}
// Process SW5 here
if ( keys & HAL_KEY_SW_5 ) // Switch 5
{
}
// Process SW6 here
if ( keys & HAL_KEY_SW_6 ) // Switch 6
{
}
}
/* If any key is currently pressed down and interrupt
is still enabled, disable interrupt and switch to polling */
if( keys != 0 )
{
if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
{
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
}
}
/* If no key is currently pressed down and interrupt/
is disabled, enable interrupt and turn off polling */
else
{
if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
{
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
}
//add
T4CTL &= 0xf7;//if need to close interrupt
T4CTL &= ~0x10;
T4IE = 0;
EA = 0;
}
}
帮我看下,我追踪PRESS_KEY_TIME变量,发现没变化。那就是中断没起作用。
我担心定时器耗电,我在按键弹起来时,关掉中断,不知是否正确。
谢了
祝好
lincoln
lincoln,
TI提供了Android 和iOS 端的源码提供参考,是基于sensortag的,对你来说是非常好的参考,但是没有你要求的那么具体的需求,你说的功能应该是都能实现的,但是需要你做些工作。