Pull to refresh

AHURATUS Smart Home Voice Assistant

Reading time 7 min
Views 1.8K

N|Solid


N|Solid


AHURATUS Smart Home Voice Assistant


Developed by Ehsan Shaghaei
Innopolis University
AHURATUS Scientific Club.

STM32F103ZET6 UNIVERSAL BOARD


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.


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.


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

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

STM32F103ZET6 UNIVERSAL BOARD


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:


Transmit: AT+UART = 115200, 0, 0
Response: OK
_ Note: In order to apply AT Commands you need to connect the KEY pin to the HIGH level.

by using STM32CubeIDE we set the peripheral registers as follows:


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


  /* 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 :


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.


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:


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

Regards,
Ehsan Shaghaei
Contact to me
Tags:
Hubs:
+14
Comments 1
Comments Comments 1

Articles