freeelectron 发表于 2022-3-28 20:05

【BLE 5.3无线MCU CH582】11、手机app控制led亮灭

本帖最后由 freeelectron 于 2022-3-28 20:15 编辑

<p>系列文章:</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1195192-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】1、初识CH582开发板(开箱)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1195464-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】2、MounRiver IDE初体验</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196099-1-1.html#pid3126477" target="_blank">【BLE 5.3无线MCU CH582】3、非阻塞方式点灯</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196188-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】4、串口不定长数据接收</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196777-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】5、硬件I2C驱动0.96吋OLED</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196846-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】6、pwm呼吸灯</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196850-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】7、按键&mdash;&mdash;GPIO外部中断</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1196888-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】8、adc采样(内部bat、内部温度,外部输入)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1197780-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】9、硬件spi驱动lcd</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1198080-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】10、ble广播者角色</a></p>

<p>&nbsp;</p>

<p><span style="font-size:26px;">1、前面的话</span></p>

<p><span style="font-size:16px;">本文使用ble的另一种角色&mdash;&mdash;外围设备,也叫从机,也是最常用的一种角色。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:26px;">2、ble数据传输</span></p>

<p><span style="font-size:16px;">这里需要明确一点,ble是属性传输数据的,属性是有权限的,可读可写等。</span></p>

<p>&nbsp;</p>

<h3><span style="font-size:26px;">3、led控制特征分析</span></h3>

<p><span style="font-size:16px;">控制led亮灭:通过对一个特征值<strong>写</strong>来实现;<br />
获取led状态:通过对一个特征值<strong>读</strong>来实现。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:26px;">4、控制led亮灭服务</span></p>

<p><span style="font-size:16px;">要实现特征值的读写,必须要有<strong>服务</strong>,<strong>特征声明</strong>,<strong>特征值声明</strong></span></p>

<h3><span style="font-size:26px;">5、属性表定义</span></h3>

<pre>
<code class="language-cpp">static gattAttribute_t ledProfileAttrTb[] =
{
      // led Profile Service, // 服务,主要服务
      {
      { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
      GATT_PERMIT_READ,                         /* permissions */
      0,                                        /* handle */
      (uint8 *)&amp;ledProfileService            /* pValue */
      },

      // CharacteristicDeclaration// 特征声明
      {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &amp;ledProfileCharProps
      },

      // Characteristic Value// 特征值声明
      {
      { ATT_BT_UUID_SIZE, ledProfilecharUUID },
      GATT_PERMIT_READ | GATT_PERMIT_WRITE,
      0,
      ledProfileChar
      },

      // CharacteristicUser Description// 特征描述(非必须)
      {
      { ATT_BT_UUID_SIZE, charUserDescUUID },
      GATT_PERMIT_READ,
      0,
      ledProfileCharUserDesp
      },      
};</code></pre>

<p><span style="font-size:16px;">上述表中定义了服务、特征声明、特征值声明、特征用户描述(非必须);服务、特征声明、特征值声明、特征用户描述,分别都属于属性。</span></p>

<p>&nbsp;</p>

<h3><span style="font-size:26px;">6、注册服务</span></h3>

<pre>
<code class="language-cpp">bStatus_t LedProfile_AddService( uint32 services )
{
uint8 status = SUCCESS;

if ( services &amp; LEDPROFILE_SERVICE )
{
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( ledProfileAttrTb,
                                          GATT_NUM_ATTRS( ledProfileAttrTb ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &amp;ledProfileCBs );
}

return ( status );
}</code></pre>

<h3><span style="font-size:26px;">7、属性读回调</span></h3>

<pre>
<code class="language-cpp">static bStatus_t ledProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                            uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen,uint8 method)
{
bStatus_t status = SUCCESS;

// If attribute permissions require authorization to read, return error
if ( gattPermitAuthorRead( pAttr-&gt;permissions ) )
{
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
}

// Make sure it's not a blob operation (no attributes in the profile are long)
if ( offset &gt; 0 )
{
    return ( ATT_ERR_ATTR_NOT_LONG );
}

if ( pAttr-&gt;type.len == ATT_BT_UUID_SIZE )
{
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr-&gt;type.uuid, pAttr-&gt;type.uuid);
    switch ( uuid )
    {
      case LEDPROFILE_CHAR_UUID:
      *pLen = LEDPROFILE_CHAR_LEN;
      tmos_memcpy( pValue, pAttr-&gt;pValue, LEDPROFILE_CHAR_LEN );

      PRINT("Led read\r\n");

      break;
      
      default:
      // Should never get here! (characteristics 3 and 4 do not have read permissions)
      *pLen = 0;
      status = ATT_ERR_ATTR_NOT_FOUND;
      break;
    }
}
else
{
    // 128-bit UUID
    *pLen = 0;
    status = ATT_ERR_INVALID_HANDLE;
}

return ( status );
}</code></pre>

<h3><span style="font-size:26px;">8、属性写回调</span></h3>

<pre>
<code>static bStatus_t ledProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                 uint8 *pValue, uint16 len, uint16 offset,uint8 method)
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;

// If attribute permissions require authorization to write, return error
if ( gattPermitAuthorWrite( pAttr-&gt;permissions ) )
{
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
}

if ( pAttr-&gt;type.len == ATT_BT_UUID_SIZE )
{
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr-&gt;type.uuid, pAttr-&gt;type.uuid);
    switch ( uuid )
    {
      case LEDPROFILE_CHAR_UUID:
      //Validate the value
      // Make sure it's not a blob oper
      if ( offset == 0 )
      {
          if ( len &gt; LEDPROFILE_CHAR_LEN )
          {
            status = ATT_ERR_INVALID_VALUE_SIZE;
          }
      }
      else
      {
          status = ATT_ERR_ATTR_NOT_LONG;
      }
      
      //Write the value
      if ( status == SUCCESS )
      {
          tmos_memcpy( pAttr-&gt;pValue, pValue, LEDPROFILE_CHAR_LEN );
          notifyApp = LEDPROFILE_CHAR;
      }
      PRINT("Led write\r\n");
      break;

      default:
      // Should never get here! (characteristics 2 and 4 do not have write permissions)
      status = ATT_ERR_ATTR_NOT_FOUND;
      break;
    }
}
else
{
    // 128-bit UUID
    status = ATT_ERR_INVALID_HANDLE;
}

// If a charactersitic value changed then callback function to notify application of change
if ( (notifyApp != 0xFF ) &amp;&amp; ledProfile_AppCBs &amp;&amp; ledProfile_AppCBs-&gt;pfnLedProfileChange )
{
    ledProfile_AppCBs-&gt;pfnLedProfileChange( notifyApp, pValue, len );
}

return ( status );
}</code></pre>

<h3><span style="font-size:26px;">9、应用层控制LED</span></h3>

<pre>
<code>static void ledProfileChangeCB( uint8 paramID, uint8 *pValue, uint16 len )
{

switch( paramID )
{
    case LEDPROFILE_CHAR:
                {
                        uint8 newValue;
      tmos_memcpy( newValue, pValue, len );

      if(newValue)
      {
      GPIOB_ResetBits (GPIO_Pin_18);
      PRINT("led on\n");
      }
      else
      {
      GPIOB_SetBits(GPIO_Pin_18);
      PRINT("led off\n");
      }
      break;
                }
    default:
      // should not reach here!
      break;
}
}</code></pre>

<h3><span style="font-size:26px;">10、APP控制LED</span></h3>

<p>(1)扫描</p>

<p></p>

<p>(2)连接</p>

<p>&nbsp; &nbsp;</p>

<p>(3)属性权限</p>

<p>&nbsp;可以看到,扫描出来后是可读可写的,与我们代码中定义的是一致的。</p>

<p>(3)控制亮灭</p>

<p></p>

<p> &nbsp; &nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

tagetage 发表于 2022-3-29 11:14

<p>顶一下楼主,楼主对蓝牙还是很有研究的。</p>

lugl4313820 发表于 2022-3-29 16:43

<p>更进一步了哦,有没有考虑用小爱同志,或者其他的APP来控制呀。</p>

freeelectron 发表于 2022-3-29 16:44

lugl4313820 发表于 2022-3-29 16:43
更进一步了哦,有没有考虑用小爱同志,或者其他的APP来控制呀。

<p><img height="53" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/sad.gif" width="54" />暂时没有小爱</p>

freebsder 发表于 2022-3-29 17:13

<p>这个app也是自己做的吗?牛逼了哦</p>

freeelectron 发表于 2022-3-29 17:55

freebsder 发表于 2022-3-29 17:13
这个app也是自己做的吗?牛逼了哦

<p>这是官方的app</p>

freeelectron 发表于 2022-4-18 11:21

tagetage 发表于 2022-3-29 11:14
顶一下楼主,楼主对蓝牙还是很有研究的。

<p>以前用ch579学过蓝牙,那一套api和ch582的基本一致。</p>

aaa1218bbb 发表于 2022-4-26 11:41

<p>大佬,有没有专案分享一下,我正在学习 CH582 蓝牙,我试了好久这专案都跑不起来...鬱闷.... 感觉这是我找到最适合入门蓝牙的例程了,谢谢大佬</p>

freeelectron 发表于 2022-4-26 12:43

aaa1218bbb 发表于 2022-4-26 11:41
大佬,有没有专案分享一下,我正在学习 CH582 蓝牙,我试了好久这专案都跑不起来...鬱闷.... 感觉这是我找 ...

<p>对照着蓝牙核心规范和代码学习</p>

little_485 发表于 2022-9-22 15:49

<p>楼主你好请问文中的例程可以分享一下吗 有一些细节的东西想再看代码学习一下</p>
页: [1]
查看完整版本: 【BLE 5.3无线MCU CH582】11、手机app控制led亮灭