7 years, 4 months ago.

UART communication difficulty

Hello, I am using the FRDM KL46z MCU for my project.I am trying to communicate through UART at a baud rate of 250000.The MCU sends the signal correctly but I am having issues with reading the data.Through a logic analyzer, I get what I should get at the receiver of the MCU but I am not being able to read it and display on pc.

My code for reading is shown below:

void read_frame() { while(1) { if(bms.readable()) { while(bms.readable()) { char c = bms.getc(); pc.printf("data: %c",c); wait(0.5f); } break; } } }

here bms communicates at 250000 and pc at 9600 baud rates respectively.

1 Answer

7 years, 4 months ago.

Hi harsh. Not a user of the KL46z MCU but some quick comments:

please use <<code>><</code>> markers to make your code easier to read.

void read_frame() 
{
 while(1) 
{ 
 if(bms.readable())
 { while(bms.readable())
    { char c = bms.getc(); 
      pc.printf("data: %c",c); 
      wait(0.5f); } 
      break; 
    }
 } 
} 

1) from past readings, better to consider the buffered serial library for your project:

https://developer.mbed.org/users/sam_grove/code/BufferedSerial/

2) The baud rate is a function of your UART clock. Standard supported baud rates by mbed are:

The list of supported baud rates is:

110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600

reference: https://developer.mbed.org/forum/mbed/topic/893/

3) The 250kbps is not listed as a common value. This does not mean it is not possible but just that you may have to tweak the library or external clock source for your UART to frame this desired target baud rate.

4) This post notes that 250kbps is possible using rawserial - please test:

https://developer.mbed.org/questions/3394/UART-baud-rate/

With some google searches, see that the Nordic boards offer support for the 250kbps support but do not see the same for the KL46z.

https://developer.mbed.org/users/rllamado/code/mbed-src/diff/6c996abb70b0/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c

Try to use the bufferserial with baud(250000) on your KL46z and post your results.

Hello Harsh,

Glad to see you are making some progress. Not exactly clear on your logic and have not used bufferedserial myself but consider the following alternate use:

#include "mbed.h"
void read_frame()
{
 // crank up the baud rate parameters for the pc.printf to 115200 and then use the same settings for your PC terminal
 // (ie. Teraterm or whatever program is on the pc side)

  unsigned int i;
  unsigned int max_bytes;
  char my_read_data[255];

  for(i=0; i<max_bytes;i++)
    {             
        if(bms.readable())
           my_read_data[i] = bms.getc();
     }

  for(i=0; i<max_bytes;i++)
       pc.printf("%02x",my_read_data[i]);


} 

the idea is to just focus on the reading of your serial data from the outside world into a local buffer. After the buffered data is read, then proceed to print to your pc. The printf is a very very slow process as compared to the UART, especially since you are @ 9600 bps read so you should not be attempting to capture the serial data and then printing right away. This printf action will slow down the next serial read. Try the above and alter the value for max_bytes to confirm that the serial capture is solid for your project. Suspecting that the printf is slowing you down. Other mbed users may have better solutions than above but if you believe you will be streaming serial data at high data rates then perhaps you can consider a RTOS or multicore options. That is, one thread can be dedicated to only reading of the serial data and another for output, etc. Keep in mind that the serial read @ 250k will be always faster than the very slow printf. If you are just using the printf for early stage debugging than ok but the printf does not belong inside the serial capture loop. Consider the printf to be "blocking". That is our understanding of the posted code. Please post your results. Curious to learn if the above code snippet allows to capture all of your data reliably @ 250000 bps.

Accepted Answer

And also remove the half second wait between characters. That's almost sure to cause receive buffer overflows.

posted by Andy A 16 Dec 2016

Hello Sanjiv,

Thank you so much for your suggestions and the KL46z now communicates with bufferedSerial library at both 250k and 9600 baud rates.But I am facing another issue with the timings.My code for reading data from a serial device and print value to PC is shown below. It always takes close to 0.1s to empty the buffer and hence I have to wait for that period to break from the while loop to get complete data.Any suggestions on how to make this communication faster.

read Serial

#include "mbed.h"
void read_frame()
{
    t.start();
    while(1)
    {
               
        if(bms.readable())
        { 
            char c = bms.getc();
            pc.printf("%x ",c);
        }
        
        if(t.read_ms()>100) 
        {
            t.stop();
            t.reset();
            break;
        }
        
    }
} 
posted by harsh gugale 18 Dec 2016

Hello Sanjiv,

Sorry for the late reply.The above code snippet did the job.I also increased the pc UART rate to 250000 which provided even better timings.Thanks for your help!

posted by harsh gugale 22 Dec 2016