

Assistente de voz doméstica inteligente AHURATUS
Desenvolvido por Ehsan Shaghaei
Universidade de Innopolis
Clube Científico AHURATUS .

1. Introdução
O AHURATUS Smart Home Voice Assistant é um dispositivo IOT desenvolvido para controlar outros dispositivos domésticos por detecção de voz. Nota: Este dispositivo é feito SOMENTE para fins acadêmicos.
Abordagem
Descrição do produto
O "AHURATUS Smart Home Voice Assistant" usa um processo ARM Cortex-M3 para executar as instruções e vários dispositivos periféricos, a fim de diminuir a complexidade dos cálculos do barramento de dados e do circuito de RF.
Lista de materiais
Bancada e softwares

Detalhes
Utilizamos drivers HAL que foram fornecidos pelo fabricante do processador para reduzir a complexidade da verificação de falhas e o uso direto de periféricos. Utilizamos o HC-05 para receber dados de nosso usuário através de uma conexão sem fio, definindo as configurações do módulo através do seguinte comando AT:
Transmitir: AT + UART = 115200, 0, 0
Resposta: OK
_ Nota: Para aplicar os comandos AT, é necessário conectar o pino KEY ao nível ALTO.
usando STM32CubeIDE, configuramos os registros periféricos da seguinte maneira:
- UART2 (porta serial HC-05):
huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); }
- UART1 (Porta serial de monitoramento através da porta padrão RS-232):
huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); }
- Canais DMA 11, 15 e 16 (acesso direto à memória para UART2 RX e UART1 RX e UART1 TX respectivamente.):
/* DMA controller clock enable */ __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA interrupt init */ /* DMA1_Channel1_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* DMA1_Channel5_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); /* DMA1_Channel6_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
Além disso, definimos os modos GPIO da seguinte forma para conduzir nossos LEDs ou outros dispositivos.
/* GPIO Ports Clock Enable */ __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOF, LED3_Pin|GPIO_PIN_7|LED1_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, LED4_Pin|GPIO_PIN_2, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6|LED2_Pin|GPIO_PIN_11, GPIO_PIN_RESET); /*Configure GPIO pin : PE2 */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /*Configure GPIO pins : PE3 PE4 PE6 */ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /*Configure GPIO pin : PE5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /*Configure GPIO pins : LED3_Pin PF7 LED1_Pin */ GPIO_InitStruct.Pin = LED3_Pin|GPIO_PIN_7|LED1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : LED4_Pin PB2 */ GPIO_InitStruct.Pin = LED4_Pin|GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PB10 */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PB11 */ GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pins : PG6 LED2_Pin PG11 */ GPIO_InitStruct.Pin = GPIO_PIN_6|LED2_Pin|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /*Configure GPIO pin : PG8 */ GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
Finalmente, escrevemos o seguinte código na função c main()
para executar nosso algoritmo de decodificação de comando:
HAL_UART_Transmit(&huart1,"Ping->> AHURATUS VOICE ASSISTANT\r\n", sizeof("Ping->> AHURATUS VOICE ASSISTANT\r\n"), 1); int i; for (i=0; i<100;i++){ data[i] = '\0'; } HAL_UART_Receive_DMA(&huart2, data, sizeof(data)); while (1) { if(strlen(data)>2){ if(strcasecmp( data,"Hey")==0){ HAL_UART_DMAStop(&huart2); HAL_UART_Transmit(&huart1, "How can I help you ?\r\n", sizeof("How can I help you ?\r\n"), 100);//Users Signal Receieved! int i; for (i=0; i<100;i++){ data[i] = '\0'; } HAL_UART_Receive_DMA(&huart2, data, sizeof(data));// Polling for new data int FLG = 1; while(!strlen(data)){ if(FLG){ HAL_UART_Transmit(&huart1, "Polling for Command ...\r\n", sizeof("Polling for Command ...\r\n"), 1); } FLG= 0; //wait... } HAL_Delay(200);//short delay to recieve the rest of data; if( (!strcasecmp(data,"turn on light one")) ||(!strcasecmp(data,"turn on light 1")) ){ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_GPIO_Port,GPIO_PIN_SET); HAL_UART_Transmit(&huart1, "Light 1 Turned ON\r\n", sizeof("Light 1 Turned ON\r\n"), 1); }else if( (!strcasecmp(data,"turn off light one")) ||(!strcasecmp(data,"turn off light 1")) ){ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_GPIO_Port,GPIO_PIN_RESET); HAL_UART_Transmit(&huart1, "Light 1 Turned OFF\r\n", sizeof("Light 1 Turned OFF\r\n"), 1); }else if( (!strcasecmp(data,"turn on light two")) ||(!strcasecmp(data,"turn on light 2")) ){ HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_GPIO_Port,GPIO_PIN_SET); HAL_UART_Transmit(&huart1, "Light 2 Turned ON\r\n", sizeof("Light 2 Turned ON\r\n"), 1); }else if( (!strcasecmp(data,"turn off light two")) ||(!strcasecmp(data,"turn off light 2")) ){ HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_GPIO_Port,GPIO_PIN_RESET); HAL_UART_Transmit(&huart1, "Light 2 Turned OFF\r\n", sizeof("Light 2 Turned OFF\r\n"), 1); }else if( (!strcasecmp(data,"turn on light three")) ||(!strcasecmp(data,"turn on light 3")) ){ HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_GPIO_Port,GPIO_PIN_SET); HAL_UART_Transmit(&huart1, "Light 3 Turned ON\r\n", sizeof("Light 3 Turned ON\r\n"), 1); }else if( (!strcasecmp(data,"turn off light three")) ||(!strcasecmp(data,"turn off light 3")) ){ HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_GPIO_Port,GPIO_PIN_RESET); HAL_UART_Transmit(&huart1, "Light 3 Turned OFF\r\n", sizeof("Light 3 Turned OFF\r\n"), 1); }else if( (!strcasecmp(data,"turn on light four")) ||(!strcasecmp(data,"turn on light 4")) ){ HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_GPIO_Port,GPIO_PIN_SET); HAL_UART_Transmit(&huart1, "Light 4 Turned ON\r\n", sizeof("Light 4 Turned ON\r\n"), 1); }else if( (!strcasecmp(data,"turn off light four")) ||(!strcasecmp(data,"turn off light 4")) ){ HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_GPIO_Port,GPIO_PIN_RESET); HAL_UART_Transmit(&huart1, "Light 4 Turned OFF\r\n", sizeof("Light 4 Turned OFF\r\n"), 1); } }else{ HAL_UART_Transmit(&huart1, "ERROR-> INVALID Command\r\n", sizeof("ERROR-> INVALID Command\r\n"), 1); } HAL_UART_DMAStop(&huart2); for (i=0; i<100;i++){ data[i] = '\0'; }//makes the buffer empty HAL_UART_Receive_DMA(&huart2, data, sizeof(data)); } }
Posteriormente, usamos um dispositivo Android para conectar-se ao nosso sistema por Bluetooth . usamos o aplicativo "Arduino Voice Control" para enviar voz ao nosso sistema.
pela palavra-chave "HEY", nosso sistema pesquisa os próximos comandos e segue seus comandos de voz, conforme mencionado acima.
Conclusão
O projeto "AHURATUS Smart Home Voice Assistant" pode ser usado para ter um dispositivo doméstico inteligente funcional simples e barato, com algumas modificações simples no circuito; como:
- Usando um MOSFET e um circuito de isolamento CA para controlar dispositivos com tensões de trabalho CA
- Usando a modulação por largura de pulso (PWM) para ter mais controle sobre a saída
- Use TRIAC para ter um setter de nível de luz ajustável
- Projete um aplicativo melhor para ter uma melhor interação com o usuário
- use o Kinect ou outros dispositivos de detecção de movimento para medir a compatibilidade do dispositivo com os gestos dos usuários.
Atenciosamente,
Ehsan shaghaei
Entre em contato comigo