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

/media/uploads/igm/writing_garbage.png

the extra number of bytes is for \r\n in the beggining and ending of the AT comand. Thanks for your help, Igm

Be the first to answer this question.