(AHURATUS Smart Home Voice Assistant)
Ehsan Shaghaei Ehsan Shaghaei开发 Innopolis University 创意大学 AHURATUS Scientific Club. AHURATUS科学俱乐部。
(Introduction)
AHURATUS Smart Home Voice Assistant is an IOT device developed in order to control other home devices by voice detection. Note: This device is made ONLY for academic purposes.
AHURATUS智能家庭语音助手是一种物联网设备,旨在通过语音检测来控制其他家庭设备。 注意:此设备仅用于学术目的。
(Approach)
(Description)
"AHURATUS Smart Home Voice Assistant" uses an ARM Cortex-M3 process for running the instructions as well as several peripheral devices in order to decrease the complexity of data bus and RF-Circuit calculations.
“ AHURATUS智能家庭语音助手”使用ARM Cortex-M3进程运行指令以及几个外围设备,以降低数据总线和RF电路计算的复杂性。
(Bill of Materials)
# | Component Name | Role | Technical Document links |
1 | STM32F103ZET6 | Process and Control | |
2 | HC-05 Bluetooth Module | Bluetooth Radio Connection | |
3 | 220-5V AC-DC Adapter | Powering the circuit | |
4 | LED or Mosfets or Relays | To System Output |
# | 组件名称 | 角色 | 技术文件链接 |
1个 | STM32F103ZET6 | 过程与控制 | |
2 | HC-05蓝牙模块 | 蓝牙无线电连接 | |
3 | 220-5V AC-DC适配器 | 电路供电 | |
4 | LED或Mosfet或继电器 | 至系统输出 |
(Workbench and Softwares)
# | Software Name | Role | Links and refrences |
1 | STM32CubeIDE | IDE for Coding our instruction | |
2 | GNU-ARM | C-Compiler for ARM processors | |
3 | Jlink | Programmer and Debugger | |
4 | HERCULES | SerialPort Monitoring Software | |
5 | Arduino Voice Control | Android Application to send data to our device |
# | 软件名称 | 角色 | 链接和参考 |
1个 | STM32立方体 | 用于编码我们指令的IDE | |
2 | GNU-ARM | 适用于ARM处理器的C编译器 | |
3 | 捷联 | 程序员和调试器 | |
4 | 苦力 | 串行端口监控软件 | |
5 | Arduino语音控制 | Android应用程序将数据发送到我们的设备 |
(Details)
We use HAL drivers which were provided by the processor manufacture in order to reduce the complexity of fault checking and straight forward usage of peripherals. We use HC-05 in order to receive data from our user via a wireless connection by setting the module settings trough the following AT command:
我们使用处理器制造商提供的HAL驱动程序,以减少故障检查和直接使用外围设备的复杂性。 我们使用HC-05,以便通过以下AT命令设置模块设置来通过无线连接从用户接收数据:
Response: OK
回应:可以
_ Note: In order to apply AT Commands you need to connect the KEY pin to the HIGH level.
_注:为了应用AT命令,您需要将KEY引脚连接到HIGH电平。
by using STM32CubeIDE we set the peripheral registers as follows:
通过使用STM32CubeIDE,我们如下设置外设寄存器:
- UART2 (HC-05 Serial Port):
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 (Monitoring Serial Port Trough RS-232 Standard Port):
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();
}
- DMA Channels 11, 15 and 16 (Direct Memory Access for UART2 RX and UART1 RX and UART1 TX respectively.):
/* 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);
Furthermore, we set the GPIO modes as following in order to Drive our LEDs or other Devices.
此外,为了驱动LED或其他设备,我们将GPIO模式设置如下。
/* 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);
Finally, we write the following code in c main()
function in order to execute our command decoding algorithm :
最后,我们在c main()
函数中编写以下代码,以执行命令解码算法:
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));
}
}
Afterward, we use an android device to connect to our system by Bluetooth. we use "Arduino Voice Control" application in order to send voice to our system. by Keyword "HEY" our system polls for the next commands and follows your voice commands as mentioned above.
之后,我们使用android设备通过Bluetooth连接到我们的系统。 我们使用“ Arduino语音控制”应用程序将语音发送到我们的系统。 如上所述,通过关键字“ HEY”,我们的系统将轮询下一个命令,并遵循您的语音命令。
(Conclusion)
"AHURATUS Smart Home Voice Assistant" project can be used in order to have a simple and cheap functional smart home device by a few simple modifications in the circuit; such as:
通过对电路进行一些简单的修改,可以使用“ AHURATUS智能家庭语音助手”项目,以拥有一种简单而廉价的功能智能家庭设备; 如:
- Using a MOSFET and an AC Isolation Circuit to control devices with AC working voltages
- Using Pulse Width Modulation (PWM) in order to have more control over the output
- Use TRIAC to have a adjustable light level setter
- Design a better application to have better interaction with user
- use Kinect or other Motion Detection Devices to measure make the device compatible with users gestures.