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.
7 years, 1 month ago.
serial getc() buffering issue.
Greetings.
I'm working with a STM32L4 NUCLEO board to test a NBIoT module. To test the module I want to write AT commands by keyboard, BUT I do not want to bridge the keyboard directly to the modem [putc (getc ())].
to achieve this I did a small program that follows this process:
1-print a message on the screen to request AT command.
2-with the keyboard the command is written and I make an echo to see what RXbuffer receives.
3- that command is written to an RX buffer.
4- once I get the Rx buffer I copy it to a TX buffer, when I copy it all I delete the RX buffer.
5- Send the tx buffer to the modem so that it responds to me.
6- Copy the modem's response in Rx buffer and send it to the screen.
The idea of using two buffers is to be able to have control over the input of the keyboard before sending it to the modem (allows to delete if you misspell the AT command and I can know when it stops typing looking for 0xD hexadecimal).
The problem now arises: What I type by keyboard and what stores RX buffer does not match (garbage receive). I have tested the rest of the program individually and it works (the modem responds to commands when I send them directly). Teraterm is configured as USART are in 9600 B / s 8n1 the 2 usart I use and the modem also have that configuration.
I think it is a processing speed problem in getc() function, I have tried to remove the echo to the pc and add waits but what I type by keyboard and what I receive still does not match.
Here is the code:
AT Spaming
#include "mbed.h" #define TRUE 0x01 #define FALSE 0x00 DigitalOut powerPin(D7); Serial UBLOX(D1,D0,9600); Serial PC(A0,A1,9600); char reading_complete = 0; Timeout time_trigger; char data_read = FALSE; char serial_rx_buffer[128]; float END_TIMEOUT = 0.2; /************************************************** ****************read_timeout************************ Antiblocking ***************************************************/ void read_timeout() { PC.printf("\r\n End of reading\n"); reading_complete = 1; } /************************************************** ****************int read_serial************************ Funcion para leer de Serie Function to read Serial return: int with number of readed bytes ***************************************************/ int read_serial (char *buffer, float end_timeout) { char token=0; int i=0; reading_complete = 0; time_trigger.attach(&read_timeout, end_timeout); // configure timeout that do the end of reception do { while(UBLOX.readable()==0 && reading_complete == 0); // wait to readable flag if(reading_complete ==0) { token=UBLOX.getc(); buffer[i++]=token; time_trigger.attach(&read_timeout, end_timeout); } }while (reading_complete == 0); buffer[i] = 0; time_trigger.detach();//detach the interrupt return i; } /************************************************** ****************int read_PC************************ read from keyboard function Store the input in a buffer, read until receive 0xD allows supr we have end_timeout seconds until the function finish if nothing is writed return: number of readed bytes ***************************************************/ int read_PC(char *buffer, float end_timeout){ char token=0;//almacena el byte int i=0; reading_complete = 0; time_trigger.attach(&read_timeout, end_timeout); // configure timeout that do the end of reception do { while(PC.readable()==0 && reading_complete == 0); // // wait to readable flag if(reading_complete == 0){ token=PC.getc(); PC.putc(token); // time_trigger.attach(&read_timeout, end_timeout); // configuramos el timeout que marcará el fin de la recepcion /* buffer[i++]=token; //wait(0.2); if(buffer[i-1]==0xD){//se ha pulsado enter reading_complete=1; i--; break; } */ if(token==0x8 && i>0){//if you type delete i--; }else{ buffer[i++]=token; if(token==0xD){//enter is pulsed reading_complete=1; i--; break; } } } }while (reading_complete == 0); reading_complete=0; time_trigger.detach(); //end interrupt return i; } /*main*/ void main() { char read_buffer[256],write_buffer[256]; int bytes_read,i; PC.printf("\r\n MODEM START...\n"); powerPin.write(1); for (i=10; i>=0; i--) { wait(1); PC.printf("\r%d ",i); } PC.printf("\n"); while(1) { bytes_read=0; memset(read_buffer,0,256);//reset RXbuffer PC.printf("\n\r Type AT comand\n\r"); bytes_read=read_PC(read_buffer, 10);//read from keyboard input function PC.printf("\n\r ending typing\n\r"); PC.printf("\r Read %d bytes\n\r%s\n",bytes_read, read_buffer); for(i=0;i<=bytes_read;i++){//copy the rx_buffer to TX_buffer write_buffer[i]=read_buffer[i]; /*if(i==bytes_read){ write_buffer[i]='/0'; } */ } memset(read_buffer,0,256);//Reset Rx_buffer if(bytes_read>0){//if typing received PC.printf("\n\r Send to modem the next petition: \n\r%s\n\r",write_buffer);//see what modem receives bytes_read=0; UBLOX.printf("\n\r%s",write_buffer);// Send tx_buffer to the modem bytes_read = read_serial (read_buffer, 0.2);//read modem answer memset(write_buffer,0,256);//reset tx_buffer PC.printf("\r\n Read %d bytes\n\r%s\n",bytes_read, read_buffer); } wait(2);//wAIT 2 secs until restart the loop } }
teraterm capture: in the picture you can see that im typping : AT+NCONFIG? but the buffer receives and echo me garbage
the extra number of bytes is for \r\n in the beggining and ending of the AT comand. Thanks for your help, Igm