Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

UART receive string from SIM808 module

Status
Not open for further replies.

akshaybhavsar

Full Member level 2
Joined
May 5, 2016
Messages
135
Helped
2
Reputation
4
Reaction score
2
Trophy points
18
Activity points
898
Hi,

I am using SIM808 module in my application.My UART is working as i receive byte.SIM808 module sends string.How do i receive string effectively?Is this a right way to receive string?

Code:
unsigned char Receive_char[100];
int i=0;

void interrupt ISR()
{
if(Receive_flag)
{
Receive_char[i++]=RCREG;
if(Receive_char[i]==NULL)
 i=0;
receive_flag=0;


}


}
 

Code:
void interrupt ISR()
{
 Receive_char[i++] = RCREG;
 if (Receive_char[i] == '\n') //detect end of string
 {
   receive_flag = 1; //rise the flag 'data ready'
   Receive_char[i] = 0; //terminate string with null
 }
}
 
Code:
void interrupt ISR()
{
Receive_char[i++] = RCREG;
if (Receive_char[i] == '\n') //detect end of string
{
receive_flag = 1; //rise the flag 'data ready'
if(strcmp(Receive_char,OK\r));
   {
         okreceived=1;
   }
else if(strcmp(Receive_char,ERROR\r));
   {
         Ereceived=1;
   }

else if(strcmp(Receive_char,Nocarrier\r));
   {
         Nocarrier=1;
   }
Receive_char[i] = 0; //terminate string with null
}
}


Like wise i need to get upto 20 different string

+CREG:
+CGREG:
+CSQ:
$GPGGA:
$GPRMC:
$CGPSINF:

It will be efficient to write if-else ladder in interrupt as it takes time?
 

It will be efficient to write if-else ladder in interrupt as it takes time?

It is quite usual to parse the incoming strings by grouping them according to the intial characters, which makes the code a little more confusing and less modulable, but this makes the process more efficient in terms of speed. For the above case, not necessarily a if-else chain, but rather a switch-case, on which each character of the string is the parent index of a new switch-case inside.
 
Could you please send me some reference of how switch case can be used in such applications?
 

For the above 6 AT commands, just something like this general structure, in pseudo-code:

Code:
case '+' : 
	case 'C': 
		case 'R': 
						... // +CREG: 
	case 'C': 						
		case 'G': 
						... // +CGREG: 
	case 'C': 						
		case 'S': 
						... // +CSQ: 
case '$' :
	case 'G': 
		case 'P':
			case 'G': 	
						... // $GPGGA: 
		case 'P':
			case 'R':   
						... // $GPRMC:
	case 'C': 			
						... // $CGPSINF:

At each incoming byte, skip and return to the next child switch-case statement next iteration.
 
If we want to get +CGREG,It will have 5 switch cases.I will try for it.
 

If we want to get +CGREG,It will have 5 switch cases.
At least, not so confusing as would be a cascaded if-else structure.
 

And this will be totaly wrong for sure :)
No any comparisons inside interrupt. In main code you search around lookup table. In table you have commands and hanlders to voids.
 

And this will be totaly wrong for sure :)
No any comparisons inside interrupt. In main code you search around lookup table. In table you have commands and hanlders to voids.

By if else ladder.We can have comparison inside interrupts.

- - - Updated - - -

Code:
void interrupt ISR()
{
 Receive_char[i++] = RCREG;
 if (Receive_char[i] == '\n') //detect end of string
 {
   receive_flag = 1; //rise the flag 'data ready'
   Receive_char[i] = 0; //terminate string with null
 }
}

It seems to be easy to understand than switch case.
 

Hi,

For sure you can. But this is against the rule that the ISR should be as short as possible.
In ISR: just store the data in a buffer, then leave the ISR.

Parse the data in the main loop.
If you can decide the commands (like: "+CREG:") on your own, then I recommend to make them as short as possible, but with equal length.
I'd trigger the comparison after the ":" is received.
Then compare the n bytes before the ":" with a the contents of a table.

Klaus
 

Hi,

For sure you can. But this is against the rule that the ISR should be as short as possible.
In ISR: just store the data in a buffer, then leave the ISR.

Parse the data in the main loop.
If you can decide the commands (like: "+CREG:") on your own, then I recommend to make them as short as possible, but with equal length.
I'd trigger the comparison after the ":" is received.
Then compare the n bytes before the ":" with a the contents of a table.

Klaus

There are responses which do not contain ' : ' character,like OK\r\n,ERROR\r\n.

- - - Updated - - -

However every response contains \r\n characters.
 

Hi,

A unique delimiter makes parsing more easy.
Not important if it is ":" or /n or /r

Klaus
 
Hi,

For sure you can. But this is against the rule that the ISR should be as short as possible.
In ISR: just store the data in a buffer, then leave the ISR.

Parse the data in the main loop.
If you can decide the commands (like: "+CREG:") on your own, then I recommend to make them as short as possible, but with equal length.
I'd trigger the comparison after the ":" is received.
Then compare the n bytes before the ":" with a the contents of a table.

Klaus

How do we do it?Any reference
 

Hi,

What exactely?
* Using an ISR?
* store data into a buffer?
* leaving n ISR?
* parsing data?
* using a table?
* decide your own commands?
* check for a delimiter?

Klaus
 

My code doesnt permit to parse data in main loop.I have to parse it inside ISR only.
I am receiving GPGGA packets every second.i have to calculate speed difference between two consecutive GPGGA packets.
 

Hi,

This tells neither
* what exactely you need, nor
* why this can´t be parsed in main loop.

So please be more specific - this saves your time (not only yours)

Klaus
 

Hi,

What exactely?
* Using an ISR?
* store data into a buffer?
* leaving n ISR?
* parsing data?
* using a table?
* decide your own commands?
* check for a delimiter?

Klaus

How to use tables

- - - Updated - - -

Code:
void main(void)
{
while(1)
   {
      parse_buffer();
      Erase buffer();

    }
 

}

void parse_buffer(void)
{
if(+creg is found in buffer)
{
Get network registration data
}
else if(+CGREG is found in buffer)
{
get GPRS registration data
}
.
.
.
.
.
.
.
.
.
.
}

- - - Updated - - -

There should be certain condition that trigger parse_buffer(); to be called.we cant parse it in while(1) loop unnecessarily.
 

Hi,

You may use a sheet of paper and a pencil,
or you may do an internet search about "using look up table" or "parsing data"

in short:
write these data
+CR:
+CG:
+CQ:
$GG:
$GR:
$CG:
#

in your memory.
and compare incoming data with the contents of the memory.
Let´s assume your incoming string is "$GR:"
* initialize a counter with 1
* Then begin to compare the first chracter of your input with the first character in the table (user_tbl_pointer)
* "$" <> "+": --> it doesnt match: increment counter, goto next line in table by looking for the next character after ":" (or use fixed increment if you have a fixed command length)
* compare:
* "$" <> "+": --> it doesnt match: increment counter, goto next line in table by looking for the next character after ":"
* compare:
* "$" = "$": --> it does match: compare next character in the string with next character in the table
* "G" = "G": --> it does match: compare next character in the string with next character in the table
* "R" = "G": --> it doesn´t match: increment counter, goto next line in table by looking for the next character after ":"
compare first character in the string with next character in the table
* "$" = "$": --> it does match: compare next character in the string with next character in the table
* "R" = "G": --> it doesn´t match: increment counter, goto next line in table by looking for the next character after ":"
* "R" = "R": --> it does match: compare next character in the string with next character in the table
* ":" = ":": --> it does match: complete string found. (up to the ":") leave the search. The counter value tells you which command is found.

in case you come to the "#" in the table: (This is the table delimiter) then set the counter value to 0 to indicate that no match is found.

***
This is gives a very compact code.
For sure one can improve performance.. but that´s another task.

***
Before you ask the next question: Please do an internet search. Look for a document that suits your needs. Try to modify/write code on your own.
Test your code. Show us your code, tell us what you expect, write down how you tested it, tell us what result you see.

Btw: Maybe I missed something, but I assume you didn´t tell what compiler you use und what controller you use. This is essential information.

Klaus

- - - Updated - - -

Hi,

There should be certain condition that trigger parse_buffer(); to be called.we cant parse it in while(1) loop unnecessarily.

--> Reading our posts helps:
I'd trigger the comparison after the ":" is received.

Klaus
 

Code:
unsigned char  GSM_response[10]="+CREG: ",GPRS_response[10]="+CGREG:

void interrupt ISR()
{
    Receive_char=U2RXREG
        if(GSM_register)
                { 

                    GSM_status[register_index]= Receive_char;
                    if( GSM_status[register_index]=='\r')
                    { 

                        GSM_register=0;
                        GPRS_register=1;
                        register_index=0;
                        get_status=0;

                    } 
                    else register_index++;
                }

 if(GSM_response[GPRS_response_index]== Receive_char)
            
            {
                GPRS_response_index++;
                if(GPRS_response_index==7)
                {
                    GPRS_response_index=0;
                    GSM_register=1;
                }
                
            }
}

If i receive string lets say,+CREG : 1,1`\r\n
After receiving +CREG: GSM_register will set to 1.Very first if statement will store remaining store into GSM_status register.
GSM_register will contain will contain 1,1.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top