Communication between the STM32 and Android via Bluetooth

This article describes the organization of communication via Bluetooth between the microcontroller STM32 (used board STM32 Value Discovery) and any Android-powered device (smartphone, tablet, etc.). As the example shows LED control from the tablet, and sending messages back to Android from STM32 board.

As a Bluetooth module uses cheap Chinese module HC-06, which has been considered in this article.

Bluetooth Modules

As an Android device, I used a cheap Chinese tablet “Ainol Aurora” with an external USB-Bluetooth module (because its not have own), connected via USB Host.

Wiring diagram STM32 Discovery board to the module HC-06 is very simple:

mc169-1

The program for the STM32 was written in the environment CooCox CoIDE, and based on the standard example of STMicroelectronics UART communication.

Source code for STM32:

#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "misc.h"
 
int i;
 
//ErrorStatus HSEStartUpStatus;
 
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void USART1_IRQHandler(void);
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount);
 
int main(void)
{
    usart_rxtx();
    while(1)
    {
 
    }
}
 
/******************************************************************************/
/*            STM32F10x Peripherals Interrupt Handlers                        */
/******************************************************************************/
 
/**
  * @brief  This function handles USARTx global interrupt request
  * @param  None
  * @retval None
  */
void USART1_IRQHandler(void)
{
    if ((USART1->SR & USART_FLAG_RXNE) != (u16)RESET)
    {
        i = USART_ReceiveData(USART1);
        if(i == '1'){
            GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);        // Set '1' on PA8
            UARTSend("LED ON\r\n",sizeof("LED ON\r\n"));    // Send message to UART1
        }
        else if(i == '0'){
            GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);      // Set '0' on PA8
            UARTSend("LED OFF\r\n",sizeof("LED OFF\r\n"));
        }
    }
}
 
void usart_rxtx(void)
{
    const unsigned char welcome_str[] = " Welcome to Bluetooth!\r\n";
 
    /* Enable USART1 and GPIOA clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
 
    /* NVIC Configuration */
    NVIC_Configuration();
 
    /* Configure the GPIOs */
    GPIO_Configuration();
 
    /* Configure the USART1 */
    USART_Configuration();
 
    /* Enable the USART1 Receive interrupt: this interrupt is generated when the
         USART1 receive data register is not empty */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
    /* print welcome information */
    UARTSend(welcome_str, sizeof(welcome_str));
}
 
/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configures the different GPIO ports
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* Configure (PA.8) as output */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure); // Save
 
  /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* Configure USART1 Rx (PA.10) as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
 
/*******************************************************************************
* Function Name  : USART_Configuration
* Description    : Configures the USART1
*******************************************************************************/
void USART_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
 
/* USART1 configuration ------------------------------------------------------*/
  USART_InitStructure.USART_BaudRate = 9600;        // Baud Rate
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 
  USART_Init(USART1, &USART_InitStructure);
 
  /* Enable USART1 */
  USART_Cmd(USART1, ENABLE);
}
 
/**
  * @brief  Configures the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
 
/*******************************************************************************
* Function Name  : UARTSend
* Description    : Send a string to the UART.
* Input          : - pucBuffer: buffers to be printed.
*                : - ulCount  : buffer's length
*******************************************************************************/
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
    //
    // Loop while there are more characters to send.
    //
    while(ulCount--)
    {
        USART_SendData(USART1, (uint16_t) *pucBuffer++);
        /* Loop until the end of transmission */
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
        {
        }
    }
}

Code is simple: the function GPIO_Configuration () is configured GPIO of STM32 Board, in USART_Configuration()  configurable UART, and in the function NVIC_Configuration () is configuration the interrupt.

To send the string to UART uses function UARTSend(). When the data is received by an interrupt occurs and call function USART1_IRQHandler (). Depending on the assumed number 1 or 0, the command on the PA8 board ON or OFF the LED connected to it. And also, there is a transfer string “LED ON” or “LED OFF” back to UART (to Android device)

mcu1

Source code for Android, I will not lead, as he is big and is based on this article, with a few additions. You can download full project in Eclipse. Also, I attached APK file.

Download APK application for Android

Download source code and project in CooCox CooIDE for STM32 and Eclipse-project for Android

 

16 thoughts on “Communication between the STM32 and Android via Bluetooth”

    1. I am interested in this question too. I wrote personally to you asking almost the same. In my opinion I think everything should happen in the ConnectedThread run method. Make a while true loop and write to the outputStream from there, wait a little(maybe) and then read from the inputStream. Is that right? How would you do it? I am very interesting in this. I am trying myself very hard to make it working. I have something working but I get bluetooth timeouts. I am sure it is possible to do pooling, but how?

    1. I don’t know exact model. I used the cheapest Chinese. You can view it’s photo on [url=http://english.cxem.net/arduino/arduino4.php]this page[/url]

  1. Hi.I’m new in the programming of the st32 and hope that you can help me. My problem is that i compiler you program and i don’t have any problem but i check the USART whith a max 232 to comunicate with my pc but this not receive nothing and i check that the GPIO A work with other program where i blink a led and thit work. You dont know why the USART dont work? thank

  2. I did it today. I suggest that you do a boolean function readWrite() that whenever you write to outputStream you also read from the inputStream and send the readBuffer to UI with mHandler. If both read and write are ok, than return true, if one of them went wrong than return false and use resetConection before closing your ConnectedThread. See my answer here for the resetConnection. http://stackoverflow.com/questions/18420525/application-using-bluetooth-spp-profile-not-working-after-update-from-android-4/19025227#19025227

    But the answer about pooling is the following:
    In the ConnectedThread run() method do a while(true), call a method similar to readWrite(byte[] data) inside the loop, where in the first place you write something to the device, and then you read the data from the input stream. In this readWrite() method, if writing to outpustream went fine, then continue to read from the inputstream. if you got any data to the input stream, send the data to UI for processing with the mHandler (or do some processing before sending to the UI).

    It worked very nice for me. Unfortunately I can not write code here, but it wouldn’t make much sense because my program is kind of complicated (I am using other stuff inside) but the principle is the same and it should work.

  3. Hi,
    I haven’t bought the bluetooth module yet, so I want to know if there’s a way to check if it works or not (for ex

  4. Hi Admin!

    I have tried this code using Coocox v 1.7.6 but giving many errors. The first three errors as given below:

    [cc] C:\CooCox\CoIDE\workspace\abc_btooth1\main.c: In function ‘USART1_IRQHandler’:
    [cc] C:\CooCox\CoIDE\workspace\abc_btooth1\main.c:36:16: error: ‘USART_TypeDef’ has no member named ‘SR’
    [cc] if ((USART1->SR & USART_FLAG_RXNE) != (u16) RESET)
    [cc] ^
    [cc] C:\CooCox\CoIDE\workspace\abc_btooth1\main.c:36:44: error: ‘u16’ undeclared (first use in this function)
    [cc] if ((USART1->SR & USART_FLAG_RXNE) != (u16) RESET)
    [cc] ^
    [cc] C:\CooCox\CoIDE\workspace\abc_btooth1\main.c:36:44: note: each undeclared identifier is reported only once for each function it appears in
    [cc] C:\CooCox\CoIDE\workspace\abc_btooth1\main.c:36:49: error: expected ‘)’ before ‘RESET’
    [cc] if ((USART1->SR & USART_FLAG_RXNE) != (u16) RESET)[size=2][/size][size=3][/size]

    Could you please tell how to remove the errors.

  5. hi!. thanks for your share. but when i open STM project, i had error:
    [cc] C:\Users\ADMINI~1\AppData\Local\Temp\cc0rl9dc.s:818: Error: registers may not be the same — `strexh r3,r2,[r3]’
    [cc] C:\Users\ADMINI~1\AppData\Local\Temp\cc0rl9dc.s:772: Error: registers may not be the same — `strexb r3,r2,[r3]’
    can you help me. thanks you!

  6. hey i am using stm32f303vc discovery board and hc-o6 bluetooth moduleand try to send some data to pc through bluetooth. this is my first programme with controller so i am not able to figure out what is wrong with it . can u please help me .

    here is my programme

    #include
    #include”stm32f30x_gpio.h”
    #include”stm32f30x_rcc.h”
    #include”stm32f30x_usart.h”

    void USART_Printf_Example(void);

    int main()
    {
    volatile uint16_t a[5] = {1,2,3,4,5};
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource5,GPIO_AF_7);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource4,GPIO_AF_7);

    GPIO_StructInit(&GPIO_InitStruct);
    // Initialize USART1_Tx
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    // see stm32f10x_usart.h
    USART_InitTypeDef USART_InitStructure;
    // Initialize USART structure
    USART_StructInit(&USART_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;
    USART_Init(USART1,&USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
    while(1)
    {
    USART_SendData(USART1,a[5]);
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *