Sugar Glider Part 7: Software Design of the Exercise Reward System for Sugar Glider Based on RSL10
[Copy link]
Introduction
The previous post introduced the exercise reward system in the sugar glider health monitoring project based on RSL10 . The exercise reward subsystem can mainly realize the communication between the host and the host through the Bluetooth protocol. When a reward command is issued, the system drives the solenoid valve to conduct and push out the box containing the insects, thereby achieving the purpose of rewarding the sugar glider with food.
Main body of this post
The previous post explained the structural design and hardware design of the sports reward subsystem .
This post mainly talks about the software design part.
The software implementation of this subsystem is relatively simple. First of all, to control the on and off of the electromagnet, only a few IO functions need to be implemented.
I chose ble_peripheral_server_bond as the base project
The output pin numbers are defined in app.h
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
........
Initialized in app_config.c
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);
...........
}
Then in terms of communication, the customss protocol is used to define the uuid to achieve two-way communication between the upper and lower computers. The maximum packet size that can be sent by BLE is 20 bytes.
Because this part of the control is also very simple, just control the corresponding reward box to pop up, so the protocol only uses two bytes, as follows
The first byte is the instruction, which is fixed to 0XFF
The second byte controls the corresponding reward switch bit by bit, for example, 0x01 is the first box, 0x02 is the second box, 0x04 is the third box...
Then modify the receiving and sending subscription protocols in app_customss.c as follows
Subscription implementation sent to the host computer
// 订阅的内容修改为当前奖励器的触发状态
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[0] = 0xff;
app_env_cs.to_air_buffer[1] = 0x00;
for(int i=0;i<5;i++)
{
if(DIO->CFG&0x01)
app_env_cs.to_air_buffer[1] |= 1<<i;
}
if ((app_env_cs.to_air_cccd_value[0] == ATT_CCC_START_NTF &&
app_env_cs.to_air_cccd_value[1] == 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);
}
........
}
Implementation of receiving data sent from the host computer to the slave computer
//接收到消息后,判断帧数据是否为指令,并执行操作
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);
}
PRINTF("\n\r");
#endif /* if RSL10_DEBUG */
/* 判断协议是否正确
* 协议简易设置为 0xff 0xxx 第二个字节 按位控制IO开关 */
if(length == 2 && to[0] == 0xff)
{
ke_timer_set(APP_FSIO_TIMEOUT, TASK_APP, TIMER_SETTING_MS(200));
for(int i=0; i < 5; i++)
{
if(((to[1]>>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;
}
It should be noted that the electromagnet of the reward system can pop up and maintain itself as long as it is powered on.
So in order to avoid wasting electricity, a software timer is added to execute the operation of turning off the electromagnet. The code is modified as follows:
//新增奖励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);
}
And register the callback of the above function in app.c
app.c
int main(void)
{
........
MsgHandler_Add(APP_FSIO_TIMEOUT, APP_FSio_Timeout_Handler);
.......
}
The above is the code implementation process of the sports reward subsystem.
Don't worry, the parts will arrive in the next batch and I will assemble them for you. Or can you write a host computer for me?
|