4 years, 8 months ago.

Serial Example Trouble

Hi, I'm trying to setup some UART based commands but I seem to be having trouble with detecting one of my longer commands. Two letters kept getting cut out while a third in between the two remains. When I loaded the following serial example from /handbook/Serial, I founded a rather unexpected behavior:

When I send over the following string "12345678" to the FRDM-KL25Z using CoolTerm I receive the following back:

Serial Output

1
2
3
4
6
8

I am using the following example code:

Attach to RX Interrupt

#include "mbed.h"
 
DigitalOut led1(LED1);
DigitalOut led2(LED2);
 
Serial pc(USBTX, USBRX);
 
void callback() {
    // Note: you need to actually read from the serial to clear the RX interrupt
    printf("%c\n", pc.getc());
    led2 = !led2;
}
 
int main() {
    pc.attach(&callback);
    
    while (1) {
        led1 = !led1;
        wait(0.5);
    }
}

Whats going on?

EDIT: Erik pointed that I was sending the "123456789" as quickly as my serial monitor was able to, which was too fast for the KL25Z to handle. My Serial Monitor, CoolTerm, has a transmit option to introduce a character delay and with a 3ms delay I was able to echo everything correctly. Thank you everyone who responded!

2 Answers

4 years, 8 months ago.

How do you send it? Manually one letter at a time, or does it buffer and that only for example when you press enter it sends everything at once? You send two chars back for every char you receive, so if it is receiving at its max speed it won't be able to send everything back, and stuff will get lost. But if you type manually this should not happen since you are way slower than the UART.

Accepted Answer

I am sending only a single string through CoolTerm's send string window. It sends the entire "12345678" in one go, however it only sends it once I press the window to send. Given that I am doing it manually there shouldn't be a speed issue.

posted by Krzysztof Sitko 08 Apr 2015

So then it will indeed send them all as fast as possible, and the board cannot reply that fast, since it has to send 2 bytes in return for every byte received. So this is expected.

posted by Erik Olieman 08 Apr 2015

I see. How should I send it so I don't run up against this problem? How slowly should I do it for this example?

posted by Krzysztof Sitko 08 Apr 2015

So I found an option in CoolTerm that adds a delay for every character that is transmitted. With a baud rate of 9600, 3ms works just fine for this example. Would implementing flow control also solve this problem?

I ask because I am working with a bluetooth device and moving the code over to that device seems to require a delay of 85ms per character for the entire string to be sent over consistently. This is however at a baudrate of 115200.

posted by Krzysztof Sitko 08 Apr 2015

85ms per character seems excessive, 3ms seems reasonable.

I don't think flow control lines are connected, and I also don't know if your bluetooth device will support those. In general it depends alot on what your setup needs to do, I assume it has a different task than echoing an incoming message. What can help alot is switching to BufferedSerial (search will give you link, I am lazy :P). This buffers the UART data, so as long as you don't completely fill the buffers it is transparant for your program, and any transmit operation will be done immediatly (well in reality it is just placed in the transmit buffer, but your program does not notice that).

posted by Erik Olieman 08 Apr 2015

I reached the 85ms experimentally, testing the return values over and over again while increasing the delay by 5ms until I received what I had sent consistently. I am using the BC127 which has CTS/RTS flow control with the lines connected to a KL25Z. The aim here is to be able to control a device over bluetooth using an iOS app. The device itself is a blood pressure cuff. So one command is to take a measurement, another is to halt measuring, send the last taken measurement, so on and so forth. I'm not that concerned with speed for this device, but I do have another one which will require the continuous transmission of a dozen data points that has been sampled at 250 sps.

Anyhow, if I use BufferedSerial, would that enable me to avoid the delay issue entirely?

posted by Krzysztof Sitko 08 Apr 2015

BufferedSerial should avoid it yes. Although if it is required depends on how you are going to use it exactly, although in general it isn't a bad anyway to use something like that.

posted by Erik Olieman 09 Apr 2015
4 years, 8 months ago.

By default, the hardware buffer in the K64F UART is not enabled. As I recall, the processor has 8 bytes on Rx and 8 on Tx. I tried to enable it a few months ago and ran into some issues, but had to quit working on that project. At the time, I could not get the buffer working at all, with or without interrupts.

I am interested in trying again, but if you look into it, please post back here. I will do the same.

Edit: I guess I answered as if you have a K64F, but I think the two have similar UART functionality.

Gary, Adding a delay between each character sent helped fix the problem for the above example code when connected over USB. I wanted to use this for a bluetooth device however, and for the device I am currently only able to have consistent communication when the delay is 85ms, which seems to me to be rather excessive.

posted by Krzysztof Sitko 08 Apr 2015