Your receiver code still has a mistake in it.
data[j] = serial_Rx();
In this loop you are still overindexing the
data array, which is only a size of 2. You should increase its size to 101 to match your
for loop. Probably a smaller value will be sufficient too, but the size of the array should match the
As I see on hyperterminal, Local Echo is disabled on your module so it will reply to most of the commands with
"\r\nERROR\r\n". (With Local Echo enabled it would return the command too). So the longest message that you could receive is the error message which is 9 characters long.
char data; //9 for data 1 for terminating null character
data[j] = serial_Rx();
data = '\0'; // close string with a terminating null character
Now, the response is presented in the array as a proper string. It is ready to be processed either by your own functions or by the standard C String library (
Or you can still send the whole string to hyperterminal as well
Process the result of the previous code with strstr() function of string.h
if(strstr(data,"OK") != NULL)
// it contains "OK"
// do stuff
More accurate way to receive serial data is to enable UART receive complete interrupts by setting
RXCIE bit in the
UCSRB |= (1<<RXCIE);
If you look at the possible responses, the effective information is enclosed between a
'\n' and a
'\r' characters which makes excellent start and end conditions when parsing the GSM's response in the interrupt service routine.
The complete code is the following:
UCSRB |= (1<<TXEN)|(1<<RXEN)|(1<<RXCIE); // enable receive interrupts
UCSRC |= (1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);
UBRRL = 51;
void serial_Tx(char *str)
for (unsigned int i=0;str[i]!=0;i++)
while(!(UCSRA & (1<<RXC)));
void uart_put(char data)
// global variables for UART rx
int buffer_index = 0, started = 0;
unsigned char buffer;
unsigned char k;
k = UDR;
if(k == '\r' && started == 1) // stop if is has already started and "\r" received
started = 2; // finished, ready for further processing
buffer[buffer_index] = '\0'; // terminate string
else if(started == 1) // if started save data
buffer[buffer_index++] = k;
else if(k == '\n') // start saving data at first "\n"
started = 1; // set process started
DDRA = 0x00;
DDRC = 0xFF;
PORTA = 0xFF;
buffer_index = 0;
started = 0;
if(started == 2) // check if rx is finished
// check if OK
So the structure of the messages we are expecting is the following:
<\r><\n><data><\r><\n>. Based on this, we want to start saving the incoming data after the first
\n was detected and keep it up until we reach a
Now the roles of the used variables:
k is a temporary variable into which the received chars are loaded, then we can check if it is a
\r or data char and handle accordingly.
started is for tracking the different phases:
started = 0 means, we did not receive the first
\n so far, so we keep waiting (
else if(k == '\n') branch ). Once a
\n arrives we set it to
1 indicating that we can start loading the received chars (
k) into our array.
started = 1 means that the start condition has been fulfilled, data can be stored in the array.
started = 2 when the processing has been started, so if the previous value was
1 and we received a
if(k == '\r' && started == 1) branch). Value
2 stops the loading of the array and indicates to the main function that the complete data is presented in the array.
I have a GSM module connected to an AVR too, so I tested the code of the ISR and get the following result:
data will contain