4 years, 8 months ago.

HC-05 Bluetooth Serial communication

/media/uploads/mrozmus/missingdata.png Hi, I'm trying to achieve steady data stream from one HC-05 device to another. To be more precise, I'm trying to send microphone samples from one device (STM32F103C8T6) to another (STM32F767ZI). Unfortunately, even when I'm using BufferedSerial (https://os.mbed.com/users/sam_grove/code/BufferedSerial/), it seems, that some bytes are missing on the receiver side, as you may see on the attached PNG file. First number is sample number, second is what i get from transmitter, and last is normalized data (it doesn't matter at this point). I'm using 921600 baud rate for both HC05.

On the receiver side I have: (numSamples is an int, it's used for holding current number of samples, bt is BufferedSerial type object, readBuffer is table of unsigned char, with size 9, sample[0] is just a floating point table with one element)

receiver

    int numSamples = 0;
    while (1) 
    {
        while(numSamples!=8000)
        {
            if(bt.readable())
            {
                int readBytes = bt.readBytes(readBuffer, 9);
                if(readBytes == 9)
                {
                    sample[0] = atof((const char*)readBuffer);
                    sample[0] = normalizeSample(sample[0]);

                        waveAddSample(&mySound, sample);
                        printf("%i: %s : %f\n", numSamples, readBuffer, sample[0]);
                        memset(readBuffer, 0, sizeof(readBuffer));
                        numSamples++;
                }
            }
        }
    }

On transmitter side I have:

transmitter

void getSample()
{
    sample = mic;
}   

int numSamples = 0;
    tickRec.attach_us(getSample, 125);
    float oldSample = sample;
    printf("Connection with master device established\n");
    while(1)
    {   
        if(pc.readable())
        {
            if(pc.getc() == '$')
            {
                while(numSamples<20000)
                {
                    if(sample != oldSample)
                    {   
                        oldSample = sample;
                        sprintf(buffer, "%f", oldSample);                     
                        bt.printf("%sA", buffer);
                        memset(buffer, 0, sizeof(buffer));
                        numSamples++;
                    }
                }
            }
        }
    }

Can someone please take a look at this? Is it possible to send samples like this using HC05 modules?/media/uploads/mrozmus/missingdata.png

Hi, thank you for your answer, I really appreciate that. So, you said there is no any protecion here. May you tell me what you mean by that? How should I provide protection? Also, isn't "%4.4F" format specifies a format with 4 total characters, 3 chars before dot, dot itself and 4 chars after dot? I'm really sorry, but now I see that I forget to attach my implementation of readBytes method (it's method in BufferedSerial):

readBytes

size_t BufferedSerial::readBytes(uint8_t *bytes, size_t requested)
{
    int i = 0;
 
    if(this->readable())
    {
        for( ; i < requested; )
        {
            int c = getc();
            if( c < 0)
                break;
            bytes[i] = c;
            i++;
        }
    }
    return i;
} 

I have also changed memory allocated for buffer in BufferedSerial to 40000. I have attached image, I hope it's visable now.

posted by Mateusz Rozmus 29 Aug 2019

1 Answer

4 years, 8 months ago.

Hi Mateusz,

I'don't see the picture you upload. However in your code snippets, readBuffer will possibly overwrite the data just received from RxIrq or be changed by RxIrq, because there is no any protection here.

And I think you should use sprintf(buffer, "%4.4f", oldSample); to make sure the string is 9-byte long.

Thanks, Desmond

Accepted Answer

Hi, thank you for your answer, I really appreciate that. So, you said there is no any protecion here. May you tell me what you mean by that? How should I provide protection? Also, isn't "%4.4F" format specifies a format with 4 total characters, 3 chars before dot, dot itself and 4 chars after dot? I'm really sorry, but now I see that I forget to attach my implementation of readBytes method (it's method in BufferedSerial):

readBytes

size_t BufferedSerial::readBytes(uint8_t *bytes, size_t requested)
{
    int i = 0;
 
    if(this->readable())
    {
        for( ; i < requested; )
        {
            int c = getc();
            if( c < 0)
                break;
            bytes[i] = c;
            i++;
        }
    }
    return i;
} 

I have also changed memory allocated for buffer in BufferedSerial to 40000.

posted by Mateusz Rozmus 29 Aug 2019

Hi Mateusz,

Main thread and RxIrq may access the same buffer at the same time, and the buffer not protected by mutex/semaphore, that could lead the value is not correct. %4.4F means the format xxxx.yyyy which forms 9-byte long string, that makes sure the string consistent.

Thanks, Desmond

posted by Desmond Chen 30 Aug 2019

Hi Desmond, Okay I understand that. The problem is, that BufferedSerial class isn't using RTOS, which means that I can't use mutex here, am I right? Also about float formatting - my samples are in format X.YYYYYY. Is possible solution for this problem to just make BufferedSerial big enough to store all income data (which is 8000 samples * 8 chars = 64000), and then just read all the date? Eventually, could you please tell me how to protect this buffer?

posted by Mateusz Rozmus 30 Aug 2019