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.

Sending SMS command to GSM Modem 'delay loop' causes problem on PIC18F452

Status
Not open for further replies.

speedEC

Full Member level 6
Joined
Apr 1, 2011
Messages
337
Helped
23
Reputation
46
Reaction score
21
Trophy points
1,298
Activity points
4,324
Dear Sir,

I have solved problem to send SMS Command from PIC18F452 to GSM Modem (SIMCOMM300) using delay (for loop). (MPLAB IDEv8.63 and MPLAB C18v3.37.01 Compiler). Without the delay, Modem gives error. But in PIC16F877A we don't need to use any delay loop between disconnect(ATH) and Send SMS(AT+CMGS) commands. It works fine there without any delay loop. When call received from any phone, the PIC extracts the called Mobile number and checks whether it is Authorized Mobile Number or not. If Authorized Number then switch on the LED and disconnect (ATH) the call and send the (acknowledgement and ) status of the LED to the called (Authorized) Mobile Number thro' SMS. If the call from Unauthorized number it simply Disconnect the Phone.

It correctly disconnect the call and Power-up the LED and correctly sending with the use of delay loop. But after SMS sent it didn't come out from the loop. That is, it didn't process any further commands. I have to restart the PIC. I didn't receive "OK" after SMS sent. I received +CMGS: <Msg Number> and Hangs. I guess this is due to delay loop. Am I right? Can anyone help me to locate the issue?
 

how do you display the lines of text
Code:
+CMGS: <Msg Number>
OK
could it be that during the time you are printing the CMGS message on your screen you miss the line with OK from the modem.
when talking to modems I use an interrupt driven ring buffer to receive the data to make sure I do not miss messages (using polled IO it is easy to miss characters and you get UART overruns).
 
how do you display the lines of text
Code:
+CMGS: <Msg Number>
OK
could it be that during the time you are printing the CMGS message on your screen you miss the line with OK from the modem.
when talking to modems I use an interrupt driven ring buffer to receive the data to make sure I do not miss messages (using polled IO it is easy to miss characters and you get UART overruns).

I am using interrupt driven buffer and I used the example code comes along with mplabc18. For your Information,


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
/*
   * Open the USART configured as
   * 8N1, 9600 baud, in polled mode
   */
  OpenUSART (USART_TX_INT_OFF &
             USART_RX_INT_ON &
             USART_ASYNCH_MODE &
             USART_EIGHT_BIT &
             USART_CONT_RX &
             USART_BRGH_HIGH, 25); //9600 Baud



// Interrupt


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma code rx_interrupt = 0x8
void rx_int (void)
{
  _asm goto rx_handler _endasm
}
#pragma code
 
#pragma interrupt rx_handler
void rx_handler (void)
{
  unsigned char input;
  
  input = ReadUSART();
 
    switch(input){ // Validating USART input
}



My Code:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void showGSM_DATA(ram char gsmOutput_s[]){
 
.....
 
    if (strlen(gsmOutput_s) > 6){ //To Avoid parsing "OK", "ERROR" msg etc
        
        strncpy(strBuff, gsmOutput_s, 5);
                strBuff[5] = '\x00';
        WriteCmdXLCD(CLR_LCD); // Clear LCD
        while(BusyXLCD()); //Wait if LCD Busy
        WriteCmdXLCD(HOME_LCD); // Goto First Position
        while(BusyXLCD()); //Wait if LCD Busy
        putsXLCD(strBuff); // Here I receive whatever the output received at 
                                                   //USART that > 6 in length
       }
}



Can you pl help me?
 
Last edited:

you are using interrupts but are you doing the reading and display of the input in the interrupt routine?
if so you could be spending too much time in the interrupt routine and loosing characters.

in the interrupt routine just read the UART bufer and put the character into a ring buffer. You can then poll the ring buffer and process data without loosing characters (assume you don't overrun the ring buffer!)
this is some code I have for a PIC18F97J60 using MCC18
Code:
	#pragma interruptlow HighISR
	void HighISR(void)
	{
        if(PIR1bits.RCIF)  uartInterrupt();					// USART character received?

        ...
      }



volatile char uartData[20]={0};
volatile int uartDataIN=0, uartDataOUT=0;

// called on receiver interrupt
void uartInterrupt(void)
{
    PIR1bits.RCIF=0;				// clear interrupt flag
    uartData[uartDataIN++]=RCREG;	// read character into buffer
    if(uartDataIN>=20)uartDataIN=0;	// check buffer pointers
    PIE1bits.RCIE=1;				// reenable interrupt
}

// data received in buffer?    
char DataRdyUSART(void)
{
  return (uartDataIN!=uartDataOUT);
}

// read a character from receiver buffer
// if none available return 0
char ReadUSART(void)
{
  char ch;
  if(!DataRdyUSART()) return 0;
  ch=uartData[uartDataOUT++];       	// Return the received data
  if(uartDataOUT>=20)uartDataOUT=0;		// check pointers
  return ch;
}
 
Thank you so much Mr. horace1. I will do modifications and update you once completed.

---------- Post added at 21:45 ---------- Previous post was at 21:41 ----------

One more thing Mr. horace1.

The following code works fine only if I used delay:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
int n;
for(n=0;n<10000;n++){
}
putrsUSART((const far rom char*)"AT+CMGS=");
putcUSART(0x22);
putsUSART(strBuff_IncomingPhNum);
putcUSART(0x22);
for(n=0; n<10000;n++){
}
putcUSART(0x0A);
putcUSART(0x0D);
n=0;


without using delay, it gives error. Can you able to find the cause of the error? Thank you Mr. horace1.
 

Yes, Mr. horace1. I have also used ring buffer as you stated. I have not missed anything from the RCREG. Instead of "for loop" I have used while(BusyUSART()); and it works fine now. But I have some problem. The problem is, after sending the SMS, if I allowed the output "+CMGS: <msg number>" come into the "if statement" I received the output correctly as "+CMGS: <msg number>" and hangs here. If I didn't allow it to come into "if statement" everything works fine. I know I made something wrong in my code. Last two days I am fighting with the code, I have not succeeded yet. If any one provide help it will be appreciated and I will be thankful.

Code:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// If I won't allow the output from GSM Modem ("+CMGS: <msg num>") to come into this "if statement" as follows, the code succeeds:
 
[B]if (strlen(gsmOutput_s) > 10){[/B]
        
        strncpy(strBuff, gsmOutput_s, 5);
        strBuff[5] = '\x00';
        WriteCmdXLCD(CLR_LCD);
        while(BusyXLCD());
        WriteCmdXLCD(HOME_LCD);
        while(BusyXLCD());
        putsXLCD(strBuff);
        
        if(strcmp(strBuff, INCOMING_CALL) == 0){
            
            *strBuff = 0;
            if (counter < 1){
                counter++;
                
                WriteCmdXLCD(CLR_LCD); 
                while(BusyXLCD()); 
                WriteCmdXLCD(HOME_LCD); 
                while(BusyXLCD()); 
                
                pch = strstr(gsmOutput_s, AdminPhNum);
                memset(strBuff_IncomingPhNum, 0, sizeof(strBuff_IncomingPhNum));
                strncpy(strBuff_IncomingPhNum, pch, 10);
                if (strcmp(strBuff_IncomingPhNum, AdminPhNum) == 0){
                    
                    putrsXLCD("Admin Calling");
                    strcpypgm2ram(WhatToDo, (const far rom char*)"SendSMS_SwitchOnOff");
                    if (LED == 0){
                        LED = 1;
                        strcpypgm2ram(identity, (const far rom char*)"SwitchOnAck");
                    }
                    else{
                        LED = 0;
                        strcpypgm2ram(identity, (const far rom char*)"SwitchOffAck");
                    }
                    
                    *gsmOutput_s = 0;
                    *strBuff = 0;
                    putrsUSART((const far rom char*)"ATH");
                    putcUSART(0x0D);
                }
                else{
                    
                    *gsmOutput_s = 0;
                    putrsXLCD("UnAuthorized Call");
                    putrsUSART((const far rom char*)"ATH");
                    putcUSART(0x0D);
                }
            
            }
        }
    
        if(strcmp(strBuff, SMS_CMGR) == 0){
            *strBuff = 0;
            WriteCmdXLCD(CLR_LCD); 
            while(BusyXLCD()); 
            WriteCmdXLCD(HOME_LCD); 
            while(BusyXLCD());
            putsXLCD(gsmOutput_s);
        }
    
        if(strcmp(strBuff, SMS_CMGS) == 0){
            *strBuff = 0;
            WriteCmdXLCD(CLR_LCD); 
            while(BusyXLCD()); 
            WriteCmdXLCD(HOME_LCD); 
            while(BusyXLCD());
            putsXLCD(gsmOutput_s);
        }
               
        if(strcmp(strBuff, SMS_CMTI) == 0){
            *strBuff = 0;
            WriteCmdXLCD(CLR_LCD); 
            while(BusyXLCD()); 
            WriteCmdXLCD(HOME_LCD); 
            while(BusyXLCD());
            putsXLCD(gsmOutput_s);
        }
    }



But If I allowed the GSM Output to come into this "if statement" as follows the code hangs:

Code C - [expand]
1
if (strlen(gsmOutput_s) > 6){


The output I received displayed on LCD correctly and hangs. I have to restart the PIC to process next commands.

I don't know why? This is also happened for "AT+CMGR=1" SMS Command. But if I received SMS "+CMTI : SM", <Msg Number>, it works fine. It process correctly for Ring (AT+CLIP). Only problem on "+CMGS" and "+CMGR". Any help?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top