CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SMS - Text Messages - GSM - Remote Control - UPDATE 06/05/13
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

SMS - Text Messages - GSM - Remote Control - UPDATE 06/05/13
PostPosted: Wed May 01, 2013 9:22 pm     Reply with quote

Hi All,

It is about time I updated the SMS code I posted a long time ago.

OLD Post:
http://www.ccsinfo.com/forum/viewtopic.php?t=42527

This new "Driver" ... yeah, lets call it that... is cleaner IMO and easier to adapt to what the next user would want, I hope.

The main update is in how the "commands" are searched/found.
I got smart and used the <strings.h> library which for some reason I did not use in my previous code.


The Sample program is VERY verbose using PCM's Flex_LCD driver.
Thanks PCM!

As is, the sample program responds to 3 commands: "Luz1", "Luz2" & "Aire".
(spanish for Light1, Light2, and Airconditioning)
The only action taken by the code is to display a message on the LCD.
The Exception is "Luz2" which aditionally, replys back with an SMS to a SET & and PREDEFINED Number... See SEND_SMS();

ALL of the Experienced Programmers here will probably point out that my Function names should NOT be in ALL CAPS... I KNOW... Sorry.

I included a Pre-Paid Card recharge function.. however this will probably vary for your country...can't help you there...
however to USE this function you will need to write a small program that runs the function once..... i can't do everything...


Test Conditions:
Quote:
MODEM: ENFORA 1218
PIC: 16F886 @20MHz / 5V
BAUD: 115.2
COM: RS-232 / MAX232 Chip
LCD:16x2 + Flex_LCD driver (available in library)
COMPILED: PCM 4.135 - MPLAB 8.85


FAQ:
Q: How much support can I expect on this code?
A:
Q: Is it Flawless and Awesome?
A: Awesome Yes! Flawless...you tell me.

... im kidding, ill try to help in what I can.


UPDATE: 06/05/2013
Forum user EZFLYR noted the "New Message Indicator" was missing.
He also noted that most modules Default with this feature OFF.
A new Function SET_CNMI() has been added to correct this.


"AWESOME SMS DRIVER": (That word you keep using....)

Code:
//******************************************************************************
//                      GSM/SMS CONTROL "Driver"
//******************************************************************************
// AUTHOR: GABRIEL BARRIOS
// DATE: 29/04/2013
// Panama, Rep. Panama.
//______________________________________________________________________________
//
// This "Driver" contains the _basic_ functions required to succesfully control
// "something" via SMS.
// The included delay function waits for a character or times out.
// Ive included a function to recharge credit to a prepaid sim.
// Also included is a reply to sms function.
//
// YOU NEED TO CLEARLY UNDERSTAND HOW TO ADD NEW COMMANDS
// There are 3 example commands - I use defines as "pointers" to the commands
//
// UPDATE: 06/05/2013
// Forum user EZFLYR noted the "New Message Indicator" was missing.
// He also noted that most modules Default with this feature OFF.
// A new Function SET_CNMI() has been added to correct this.
//______________________________________________________________________________
//******************************************************************************


//******************************************************************************
// These defines are for code readability purposes. They must match EXACTLY with:
//          Strings[][] + SIZE_COMMAND + TOTAL_STRINGS + GET_SMS_COMMAND()
// Makes it a whole lot easier to add new ones.
// I have arbitrarily set the max command length to 10 chars, including '\0'.
// This can be changed with the defines below.
//******************************************************************************
//                        (See TOTAL_STRINGS BELOW)
#DEFINE OK       0          // 1 <-- Required
#DEFINE CMTI    1          // 2 <-- Required
#DEFINE ERROR    2          // 3 <-- Required
#DEFINE EXITO    3          // 4 <-- Untested
#DEFINE AIRE   4          // 5 <-- USER DEFINED
#DEFINE LUZ1    5          // 6 <-- USER DEFINED
#DEFINE LUZ2   6          // 7 <-- USER DEFINED

#DEFINE SIZE_COMMAND    10   // Sets the Max command Length including '\0'
#DEFINE TOTAL_STRINGS    7   // Total number of Searchable strings
#DEFINE SIZE_BUFFER    80   // Serial Buffer Size
#DEFINE NULL    '\0'      // Easier to type than '\0'
//______________________________________________________________________________



//******************************************************************************
//                      FUNCTION DECLARATIONS
//******************************************************************************

#INT_RDA
void SerialInt();         // Serial ISR used

int1 CHECK_COM();         // Checks Modem comms are OK
int1 SET_PDU();            // Sets modem to TXT MODE
int1 SET_MEM();            // Sets the Prefered Message Storage
int1 SET_CNMI();
int1 DEL_SMS(int);         // Deletes SMS form memory
int1 READ_SMS(int);         // Loads SMS onto buffer
int1 RECHARGE_ACCOUNT();   // If using Pre_Paid cards *Might* vary depending on country
int1 STRING_SEARCH(int);   // Searchs for strings or commands
int1 DELAY(int);          // Delay with Limit
int GET_SMS_COMMAND();      // Similar to string_search but "simpler" and for user level.
void CMD_LOAD(int);         // Loads commands to a temp buffer from main "Strings" data base
void SEND_SMS();         // Sends an SMS

// These are helpfull to have around
void CLEAR_BUFFER();      // Clears the serial buffer
void PRINT_BUFFER();      // Just a serial buffer Print
//______________________________________________________________________________



//******************************************************************************
//          MAIN STRINGS or COMMANDS ARRAY and TEMPORARY COMMAND STORAGE
//******************************************************************************
// It is _IMPERATIVE_ that these match the define statements at the top
//
//                                              (SEE DEFINES AT TOP)
const char Strings[TOTAL_STRINGS][SIZE_COMMAND]={   "OK\0",               // index 0
                                       "+CMTI\0",            // index 1
                                       "ERROR\0",            // index 2
                                       "Exitosa\0",         // index 3
                                       "Aire\0",            // index 4
                                       "Luz1\0",            // index 5
                                       "Luz2\0"};            // index 6
char Command[SIZE_COMMAND];                              // Temp command buffer

char Receive_String[SIZE_BUFFER];                        // Serial Buffer
int counter_read = 0x00;                              // Serial Buffer Counter

//______________________________________________________________________________



//******************************************************************************
//                      HAVE *ALL* THE CODES!!!         
//******************************************************************************
//                                          (It's a meme reference)
//______________________________________________________________________________
//
//                      CHECKS COMMS WITH MODEM
int1 CHECK_COM()
{
   counter_read=0;                     // Reset buffer counter
   printf("AT\r");                     // Send Attention Command
   DELAY(5);                        // Delay a maximum of X seconds
   counter_read=0;                     // Reset buffer counter
   return(STRING_SEARCH(OK));            // Check for OK response
}
//______________________________________________________________________________
//
//                      SET MODEM TO TXT MODE
int1 SET_PDU()
{
   counter_read=0;                  // Reset buffer counter
   printf("AT+CMGF=1\r");            // Set modem to TXT mode
   DELAY(5);                     // Delay a maximum of X seconds
   counter_read=0;                  // Reset buffer counter
   return(STRING_SEARCH(OK));         // Check for OK response
}
//______________________________________________________________________________
//
//                     SET MESSAGE STORAGE
int1 SET_MEM()
{
   counter_read=0;                        // Reset buffer counter
   printf("AT+CPMS=\"SM\",\"SM\",\"SM\"\r");   // Store in SIM Card
   DELAY(5);                           // Delay a maximum of X seconds
   counter_read=0;                        // Reset buffer counter
   return(STRING_SEARCH(OK));               // Check for OK response
}
//______________________________________________________________________________
//
//                     SET NEW SMS ALERT MSG
int1 SET_CNMI()
{
   counter_read=0;                        // Reset buffer counter
    printf("AT+CNMI=2,1,2,0,0\r");              //text part of the command.
   DELAY(5);                           // Delay a maximum of X seconds
   counter_read=0;                        // Reset buffer counter
   return(STRING_SEARCH(OK));               // Check for OK response
}
//______________________________________________________________________________
//
//                     DIALS PREPAID CARDS
int1 RECHARGE_ACCOUNT()
{
   counter_read=0;                        // Reset buffer counter
            //         Card #      //
            //  |--------------|   //
   printf("ATD*166*5096294738864525#I;\r");    // Dial carrier with prepaid card#
   DELAY(5);                           // Delay a maximum of X seconds
   counter_read=0;                        // Reset buffer counter
   return(STRING_SEARCH(EXITO));
}
//______________________________________________________________________________
//
//                     LOADS SMS INTO BUFFER
int1 READ_SMS(int index)            // index' is the memory address/location
{
   counter_read=0;                  // Reset buffer counter
   printf("AT+CMGR=%d\r",index);      // Send Read SMS command
   DELAY(5);                     // Delay a maximum of X seconds
   counter_read=0;                  // Reset buffer counter
   if(STRING_SEARCH(OK))            // Check for OK response
      return(1);                  //           OR
   if(STRING_SEARCH(ERROR))         // Check for ERROR response
      return(0);
}
//______________________________________________________________________________
//
//                     DELETES SMS FROM MODEM
int1 DEL_SMS(int index)               // index' is the memory address/location
{
   counter_read=0;                  // Reset buffer counter
   printf("AT+CMGD=%d\r",index);      // Send Delete SMS command
   DELAY(5);                     // Delay a maximum of X seconds
   counter_read=0;                  // Reset buffer counter
   if(STRING_SEARCH(OK))            // Check for OK response
      return(1);                  //           OR
   if(STRING_SEARCH(ERROR))         // Check for ERROR response
      return(0);
}
//______________________________________________________________________________
//
//                           SEND SMS
void SEND_SMS()
{
   counter_read=0;
   printf("AT+CMGS=\"########\"\r");            // send command and cel #   
   delay_ms(1000);                           // Delay long enough for modem response
   printf("LORD JESUS ITS A FIRE!!!\n\r");         // Text to reply
   putchar(0x1A);                           // send Ctrl-z
   DELAY(20);                              // Delay a maximum of X seconds
}
//______________________________________________________________________________
//
//               SEARCHES FOR A SPECIFIC STRING IN BUFFER
int1 STRING_SEARCH(int index)               // index' is Strings[index][SIZE_COMMAND]
{                                    // See defines at top.
   CMD_LOAD(index);                     // Loads into temp array the string to be found
   if(STRSTR(Receive_String,Command)!=NULL)   // Find String or Command in main Buffer
      return(1);                        // Return 1 if found
   else
      return(0);                        // Return 0 if not found.
}
//______________________________________________________________________________
//
//               LOADS TO TEMP ARRAY THE SEARCHABLE STRING
void CMD_LOAD(int index)
{
   int var=0;                                            // temp index for array
   memset(Command,NULL,SIZE_COMMAND);                  // Reset data array index
      while((Strings[index][var]!=NULL)&&(var<SIZE_COMMAND))   // Copy data from main "Strings" to commparing array.
      {
      Command[var]=Strings[index][var];      // Copy into temp array the strings from Main Database
         var++;                           // Up index
      }
}
//______________________________________________________________________________
//
//               SEARCHES TRHOUGH ALL POSSIBLE COMMANDS
int GET_SMS_COMMAND()
{
   if(STRING_SEARCH(AIRE)==1)return(AIRE);    // Using string_search() goes through
   else                              // all user defined commands.

   if(STRING_SEARCH(LUZ1)==1)return(LUZ1);
   else

   if(STRING_SEARCH(LUZ2)==1)return(LUZ2);
   else
   return(0);                           // returns zero if nothing found
}
//______________________________________________________________________________
//
//                     PRINT SERIAL BUFFER
void PRINT_BUFFER()
{
   int var=0;                              // Temp data array index
   while(var<SIZE_BUFFER)                     // print all data array
   {
      Printf("%c-%u, ",Receive_String[var],var);   // pring in ASCII content and index
      var++;                              // Up index
   }
   Printf("\r\n");                           // Send return & new line
}
//______________________________________________________________________________
//
//                     CLEAR SERIAL BUFFER
void CLEAR_BUFFER()
{
   memset(Receive_String,NULL,SIZE_BUFFER);      // Set all elements to NULL
   counter_read=0;                           // Reset index
}
//______________________________________________________________________________
//
//                         LIMITED DELAY
int1 DELAY(int Delay_ctr)
{
   counter_read=0;                     // Reset buffer counter
   while((counter_read==0)&&(Delay_ctr>0))   // stay here until modem responds (X Seconds is arbitrary)
   {                              
   delay_ms(1000);                     
   Delay_ctr--;
    }
   if((counter_read==0)&&(Delay_ctr==0))
   return(1);
   if((counter_read==0)&&(Delay_ctr>0))
   return(0);            
}
//______________________________________________________________________________
//
//                     SERIAL BUFFER ISR
#INT_RDA
void SerialInt()
{
   Receive_String[counter_read]=getchar();         // Gets chars from uart
   counter_read++;                           // Increment counter
      if(counter_read==SIZE_BUFFER)counter_read=0;   // Circle Buffer
}


SAMPLE PROGRAM:

Code:
#include <16f886.h>
#device adc=8
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)


#include "string.h"
#include "enfora1218_driver -12-02-2013.c"
#include "flex_lcd.c"

//==========================
void main()
{
   int sms_index=1;

   ENABLE_INTERRUPTS(GLOBAL);               // Enable Interrupts
   ENABLE_INTERRUPTS(INT_RDA);               // Enable Serial Interrupts   
   SETUP_TIMER_2(T2_DIV_BY_4,207,1);         // Set Timer source for PWM   
      setup_ccp1(CCP_PWM|CCP_PULSE_STEERING_A);   // Configure CCP1 as a PWM
   set_pwm1_duty(416L);                  // Set Duty to %50 (Drives LCD -Ve pump)
   lcd_init();                          // Initialize LCD Screen


//**************************************************************************
// Clears the Comm buffer
//**************************************************************************

   CLEAR_BUFFER();
   lcd_putc("\fBUFFER CLEARED\n");
   DELAY(1);                           // Delay a maximum of X seconds

   while(1)
   {

//**************************************************************************
// Check if modem is attached
//**************************************************************************
      if(CHECK_COM())
      {   
         CLEAR_BUFFER();
         lcd_putc("\fCOMMS ARE GOOD\n");
         lcd_putc("\MOVING ON...\n"); 
         DELAY(1);                     // Delay a maximum of X seconds
      }
      else
      {
      lcd_putc("\fCOMMS FAILED\n");
      DELAY(1);                        // Delay a maximum of X seconds
      while(!CHECK_COM())
         {
            lcd_putc("\RETRYING - STUCK IN LOOP\n");
            DELAY(1);                  // Delay a maximum of X seconds
         }
         lcd_putc("\f");
         lcd_putc("\fCOMMS ARE GOOD\n");
      }
      DELAY(1);                        // Delay a maximum of X seconds;

//**************************************************************************
// Set Modem to TXT mode
//**************************************************************************
      lcd_putc("\fSET MODEM TO TXT MODE\n");
      DELAY(1);                        // Delay a maximum of X seconds
      if(SET_PDU())
      {
         CLEAR_BUFFER();
         lcd_putc("\OK! - MOVING ON...\n"); 
         DELAY(1);                     // Delay a maximum of X seconds
      }
      else
      {
         lcd_putc("\ERROR - STUCK IN LOOP...\n");
         while(1);
       }

//**************************************************************************
// Set Prefered message Storage
//**************************************************************************
      lcd_putc("\fSETTING SMS MEMORY\n");
      DELAY(1);                        // Delay a maximum of X seconds;
      if(SET_MEM())
      {
         CLEAR_BUFFER();
         lcd_putc("\OK! - MOVING ON...\n"); 
         DELAY(1);                     // Delay a maximum of X seconds
      }
      else
      {
         lcd_putc("\ERROR - STUCK IN LOOP...\n");
         while(1);
       }
//**************************************************************************
// Set SMS Alert Message
//**************************************************************************
      lcd_putc("\fSETTING SMS ALERT\n");
      DELAY(1);                        // Delay a maximum of X seconds;
      if(SET_CNMI())
      {
         CLEAR_BUFFER();
         lcd_putc("\OK! - MOVING ON...\n"); 
         DELAY(1);                     // Delay a maximum of X seconds
      }
      else
      {
         lcd_putc("\ERROR - STUCK IN LOOP...\n");
         while(1);
       }

//**************************************************************************
// WAIT FOR SMS AND READ
//**************************************************************************
      lcd_putc("\fMODEM SETUP IS DONE\n");
      lcd_putc("\CLEARING BUFFER...\n"); 
      CLEAR_BUFFER();
      lcd_putc("\DONE ---> RUN PROGRAM\n");
      DELAY(1);                        // Delay a maximum of X seconds

      while(1)
      {
         lcd_putc("\f");
         lcd_putc("\fWAITING FOR SMS\n");
   
         while(!STRING_SEARCH(CMTI)){}
         lcd_putc("\fSMS RECEIVED!!!\n");
         CLEAR_BUFFER();
         sms_index=1;
         while(READ_SMS(sms_index))
            {
               if(GET_SMS_COMMAND()==AIRE)lcd_putc("\PRENDE AIRE\n");
               if(GET_SMS_COMMAND()==LUZ1)lcd_putc("\PRENDE LUZ 1\n"); 
               if(GET_SMS_COMMAND()==LUZ2)
               {
                  lcd_putc("\PRENDE LUZ 2\n");
                  CLEAR_BUFFER();
                  SEND_SMS();
               }
               DELAY(3);               // Delay a maximum of X seconds
               DEL_SMS(sms_index); 
               sms_index++;
               CLEAR_BUFFER();
            }
   
      }

   }//--END OF MAIN WHILE

}


Obviously all the Tabs and Spacing got Screwed up, but dont worry, think of it as an exiting adventure!


.... So, That's that and I hope it helps others and solves a lot of the issues of the previous code...



Gracias...
.
.
.
.
...TOTALES,

Gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093


Last edited by Gabriel on Mon May 06, 2013 8:09 pm; edited 3 times in total
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

Like Brian
PostPosted: Fri May 03, 2013 6:30 am     Reply with quote

Posts New Updated Code...


Shocked


Old Code gets more views.





like this kid
http://knowyourmeme.com/memes/bad-luck-brian
_________________
CCS PCM 5.078 & CCS PCH 5.093
ihsanbu



Joined: 14 Oct 2006
Posts: 27
Location: islamabad,pakistan

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger

-----------
PostPosted: Tue May 07, 2013 11:24 pm     Reply with quote

----------------

Last edited by ihsanbu on Wed May 08, 2013 8:20 am; edited 1 time in total
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

Wrong Driver, Wrong Thread, Wrong Problem
PostPosted: Wed May 08, 2013 6:35 am     Reply with quote

Hi ihsanbu,

You are using my _OLD_ GSM/SMS driver, which I am no longer supporting.

I suggest if you want to experiment with SMS you use the code in THIS post...
The code you posted is from a DIFFERENT DRIVER...

Lastly, your problem is with an LCD driver and NOT with my _OLD_code.
(according to your post)

I suggest you remove your post from this thread and put it under the appropriate place...

Why would you put that here?

G.


++++++++++++++++++++++++
Gabriel,
Do you want OLD thread removed from Code Library ?
(removed from public forum, but not deleted).
http://www.ccsinfo.com/forum/viewtopic.php?t=42527

- Forum Moderator
++++++++++++++++++++++++

_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri May 10, 2013 8:17 am     Reply with quote

Hi Mr. Moderator,

I am only trying to encourage people to use the newer code, but there is alot of help in that thread people might still find useful.

I do not know how many people have actually used the old code, and I dont know if anyone still finds that code usefull or comes back to it for reference.
Its been online for a while.

Where would you move it too?

G.


+++++++++++++++++
Let's leave it up.

- Forum Moderator
+++++++++++++++++

_________________
CCS PCM 5.078 & CCS PCH 5.093
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 20, 2013 1:40 pm     Reply with quote

Thanks for posting your new version!
It has been long waited for. Wink

I'm sure this topic will help a lot of people who are struggling with SMS reception. I just want to give a few pointers for further improvement:
1) The DELAY function returns a value that is never being tested. Even worse is that there is a code path inside DELAY where there is no value defined at all resulting in a random returned value.

2) Try to use more descriptive names than 'Strings' and 'DELAY()'. For example use 'CommandStrings' and 'WaitForDataOrTimeout()'.

3)
Code:
"+CMTI\0",            // index 1
You don't have to add a terminating zero to the string. In C the compiler does this for you. Now you have 2 terminating zeroes.

4) The serial receive function works most of the time but when the receive buffer overflows (after 80 characters) there is the small chance of misinterpreting a correct message from the modem. When this happens the whole state machine will fail and the procedure has to start from scratch again.
Another approach here would be to first set the text you are waiting for and then check this text being received inside the ISR. Then the whole problem with buffer overflows doesn't exist any more.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed May 22, 2013 4:03 pm     Reply with quote

Hi ckielstra,

Constructive criticisim is always welcomed!
Feel free to tear this code apart until it breaks (probably often, but less than before)...

I am working on rev3 since posting this update...


Quote:
1) The DELAY function returns a value that is never being tested. Even worse is that there is a code path inside DELAY where there is no value defined at all resulting in a random returned value.


Yes, you are right I never test the value returning from DELAY().
The reason why I included the diferent return values is because eventually I was supposed to check and act or error report on diferent return values.
The main reason is to know if the delay ended because the modem responded or because the delay simply timed out... a timeout would constitute an Error or Problem.
However, I never got arround to implementing this error checking.
The reason for making this DELAY() was to avoid getting permanently stuck in loops like in the first version of the SMS code--- this was one of the problems pointed out by many...

Can you please elaborate on the Unknown return state?
I would like to correct this but, i frankly do not see it... your help is appreciated.


Quote:
2) Try to use more descriptive names than 'Strings' and 'DELAY()'. For example use 'CommandStrings' and 'WaitForDataOrTimeout()'.


Agreed...


Quote:
3)
"+CMTI\0", // index 1
You don't have to add a terminating zero to the string.
In C the compiler does this for you. Now you have 2 terminating zeroes.


... i swear ive been told before that arrays in ccs are not Null terminated and that adding said null is a manual task nesesary for String functions to work...
I guess this is easily tested... but im having a hard time understanding where my confusion is comming from...

what im used to is: strings vs array where strings are null terminated and arrays are not.... but if you add the null to the array.. you get a string Smile

Quote:
4) The serial receive function works most of the time but when the receive buffer overflows (after 80 characters) there is the small chance of misinterpreting a correct message from the modem. When this happens the whole state machine will fail and the procedure has to start from scratch again.
Another approach here would be to first set the text you are waiting for and then check this text being received inside the ISR. Then the whole problem with buffer overflows doesn't exist any more.


Totally <--- glad you noticed, now you can help!

Indeed if the buffer loops in the middle of a desired string the code will fail to find the string and commands will be missed and so forth...

I am well aware of this problem since the begining of my SMS days...


From the original old code:
Code:
int READ_SMS()
{
   counter_read=0;

   printf("AT+CMGR=1");             // send command, MEMORY LOCATION OF SMS IS ALWAYS ONE, SINCE I DELETE THEM AFTER PROSCESING
   putchar(0x0D);

   delay_ms(3000);                  // long [spam] message... so give time,  buffer will loop back one time...
                                    // text will be on second fill.
   counter_read=0;

   if(GET_OK(0X45))
      Return(1);
   else return(0);

}


as described in the comments... its a long freaking modem reply before the actual SMS text.... which i relied purely on trial an error to get on the second buffer loop....

I am guilty of doing this again... more or less...

Part of the reason i didnt give much thought on how to handle this type of situation is because of the two modems ive tested... reply length and data fields varied alot...

and the other reason is because i didnt feel comfortable including a bunch of IFs inside my ISR... to test for a '+' for example and then start saving chars from that point.... which would have to be conditioned to another flag, because its a shared ISR and not everything has a '+'.

conditionals at 115.2kbps?



... so, the errors you point out are REAL, some of them i am aware of and simply didnt get around to finishing... others i didnt know how to solve them or see them..

I am fully commited to making a reliable driver and i think this driver is a major improvement over the past one.
I appreciate your help, and ask you to keep helping, testing, and finding things that break....

however, my coding abilities are limited to my imagination... another set of hands/eyes contributing to the driver would be appreciated.


Thanks,
G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri May 24, 2013 8:24 am     Reply with quote

@ckielstra,

I see it now...

Code:
int1 DELAY(int Delay_ctr)
{
   counter_read=0;                     // Reset buffer counter
   while((counter_read==0)&&(Delay_ctr>0))   // stay here until modem responds (X Seconds is arbitrary)
   {                               
   delay_ms(1000);                     
   Delay_ctr--;
    }
   if((counter_read==0)&&(Delay_ctr==0))
   return(1);
   if((counter_read!=0)&&(Delay_ctr>0))  // Change '==' to '!='
   return(0);             
}


Please confirm that is what you meant... Ill update the code accordingly once you reply.

Thanks!

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 24, 2013 9:00 am     Reply with quote

No, that is still not what I meant.
The problem is that you have
Code:
  if (some tests) return value1;
  if (some other tests) return value2;
end of function.
What happens when both of the if-statement are invalid? Then the function will wrongly terminate without a return value.
This is what happens in your modified version when counter_read != 0 and Delay_ctr == 0. Perhaps an unlikely situation to happen but you should never allow such a situation to happen.

Depending on what you want to achieve it could have looked like:
Code:
  if (some tests) return value1;
  else return value2;
end of function.

or...

  if (some tests) return value1;
  if (some other tests) return value2;
  return value3
end of function.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri May 24, 2013 9:12 am     Reply with quote

Hi,

I dont see how that is possible since i exit the While loop ONLY on either of of the 2 conditions im testing.

what would be the unknow state you speak of?
what values of counter_read and Delay_ctr would result on this third state?



my while exits on arrival of a character or expiration of the allowed time.

and then i proceed to test if the exit condition was a char or a timeout.
i do not see the third option...

I appologize for sounding dense but i honestly do not see the mistake and i am really trying to incorporate your suggestions..

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
jeremiah



Joined: 20 Jul 2010
Posts: 1313

View user's profile Send private message

PostPosted: Fri May 24, 2013 9:40 am     Reply with quote

What if counter_read gets incremented in the interrupt right after the Delay_ctr-- but before the while loop test occurs? You would have a scenario that would skip both returns.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri May 24, 2013 10:10 am     Reply with quote

Shocked Sweet Jesus...

thank you!

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 24, 2013 11:02 am     Reply with quote

It is good programming practice to never have a program flow where it is possible to get in an undefined state. The better compilers do warn you for such a possible error in your program flow.
In your example you were either doing too much testing and only one if-statement was required. Or, you didn't think of the third state and should have added a 3rd return value.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri May 24, 2013 1:45 pm     Reply with quote

yeah, definitely good practice, i just didn't realize i wasn't covering all angles there...

then again... i never really got to implement the use of that particular code... thus i never actually test the return value, as you pointed out.

Since i will implement that in the future revisions, i highly appreciate your comments and suggestions to make this code better.

if you have any further suggestions/critics/improvements.... feel free to let me know!

br.
G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
creative_35



Joined: 02 Jan 2007
Posts: 15

View user's profile Send private message

PostPosted: Tue May 05, 2015 7:56 am     Reply with quote

Thanks for the code, I have tested it with hyper terminal instead of LCD and sim900 modem with a speed of it's default 9600 baud rate. It's working fine and I have to modify. My question is how can I retrieve a 10 byte unknown string just after a known string in the message?
For example if someone messages as "PHONE XXXXXXXXXX", and I want to search for the string "PHONE" and want to get the following 10 numbers to a global string variable. Please help me.
My other question is, the SMS message contains number and other stuff, while printing the 'buffer' to LCD how did you remove the other stuff?
Thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group