(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

Datasheet

2

HC-05 Bluetooth Module

Bluetooth Radio Connection

Datasheet

3

220-5V AC-DC Adapter

Powering the circuit

Datasheet

4

LED or Mosfets or Relays

To System Output

Datasheet


组件名称

角色

技术文件链接

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

Link

2

GNU-ARM

C-Compiler for ARM processors

Link

3

Jlink

Programmer and Debugger

Link

4

HERCULES

SerialPort Monitoring Software

Link

5

Arduino Voice Control

Android Application to send data to our device

Link


软件名称

角色

链接和参考

1个

STM32立方体

用于编码我们指令的IDE

链接

2

GNU-ARM

适用于ARM处理器的C编译器

链接

3

捷联

程序员和调试器

链接

4

苦力

串行端口监控软件

链接

5

Arduino语音控制

Android应用程序将数据发送到我们的设备

链接


语音助手 架构 语音助手产品_python_02


(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.

翻译自: https://habr.com/en/post/475960/