蜜袋鼯 第⑦贴 基于RSL10的蜜袋鼯--运动奖励系统之软件设计
<p> </p><p><strong><font face="Microsoft YaHei"><span style="font-size: 18.6667px;">前要简介</span></font></strong></p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> 上一贴介绍了<a href="https://bbs.eeworld.com.cn/thread-1170825-1-1.html">基于RSL10的蜜袋鼯健康监测项目</a>中的运动奖励系统,</span></span><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">运动奖励子系统主要可以实现 主机端通过蓝牙协议 与其通讯,当有奖励指令下达后,该系统则驱动电磁阀导通,推出装有小虫的盒子,已达到给蜜袋鼯奖励食物的作用。</span></span></p>
<p> </p>
<p></p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> </span></span></p>
<p><strong><font face="Microsoft YaHei"><span style="font-size: 18.6667px;">本帖正文</span></font></strong></p>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">上一贴讲解了<a href="https://bbs.eeworld.com.cn/thread-1170826-1-1.html">运动奖励子系统的结构设计和硬件设计部分</a>。</span></span></p>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">本帖主要讲下软件设计部分内容。</span></span></p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> </span></span></p>
<p><span style="font-size:14.0pt"><span lang="zh-CN" style="font-style: normal;">这个子系统的</span><span lang="zh-CN" style="font-family:"Microsoft YaHei"">软件实现相对比较简单,首先是要控制电磁铁的通断只需要实现几个</span><span lang="en-US" style="font-family:"Times New Roman"">IO</span><span lang="zh-CN" style="font-family:"Microsoft YaHei"">的功能,</span></span></p>
<p> </p>
<p><span style="font-size:14.0pt"><span lang="zh-CN" style="font-family:"Microsoft YaHei"">我选择了</span><span lang="en-US" style="font-family:"Microsoft YaHei"">ble_peripheral_server_bond</span><span lang="zh-CN" style="font-family:"Microsoft YaHei"">作为基础工程</span></span></p>
<p> </p>
<p><span style="font-size:14.0pt"><span lang="zh-CN" style="font-family:"Microsoft YaHei"">在</span><span lang="en-US" style="font-family:"Microsoft YaHei"">app.h</span><span lang="zh-CN" style="font-family:"Microsoft YaHei"">中定义了输出引脚号</span></span></p>
<pre>
<code class="language-cpp">app.h
........
/* 喂食继电器 DIO 端口定义 */
#define TS1_DIO_NUM 0
#define TS2_DIO_NUM 1
#define TS3_DIO_NUM 2
#define TS4_DIO_NUM 3
#define TS5_DIO_NUM 4
........
</code></pre>
<p><span style="font-size:14.0pt"><span lang="zh-CN" style="font-family:"Microsoft YaHei"">在</span><span lang="en-US" style="font-family:"Microsoft YaHei"">app_config.c</span><span lang="zh-CN" style="font-family:"Microsoft YaHei"">中做了初始化</span></span></p>
<pre>
<code class="language-cpp">void Device_Initialize(void)
{
.........
Sys_DIO_Config(TS1_DIO_NUM, DIO_MODE_GPIO_OUT_0);
Sys_DIO_Config(TS2_DIO_NUM, DIO_MODE_GPIO_OUT_0);
Sys_DIO_Config(TS3_DIO_NUM, DIO_MODE_GPIO_OUT_0);
Sys_DIO_Config(TS4_DIO_NUM, DIO_MODE_GPIO_OUT_0);
Sys_DIO_Config(TS5_DIO_NUM, DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(TS1_DIO_NUM);
Sys_GPIO_Set_Low(TS2_DIO_NUM);
Sys_GPIO_Set_Low(TS3_DIO_NUM);
Sys_GPIO_Set_Low(TS4_DIO_NUM);
Sys_GPIO_Set_Low(TS5_DIO_NUM);
...........
}</code></pre>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">然后是通讯方面,使用customss协议定义好uuid实现上下位机双向通讯,BLE最大可发送的包大小为20字节,</span></span></p>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">因为这部分控制也很简单,只要控制对应奖励盒弹出即可,所以协议只用了两个字节,如下</span></span></p>
<p> </p>
<p></p>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">其中 第一个字节为指令,固定为0XFF</span></span></p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">第二个字节 按位控制对应奖励器开关,例如0x01为第一个盒子,0x02为第二个盒子,0x04为第三个盒子…</span></span></p>
<p lang="en-US"><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> </span></span></p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">然后在app_customss.c中修改接收、和发送的订阅协议,如下所示</span></span></p>
<p> </p>
<p><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> 发送给上位机的订阅实现</span></span></p>
<pre>
<code class="language-cpp">// 订阅的内容修改为当前奖励器的触发状态
void CUSTOMSS_MsgHandler(ke_msg_id_t const msg_id, void const *param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
.........
case CUSTOMSS_NTF_TIMEOUT:
{
uint8_t conidx = KE_IDX_GET(dest_id);
app_env_cs.to_air_buffer = 0xff;
app_env_cs.to_air_buffer = 0x00;
for(int i=0;i<5;i++)
{
if(DIO->CFG<i>&0x01)
app_env_cs.to_air_buffer |= 1<<i;
}
if ((app_env_cs.to_air_cccd_value == ATT_CCC_START_NTF &&
app_env_cs.to_air_cccd_value == 0x00)
&& GAPC_IsConnectionActive(conidx))
{
/* Send notification to peer device */
GATTC_SendEvtCmd(conidx, GATTC_NOTIFY, 0, GATTM_GetHandle(CS_TX_VALUE_VAL0),
2 , app_env_cs.to_air_buffer);
}
........
}</i></code></pre>
<p><i> 上位机发送给下位机的接收实现</i></p>
<pre>
<i>
<code class="language-cpp">//接收到消息后,判断帧数据是否为指令,并执行操作
uint8_t CUSTOMSS_RXCharCallback(uint8_t conidx, uint16_t attidx, uint16_t handle,
uint8_t *to, const uint8_t *from, uint16_t length,
uint16_t operation)
{
memcpy(to, from, length);
#if RSL10_DEBUG
PRINTF("RXCharCallback (%d): (%d)", conidx, length);
for (int i = 0; i < length; i++)
{
PRINTF("%02x ", app_env_cs.from_air_buffer<i>);
}
PRINTF("\n\r");
#endif /* if RSL10_DEBUG */
/* 判断协议是否正确
* 协议简易设置为 0xff 0xxx 第二个字节 按位控制IO开关 */
if(length == 2 && to == 0xff)
{
ke_timer_set(APP_FSIO_TIMEOUT, TASK_APP, TIMER_SETTING_MS(200));
for(int i=0; i < 5; i++)
{
if(((to>>i)&0x01) == 1)
{
Sys_GPIO_Set_High(i);
#if RSL10_DEBUG
PRINTF("Open TS%d.\r\n", i);
#endif /* if RSL10_DEBUG */
}
else
{
Sys_GPIO_Set_Low(i);
#if RSL10_DEBUG
PRINTF("Close TS%d.\r\n", i);
#endif /* if RSL10_DEBUG */
}
}
}
return ATT_ERR_NO_ERROR;
}</i></code></i></pre>
<p><i><i><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">需要注意的是,奖励系统的电磁铁只要通电一下就能弹出来并且自己维持</span></span></i></i></p>
<p><i><i> </i></i></p>
<p><i><i><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">所以为了避免浪费电量,增加了个软件定时器,来执行关闭电磁铁的操作,代码修改如下:</span></span></i></i></p>
<pre>
<i><i>
<code>//新增奖励IO触发超时定时回调函数
void APP_FSio_Timeout_Handler(ke_msg_id_t const msg_id, void const *param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
Sys_GPIO_Set_Low(TS1_DIO_NUM);
Sys_GPIO_Set_Low(TS2_DIO_NUM);
Sys_GPIO_Set_Low(TS3_DIO_NUM);
Sys_GPIO_Set_Low(TS4_DIO_NUM);
Sys_GPIO_Set_Low(TS5_DIO_NUM);
}
</code></i></i></pre>
<p><i><i><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei""> 并在app.c中注册上述函数的回调</span></span></i></i></p>
<pre>
<i><i>
<code>app.c
int main(void)
{
........
MsgHandler_Add(APP_FSIO_TIMEOUT, APP_FSio_Timeout_Handler);
.......
}</code></i></i></pre>
<p><i><i><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">以上就是运动奖励子系统上的代码实现过程。</span></span></i></i></p>
<p> </p>
<p><i><i></i></i></p>
<p> </p>
<p><i><i><span style="font-size:14.0pt"><span style="font-family:"Microsoft YaHei"">别急啦,下一贴零件就到啦,给你装起来~ 要不你给我写个上位机吧?</span></span></i></i></p>
<p> </p>
<p> </p>
<p> </p>
<p>这跑完就吃虫,不会得盲肠炎吗?</p>
soso 发表于 2021-7-2 10:29
这跑完就吃虫,不会得盲肠炎吗?
<p>哈哈哈哈 它得现有盲肠~</p>
justd0 发表于 2021-7-2 12:25
哈哈哈哈 它得现有盲肠~
<p><img height="53" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan59.gif" width="48" />哈哈</p>
<p>每次看到这种小动物都很揪心</p>
<p>小时候养的仓鼠被坐化了</p>
页:
[1]