搭建好开发环境后,就可以开始编写代码
(1)智能语音垃圾桶需要四个舵机,所以我们需要对GPIO6、GPIO7、GPIO9、GPIO10做初始化设置pwm功能
void SmartdustbinInit(void)
{
GpioInitOperation(HAL_WIFI_IOT_IO_NAME_GPIO_10, 0, IOT_GPIO_DIR_OUT, IOT_GPIO_VALUE0);
GpioInitOperation(HAL_WIFI_IOT_IO_NAME_GPIO_9, 0, IOT_GPIO_DIR_OUT, IOT_GPIO_VALUE0);
GpioInitOperation(HAL_WIFI_IOT_IO_NAME_GPIO_7, 0, IOT_GPIO_DIR_OUT, IOT_GPIO_VALUE0);
GpioInitOperation(HAL_WIFI_IOT_IO_NAME_GPIO_6, 0, IOT_GPIO_DIR_OUT, IOT_GPIO_VALUE0);
}
可将GPIO10、GPIO9、GPIO7、GPIO6分别用作可回收垃圾、不可回收垃圾、厨余垃圾、其他垃圾的开关功能
//舵机正转
void set_engine_angle_R(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_VALUE1);
hal_udelay(duty - i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - (duty - i*THE_PARM_OF_CACL_CYCLE));
}
}
void set_engine_angle_U(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_9, IOT_GPIO_VALUE1);
hal_udelay(duty - i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_9, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - (duty - i*THE_PARM_OF_CACL_CYCLE));
}
}
void set_engine_angle_K(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_VALUE1);
hal_udelay(duty - i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - (duty - i*THE_PARM_OF_CACL_CYCLE));
}
}
void set_engine_angle_O(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_6, IOT_GPIO_VALUE1);
hal_udelay(duty - i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_6, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - (duty - i*THE_PARM_OF_CACL_CYCLE));
}
}
//舵机反转
void set_engine_angle_reversal(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_VALUE1);
hal_udelay(i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - i*THE_PARM_OF_CACL_CYCLE);
}
}
void set_engine_angle_reversal_U(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_9, IOT_GPIO_VALUE1);
hal_udelay(i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_9, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - i*THE_PARM_OF_CACL_CYCLE);
}
}
void set_engine_angle_reversal_K(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_VALUE1);
hal_udelay(i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - i*THE_PARM_OF_CACL_CYCLE);
}
}
void set_engine_angle_reversal_O(hi_s32 duty)
{
uint32 count = duty/THE_PARM_OF_CACL_CYCLE;
for (int i = 1; i <= count; i++) {
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_6, IOT_GPIO_VALUE1);
hal_udelay(i*THE_PARM_OF_CACL_CYCLE);
IoTGpioSetOutputVal(HAL_WIFI_IOT_IO_NAME_GPIO_6, IOT_GPIO_VALUE0);
hal_udelay(THE_CYCLES_OF_PWM_CONTROL - i*THE_PARM_OF_CACL_CYCLE);
}
}
void Dustbin_close_R(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:close_R", 1);
set_engine_angle_reversal(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = FALSE;
}
void Dustbin_close_U(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:close_U", 1);
set_engine_angle_reversal_U(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = FALSE;
}
void Dustbin_close_K(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:close_K", 1);
set_engine_angle_reversal_K(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = FALSE;
}
void Dustbin_close_O(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:close_O", 1);
set_engine_angle_reversal_O(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = FALSE;
}
void Dustbin_open_R(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:open_R ", 1);
set_engine_angle_R(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = TRUE;
}
void Dustbin_open_U(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:open_U ", 1);
set_engine_angle_U(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = TRUE;
}
void Dustbin_open_K(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:open_K ", 1);
set_engine_angle_K(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = TRUE;
}
void Dustbin_open_O(void)
{
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, " ", 1);
OledShowStr(0, Y_SHOW_SMART_CAN_SHOW_OPEN, "Dustbin:open_O ", 1);
set_engine_angle_O(THE_ANGLE_OF_dustbin_WROK);
g_dustbinIsOpen = TRUE;
}
我们需要一个包含四个垃圾桶容量上报的函数,上报属性可参考profile文件
int IotProfile_Report_ALL(int dev_status,int recyclables_Capacity,int unrecyclable_Capacity,int kitchenGarbage_Capacity,int otherRubbish_Capacity)
{
int ret = -1;
cJSON *root;
char *jsonString;
IotProfileService service;
IotProfileKV kvDev_status;//dev
IotProfileKV kvRecyclables_Capacity;//可回收垃圾桶
IotProfileKV kvUnrecyclable_Capacity;//不可回收垃圾桶
IotProfileKV kvKitchenGarbage_Capacity;//厨余垃圾垃圾桶
IotProfileKV kvOtherRubbish_Capacity;//其他垃圾
/* package the data */
service.eventTime = NULL;
service.serviceID = "SmartDustbin_DATA";
service.propertyLst = &kvDev_status;
service.nxt = NULL;
kvDev_status.key = "Dev_Status";
kvDev_status.value = &dev_status;
kvDev_status.type = IOT_PROFILE_KEY_DATATYPE_INT;
kvDev_status.nxt = &kvRecyclables_Capacity;
kvRecyclables_Capacity.key = "Recyclables_Capacity";
kvRecyclables_Capacity.value = &recyclables_Capacity;
kvRecyclables_Capacity.type = IOT_PROFILE_KEY_DATATYPE_INT;
kvRecyclables_Capacity.nxt = &kvUnrecyclable_Capacity;
kvUnrecyclable_Capacity.key = "Unrecyclable_Capacity";
kvUnrecyclable_Capacity.value = &unrecyclable_Capacity;
kvUnrecyclable_Capacity.type = IOT_PROFILE_KEY_DATATYPE_INT;
kvUnrecyclable_Capacity.nxt = &kvKitchenGarbage_Capacity;
kvKitchenGarbage_Capacity.key = "KitchenGarbage_Capacity";
kvKitchenGarbage_Capacity.value = &kitchenGarbage_Capacity;
kvKitchenGarbage_Capacity.type = IOT_PROFILE_KEY_DATATYPE_INT;
kvKitchenGarbage_Capacity.nxt = &kvOtherRubbish_Capacity;
kvOtherRubbish_Capacity.key = "OtherRubbish_Capacity";
kvOtherRubbish_Capacity.value = &otherRubbish_Capacity;
kvOtherRubbish_Capacity.type = IOT_PROFILE_KEY_DATATYPE_INT;
kvOtherRubbish_Capacity.nxt = NULL;
jsonString = IoTProfilePackage(&service);
if ( NULL != jsonString) {
ret = CLOUD_ReportMsg(jsonString);
free(jsonString);
} else {
RaiseLog(LOG_LEVEL_ERR, "format the report message error");
}
return ret;
}
int CLOUD_CommandCallBack(const char *jsonString)
{
cJSON *objRoot = NULL;
cJSON *objCmdName = NULL;
int ret = -1;
if (jsonString == NULL) {
return ret;
}
if ((objRoot = cJSON_Parse(jsonString)) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "could not parse the payload\r\n");
goto EXIT_JSONPARSE;
}
if ((objCmdName = cJSON_GetObjectItem(objRoot, "command_name")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "%s:could not get the cmd name from json\r\n");
goto EXIT_CMDOBJ;
}
if (0 == strcmp(cJSON_GetStringValue(objCmdName), "Open_R")) {
ret = DealMain_dustbinOpenRecyclables(objRoot);
} else if(0 == strcmp(cJSON_GetStringValue(objCmdName), "Open_U")) {
ret = DealMain_dustbinOpenUnrecyclable(objRoot);
} else if(0 == strcmp(cJSON_GetStringValue(objCmdName), "Open_K")) {
ret = DealMain_dustbinOpenKitchenGarbage(objRoot);
}else if(0 == strcmp(cJSON_GetStringValue(objCmdName), "Open_O")) {
ret = DealMain_dustbinOpenOtherRubbish(objRoot);
}else {
RaiseLog(LOG_LEVEL_ERR, "unresolved command:%d\r\n", cJSON_GetStringValue(objCmdName));
}
EXIT_CMDOBJ:
EXIT_JSONPARSE:
if (objRoot != NULL) {
cJSON_Delete(objRoot);
}
return ret;
}
static int DealMain_dustbinOpenRecyclables(cJSON *objCmd)//云端命令处理
{ int ret = -1;
cJSON *objParas = NULL;
cJSON *objPara = NULL;
CommandParamSetOpen setOpen;
if ((objParas = cJSON_GetObjectItem(objCmd, "paras")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "Could not get paras in json");
return ret;
}
if (Getcommand_dustbinOpenRecyclables(&setOpen, objParas) < 0) {
RaiseLog(LOG_LEVEL_ERR, "GetCommandSetOpen failed!\n");
}
ret = IotProfile_CommandCallback(CLOUD_COMMAND_SETOPEN, &setOpen);
return ret;
}
int IotProfile_CommandCallback(int command, void *buf)
{
CommandParamSetOpen setOpen;
CLOUD_CommandType cmd = (CLOUD_CommandType)command;
if (cmd == CLOUD_COMMAND_SETOPEN) {
setOpen = *(CommandParamSetOpen *)buf;
g_appController.recyclables_Capacity = setOpen.openStatus;
return 0;
}
return -1;
}
static int Getcommand_dustbinOpenRecyclables(CommandParamSetOpen *setOpen,cJSON *objCmd)
{
cJSON *objPara = NULL;
if (setOpen== NULL || objCmd == NULL) {
RaiseLog(LOG_LEVEL_ERR, "NULL POINT!\n");
return -1;
}
memset(setOpen, 0x00, sizeof(CommandParamSetOpen));
if ((objPara = cJSON_GetObjectItem(objCmd, "OpenRecyclables")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "Could not get paras in json");
return -1;
}
if (0 == strcmp(cJSON_GetStringValue(objPara), "ON")) {
Dustbin_open_R();
}
else {
Dustbin_close_R();
}
return 0;
}
static int Getcommand_dustbinOpenUnrecyclable(CommandParamSetOpen *setOpen,cJSON *objCmd)
{
cJSON *objPara = NULL;
if (setOpen== NULL || objCmd == NULL) {
RaiseLog(LOG_LEVEL_ERR, "NULL POINT!\n");
return -1;
}
memset(setOpen, 0x00, sizeof(CommandParamSetOpen));
if ((objPara = cJSON_GetObjectItem(objCmd, "OpenUnrecyclable")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "Could not get paras in json");
return -1;
}
if (0 == strcmp(cJSON_GetStringValue(objPara), "ON")) {
Dustbin_open_U();
}
else {
Dustbin_close_U();
}
return 0;
}
static int Getcommand_dustbinOpenKitchenGarbage(CommandParamSetOpen *setOpen,cJSON *objCmd)
{
cJSON *objPara = NULL;
if (setOpen== NULL || objCmd == NULL) {
RaiseLog(LOG_LEVEL_ERR, "NULL POINT!\n");
return -1;
}
memset(setOpen, 0x00, sizeof(CommandParamSetOpen));
if ((objPara = cJSON_GetObjectItem(objCmd, "OpenKitchenGarbage")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "Could not get paras in json");
return -1;
}
if (0 == strcmp(cJSON_GetStringValue(objPara), "ON")) {
Dustbin_open_K();
}
else {
Dustbin_close_K();
}
return 0;
}
static int Getcommand_dustbinOpenOtherRubbish(CommandParamSetOpen *setOpen,cJSON *objCmd)
{
cJSON *objPara = NULL;
if (setOpen== NULL || objCmd == NULL) {
RaiseLog(LOG_LEVEL_ERR, "NULL POINT!\n");
return -1;
}
memset(setOpen, 0x00, sizeof(CommandParamSetOpen));
if ((objPara = cJSON_GetObjectItem(objCmd, "OpenOtherRubbish")) == NULL) {
RaiseLog(LOG_LEVEL_ERR, "Could not get paras in json");
return -1;
}
if (0 == strcmp(cJSON_GetStringValue(objPara), "ON")) {
Dustbin_open_O();
}
else {
Dustbin_close_O();
}
return 0;
}
语音开发板识别一级命令:“你好,垃圾桶”成功后,说出第二级控制命令后,通过UART串口协议输出cJson包:Open_R、Open_U、Open_K、Open_O,需要hi3861对接口进行监听,以保证不会漏掉语音命令
void UartInit(void){
RaiseLog(LOG_LEVEL_INFO,"[2022012x01] entry into UartInit");
IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_0);
HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_UART1_TXD);
IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_1);
HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_UART1_RXD);
hi_uart_attribute uart_attr = {
.baud_rate = UART_BAUD_RATE, /* baud_rate: 9600 */
.data_bits = UART_DATA_BITS, /* data_bits: 8bits */
.stop_bits = UART_STOP_BITS,
.parity = 0,
};
RaiseLog(LOG_LEVEL_INFO,"[2022012x01] uart_init success");
/* Initialize uart driver */
hi_u32 ret = hi_uart_init(HI_UART_IDX_1, &uart_attr, HI_NULL);
if (ret != HI_ERR_SUCCESS)
{
printf("[220214x02]Failed to init uart! Err code = %d\n", ret);
return;
}
}
static void *uart_demo_task(void)
{
static uint16_t countSendTimes = 0;
static uint8_t countReceiveTimes = 0;
g_uartController.isReadBusy = false;
printf("[Initialize uart successfully\n");
while (1)
{
osDelay(50);
UartReceiveMessage();//Collecting Serial Port Data
hi_sleep(SMART_CAN_SLEEP_2500MS);
}
return 0;
}
void uart_task_create(void)
{
RaiseLog(LOG_LEVEL_INFO,"uart_task_create");
osThreadAttr_t attr;
attr.name = "uartTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = UART_DEMO_TASK_STAK_SIZE;
attr.priority = CONFIG_TASK_UART_PRIOR;
if (osThreadNew((osThreadFunc_t)uart_demo_task, NULL, &attr) == NULL)
{
printf("[220214x02]Falied to create uart_demo_task!\n");
}
}
static void UartReceiveMessage(void)
{
char *recData;
printf("----Listening----");
RaiseLog(LOG_LEVEL_INFO,"Start Listening serial port");
if (UartIsBufEmpty())
{
return;
}
if (g_uartController.isReadBusy)
{
return;
}
g_uartController.isReadBusy = true;
g_ReceivedDatalen = hi_uart_read(DEMO_UART_NUM, g_uart_buff, UART_BUFF_SIZE);
if (g_ReceivedDatalen > 0)
{
printf("UartReceiveMessage rcvData len:%d,msg:%s.\n", g_ReceivedDatalen, g_uart_buff);
setVoiceCommand();//Setting voice Commands
memset(g_uart_buff, 0, sizeof(g_uart_buff));
g_ReceivedDatalen = 0;
}
g_uartController.isReadBusy = false;
}
static void setVoiceCommand(void)
{
if (strstr(g_uart_buff, "Open_R") != NULL)
{
printf("[220214x02]listened Open_R\n");
Dustbin_open_R();
printf("[220214x02] Delay 10s close_R\n");
osDelay(1000);
Dustbin_close_R();
}else if (strstr(g_uart_buff, "Open_U") != NULL)
{
printf("[220214x02]listened Open_U\n");
Dustbin_open_U();
printf("[220214x02] Delay 10s close_U\n");
osDelay(1000);
Dustbin_close_U();
}else if (strstr(g_uart_buff, "Open_K") != NULL)
{
printf("[220214x02]listened Open_K\n");
Dustbin_open_K();
printf("[220214x02] Delay 10s close_K\n");
osDelay(1000);
Dustbin_close_K();
}else if (strstr(g_uart_buff, "Open_O") != NULL)
{
printf("[220214x02]listened Open_O\n");
Dustbin_open_O();
printf("[220214x02] Delay 10s close_O\n");
osDelay(1000);
Dustbin_close_O();
}
}