Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
6 years, 3 months ago.
UART does not return full strings
I'm making a test app with NUCLEO-L053R8 on mbed. I have some trouble.
My code is here.
#include "mbed.h" Serial pc(SERIAL_TX, SERIAL_RX); Serial self_uart(PA_9,PA_10); // tx, rx int main() { volatile char command[8]; unsigned int i = 0; pc.printf("Start!\r\n"); self_uart.baud(115200); while(1) { i = 0; self_uart.printf("hogehoge\r\n"); while(self_uart.readable()==0){ pc.printf("waiting\r\n"); wait(0.1); }; pc.printf("data received\r\n"); while(self_uart.readable()>0) { pc.printf("i=%d\r\n", i); command[i] = self_uart.getc(); i++; wait(0.1); } pc.printf("%s\r\n", command); wait(2.0); // 1 sec } }
PA_9 is connected to PA_10 so when self_uart send a message "hogehoge", the device itself receives the message.
The result is below.
Start! data received i=0 h test data received i=0 h test data received i=0 h
Only "h" returned, while "hogehoge" should have been returned.
Why? I spent a lot of time to solve this problem. Please help me!
1 Answer
6 years, 3 months ago.
Hi Yusuke,
I believe you can read this article written in Japanese. It says implementation of Serial class doesn't have software buffer. If you use printf()
to send a message, it cause overflow because the program send all the characters before receive.
According to Zoltan, your program worked on LPC1768. This is because LPC1768 has 16-byte hardware buffer. https://exploreembedded.com/wiki/LPC1768:_UART_Programming
I changed your code not to require buffer. This worked on NUCLEO-L053R8.
#include "mbed.h" Serial pc(SERIAL_TX, SERIAL_RX); Serial self_uart(PA_9,PA_10); // tx, rx const char message[] = "hogehoge\r\n"; int main() { volatile char command[11]; unsigned int i = 0; pc.baud(115200); pc.printf("Start!\r\n"); self_uart.baud(9600); while(1) { i = 0; char *p = (char*)message; do{ self_uart.putc(*p++); while(!self_uart.readable()) continue; command[i++] = self_uart.getc(); } while(*p != '\0'); command[i] = '\0'; pc.printf("%s\r\n", command); wait(2.0); // 1 sec } }
Hi, Osamu Koizumi If possible, could you show code in which NUCLEO-L053R8 communicate with another device through UART? I want to know how to write code sending and receiving data. If you tell it, it is really helpful.
posted by 22 Aug 2018Hi Yusuke,
Do you want to communicate between two Mbed devices? Check this FAQ: https://os.mbed.com/questions/77669/UARTshort-int-mbedmbed/
posted by 23 Aug 2018No, I want a mbed device to communicate with a 3g module, like Sierra wireless HL8548, through UART.
Mbed device ーーAT command ーー> HL8548
Mbed device <ーーresponse ーーーー HL8548
Do you know how to do this?
posted by 23 Aug 2018If you use AT command to communicate with your modem, see ATCmdParser. The example in this page uses serial and AT command.
posted by 23 Aug 2018Thank you so much for telling the command ATCmdParser!
I connected NUCLEO-L053R8 and eps8266 through UART.
I implemented the below code, which should get SDK version, but it does not work. SDK version does not show the correct value. Instead, SDK version = 0.0.0
I'm new to mbed and confused.
Could you tell me where is the mistake, if you find it?
my code
#include "mbed.h" #include "ATCmdParser.h" Serial pc(SERIAL_TX, SERIAL_RX); int main() { pc.printf("Hello World!\r\n"); UARTSerial serial = UARTSerial(PA_9,PA_10); ATCmdParser at = ATCmdParser(&serial, "\r\n"); int value1 = 0; int value2 = 0; int value3 = 0; while(1){ pc.printf("start\r\n"); at.send("AT+GMR") && at.recv("SDK version:%d.%d.%d", &value1, &value2, &value3) && at.recv("OK"); pc.printf("SDK version:%d.%d.%d\r\n", value1, value2, value3); // version should be 2.0.0 } }
If you are using ESP-WROOM-02 Shield, this code should work.
#include "mbed.h" #include "ATCmdParser.h" Serial pc(SERIAL_TX, SERIAL_RX); int main() { pc.printf("Hello World!\r\n"); // (*) Please wire D8 and D4 on ESP-WROOM-02 Shield // and toggle the hardware switch on the shield to SW UARTSerial serial = UARTSerial(PA_9,PA_10, 115200); // Set D4 as a input for protection DigitalIn pin_d4(D4); ATCmdParser at = ATCmdParser(&serial, "\r\n"); int value1 = 0; int value2 = 0; int value3 = 0; while(1){ pc.printf("start\r\n"); at.send("AT+GMR") && at.recv("SDK version:%d.%d.%d", &value1, &value2, &value3) && at.recv("OK"); pc.printf("SDK version:%d.%d.%d\r\n", value1, value2, value3); // version should be 2.0.0 wait(1); } }
By the way, if you use ESP8266, device driver already exists. Check it out: https://github.com/ARMmbed/esp8266-driver
posted by 24 Aug 2018I'm using this: http://akizukidenshi.com/catalog/g/gK-09758
Is this ESP-WROOM-02 Shield?
And if not, how to communicate between a mbed device and the above wifi device? Is ATCmdParser available?
posted by 24 Aug 2018That is different from ESP-WROOM-02 Shield: https://www.switch-science.com/catalog/2619/ However, the difference is just pinout. You should be able to do the same thing with your hardware.
posted by 24 Aug 2018
Yusuke,
Have you tried a lower baud rate below 115200 ?
posted by Kevin Braun 20 Aug 2018Hello Yusuke-san,
I have run your code on an LPC1768 and it worked fine. However, since
sends 10 characters, the
command
variable shall be sized adequately (+ one byte for the null termination character. See below why):Otherwise when
i > 7
would write to undefined memory location and the program could crash.
Also when a c-style string is printed with
printf
the string shall be null terminated as below: