RX String on UART not working

atmegaavrreceiverserialuart

I am having some problems with UART communication with the RN-42 SM Bluetooth module. Currently, I am just using polling to get communication going. I have my source files below.

The problems is that I can send properly, however cannot receive. I have been able to receive PARTS of a response, but it seems that the Transmit, sends a command before I can receive the whole buffer.

Note also that I am trying to retrieve a string of values. So for example, if I send a '$$$', I get a 'CMD\r\n' in return. I am trying to retrieve the latter.

SOURCE FILE

DDRC |= 0xFF;
DDRD |= 0xFA;

initUART();
unsigned char pinRTS = 0;
unsigned char buffer[RXBUFSIZE] = {0};

UNSETCTS(PORTD);

while(1)
{
    PORTC ^= 0xFF;
    pinRTS = GETRTS(PIND);

    if(pinRTS == 0x00) { //Receiver is letting us send
        SETCTS(PORTD);
        transmitStr((unsigned char *)CMDMODE);  
        UNSETCTS(PORTD); 

        waitForRcv();
        rcvStr(buffer);

        SETCTS(PORTD);  
        transmitStr((unsigned char *)EXITCMD); 
        UNSETCTS(PORTD); 

        waitForRcv();
        rcvStr(buffer);        
    }             
}

HEADER BELOW

#include "serial.h"

void initUART() {   
    /* Set baud rate */
    UBRR0H = (unsigned char)(UBBRVAL >> 8);
    UBRR0L = (unsigned char)UBBRVAL;

    /* Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

    /* Set frame format: 8 data, 1 stop bit */
    UCSR0C = (3<<UCSZ00);

    /* Double the speed */
    UCSR0A |= (1 << U2X0);
}

void USART_TRANSMIT(unsigned char cmd) {
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A & (1 << UDRE0)) );

    /* Put data into buffer, sends the data */
    UDR0 = cmd;
}

void transmitStr(unsigned char *cmd) {
    int i;
    for(i = 0; cmd[i] != '\0' ;i++) {
        USART_TRANSMIT(cmd[i]);
    }    
}

unsigned char USART_RECEIVE()
{
    /* Wait for data to be received */
    while ( !(UCSR0A & (1 << RXC0)) );

    /* Get and return received data from buffer */
    return UDR0;
}

void rcvStr(unsigned char *buffer) {
    int i = 0;
    while ( UCSR0A & (1 << RXC0) )  {
        buffer[i] = UDR0;
        i++;
    }   
    UCSR0A |= (1 << RXC0); 
}

void waitForRcv()
{
    while ( !((UCSR0A >> RXC0) & 0x01) );
}

Thanks for your help. 🙂

Best Answer

Are you sure you're properly watching to see if the bluetooth module has filled up it's RX buffer? I'm really just not sure you're checking the RTS and CTS flags properly.

You should be checking the RTS and CTS flags every character, not just when you begin to send the whole string! If you fill up the RX buffer on the bluetooth module, currently you'll keep transmitting, even if the RTS or CTS flags change.

You should also check which version of handshaking your module uses: http://en.wikipedia.org/wiki/Rs232#RTS.2FCTS_handshaking

Last but not least, small nit-pick: Are you actually storing source code in a header? Please don't! Put the source in a separate file and just put the prototypes in the header!

Related Topic