# MBED slow serial communication

#### Dritech

Joined Sep 21, 2011
869
Hi all,

I was using the code below to display four analog inputs on the computer through serial communication.The MCU that I am using is the LPC1768.
From the plots I noticed that the MBED code is slow since I was getting a very low quality graph.
Can someone please guide me on what I am doing wrong?

C:
#include "mbed.h"

// Initialize a pins to perform analogue input fucntions

// USB serial (TX, RX)
Serial pc(USBTX, USBRX);

int main(void)
{
// Declaring variables to be used for the ADC voltages

while (1)
{

// Send the five ADC values to serial port
}
}
Moderators note: used code tags for C

Last edited by a moderator:

#### MrChips

Joined Oct 2, 2009
22,550
Stop using floating point and you will regain a lot of speed and memory space.

#### jjw

Joined Dec 24, 2013
561
How fast it should be?
The default serial speed is 9600bd, so printing about 4*8 characters takes ~ 4ms + the time used by the printf function.
I think you can use faster serial speed?

Btw. in the printf function there are five %f parameters, but only four variables to be printed.

#### Dritech

Joined Sep 21, 2011
869
Stop using floating point and you will regain a lot of speed and memory space.
Thanks for the reply. Since the ADC result is a floating value, what can I use instead of a floating data type?

#### Dritech

Joined Sep 21, 2011
869
How fast it should be?
The default serial speed is 9600bd, so printing about 4*8 characters takes ~ 4ms + the time used by the printf function.
I think you can use faster serial speed?
Hi, I need to display a four 1kHz signals at reasonable quality. How can I determine the baud rate required?

Btw. in the printf function there are five %f parameters, but only four variables to be printed.
Sorry that was a typo.

Last edited:

#### jjw

Joined Dec 24, 2013
561
Mbed supports at least 112500 bd, maybe also higher speeds.
Thanks for the reply. Since the ADC result is a floating value, what can I use instead of a floating data type?
You can have the ADC result with 16bit unsigned integer value.
Serial interfacing etc. is explained in mbed.org
What is at the receiving end?
PC terminal or some graphical display?
Can you do some processing at the receiving end?

#### Dritech

Joined Sep 21, 2011
869
The receiving end is a computer and I am using MATLAB to display the plots, but I need to do the processing on the MCU since it will be used as a standalone device. I am only using MATLAB to confirm that the processing of the signals is correct and for better visualisation of the processed signals.

Last edited:

#### jjw

Joined Dec 24, 2013
561
You can do adc at full speed, save the data into arrays and at the end send the arrays to pc.
If the conversion with floats is too slow, use 16bit unsigned integers.
The adc sampling speed is at least 200kHz and is more than enough for four 1kHz channels.

#### jjw

Joined Dec 24, 2013
561
I tested this on Nucleo board ( stm32F401RE / 84MHz )
ADC for 4 channels takes 15us / round, so 66 samples / 1kHz period / channel.
STM32F401 has a floating point unit, but with integer values you should get about the same speed.

C:
#include "mbed.h"

#define N_Samples 100

// Nucleo stm32F401re . Initialize 4 pins to perform analogue input functions.

// USB serial (TX, RX)
Serial pc(USBTX, USBRX);

Timer t;

int main(void)
{
// Declaring variables to be used for the ADC voltages

int i;

t.reset();
t.start();

for ( i=0; i< N_Samples; i++ ){

}

t.stop();
pc.printf("\nTime for one round= %f us\n", t.read()*1000000/N_Samples);

// Send the ADC values to serial port
// Values from the last round

}

[\code]

#### Dritech

Joined Sep 21, 2011
869
Thanks for the reply. I tried using the ADC in integer data type by following the link you mentioned previously.
I did as follows:

This did not work. What am I doing wrong? Is "int ADC_int" the way to declare the variable (since it is a 16-bit integer)?

#### jjw

Joined Dec 24, 2013
561
Thanks for the reply. I tried using the ADC in integer data type by following the link you mentioned previously.
I did as follows:

This did not work. What am I doing wrong? Is "int ADC_int" the way to declare the variable (since it is a 16-bit integer)?
First, you can't multiply an integer with 3.3.
read_u16() returns unsigned short integer, normalized from 0 to 65535. With 12 bit ADC you can get the real value ( 0-4095 ) by dividing with 16

If you need to scale the values to real voltages ( 0 to 3.3V) you could multiply the values by 3300 and then divide by 65535 to get the results in millivolts.
I have not yet connected anything to ADC pins, so have not tested this.
The speed in stm32f401 is the same with integers and floats.

In mbed the default sizes are:
short = 16bit
int = 32b
long = 32b
long long = 64b

#### Dritech

Joined Sep 21, 2011
869
Hi again,

I connected a potentiometer to the ADC and turned it both directions for eight times to monitor the output through Putty.
I tried the following code:

C:
#include "mbed.h"
// Initialize a pins to perform analogue input fucntions

// USB serial (TX, RX)
Serial pc(USBTX, USBRX);

int main(void)
{
pc.baud(115200);

while (1)
{

// Send the five ADC values to serial port

}
}
and got this plot:

Then I replaced the the same code, but this time using a floating variable:

C:
#include "mbed.h"
// Initialize a pins to perform analogue input fucntions

// USB serial (TX, RX)
Serial pc(USBTX, USBRX);

int main(void)
{
pc.baud(115200);

while (1)
{

// Send the five ADC values to serial port

}
}
and got the following result:

As can be seen, the results are not correct when using integers. Any suggestions of what can be wrong?
In the code ADC_int = ((ain1.read_u16()&amp;0xFFF)*3.3/4095); , do I have to keep the "amp;" ? because the program was not compiling with it included in the code.

Moderators note: used code tags for C

#### jjw

Joined Dec 24, 2013
561
What is amp?

Don't mask the result with 0xfff, 0xffff is ok, if needed.

This should be ok:

#### djsfantasi

Joined Apr 11, 2010
7,236
An unsigned integer type has a maximum value of 65535. Since you are multiplying the ADC value by 3300, the ADC value cannot be greater than 19! Otherwise you will have overflow errors. Cast your input to an unsigned long and multiply by an unsigned long (3300ul, or however it is represented in your language). Divide by an unsigned long and then cast the entire calculation back to an unsigned integer.

You can even use integer arithmetic to get the result, and use this technique to obtain a floating point value in volts.

Calculating with mixed types and using division with integers can often be problematic. You have to consider the range of intermediate results. The technique I explained is an example of how I code to get around these limitations.