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 CCS Technical Support

CHAR AND STRING
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

CHAR AND STRING
PostPosted: Mon Apr 26, 2021 7:57 pm     Reply with quote

I am developing a GSM SIM800 code, and really having trouble to find a specific character in the buffer.

When I use STRSTR function, it works fine, but when I try to loop the buffer to find this CHAR + (0X2B), I simple cannot find, don’t know why! I need this loop to find the index of this CHAR and reorient the buffer, so I can extract the message I need to work with.

Please help me!


Thanks!

Code:


#include <16f628A.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, NOCPD, PUT, NOLVP
#use delay(clock=4000000, RESTART_WDT)
#use rs232(UART1, baud=9600, stream=GSM)


if(BFR[i]==0X2B)    //Don't work
if(BFR[i]=='+')     //Don't work also
                         

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 26, 2021 10:14 pm     Reply with quote

You didn't show us enough code to find the problem.
Post a complete program with all variable declarations and #define
statements, and a main(), etc.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 27, 2021 4:42 am     Reply with quote

quick comments...
1st, that PIC doesn't have a ton of memory, so you'll have to be 'creative' in your code...
2nd, always add 'ERRORS' to the USE RS232(....options...),prevents UART from 'locking up'
3rd, disable the WDT. it's not needed until 100% of the product works.
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Tue Apr 27, 2021 5:04 am     Reply with quote

Ok, Thank you for the support.

The code itself is a little big, so I will try to put only the information needed. Regardingly with the chip memory, don’t worry, my code fits very well in this cheap processor.
I don’t like Arduino, I think people don’t think too much about what are doing when use it, but I buy one, just to use the serial interface. Using the Arduino, I could receive this message back.
13:59:07.386 -> +CMT: "041999972949","","21/04/24,13:59:03-12"
13:59:07.386 -> Teste
I take a good attention and tried to see how this Arduino code work, and this code I am writing should do the same.
So, in first place, I need to find in the BFR the exactly location of “+CMT:” after that, I can move and correct index the BFR in another string, the char SUB. After that, I can take anything I need from the message sent to the SIM800.

Code:

#include <16f628A.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, NOCPD, PUT, NOLVP
#use delay(clock=4000000, RESTART_WDT)
#use rs232(UART1, baud=9600, stream=GSM)

#byte porta=0x05
#byte portb=0x06

int PAGE=10, AUX_LED_STATUS=0, AUX=0, FLG_0=0;

int BFR_COUNTER=0;
char BFR[64];
char SUB[64];
char CMT[5]="+CMT:";


void CHECK_SMS()
   {
   int i, j;
   RELE_SWT=1;   //RELE LIGA O SWITCH POE
   sms_in=0;      
      for(i=0;i<=63;i++)
         {
         if(BFR[i]=="+")   //detec +
            {
            if(BFR[i+1]=='C')   //detec C
               {
               if(BFR[i+2]=='M')   //detec M
                  {
                  if(BFR[i+3]=='T')   //detec T
                     {
                     if(BFR[i+4]==':')   //detec :
                        {
                        j=i;   //initial + position
                        sms_in=1;
                        RELE_NVR=1;   
                        break;
                        //}                     
                  //   }               
                  }            
               }         
            //}      
         //}
   if(sms_in)
      {
      for(i=j;i<=63;i++)
         {
         SUB[i-j]=BFR[i];
         }
      for(i=0;i<=j-1;i++)
         {
         SUB[64-j+i]=BFR[i];
         }
      sms_send=1;   
      }
   else
      {
      for(i=0;i<=63;i++)SUB[i]=0X00;      
      }
   }



#INT_RDA
void RS232_ISR()
   {
   BFR[BFR_COUNTER]=getchar();         
     BFR_COUNTER++;                                 
      if(BFR_COUNTER==65)BFR_COUNTER=0;
   }
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Tue Apr 27, 2021 9:24 am     Reply with quote

With this method you always get your data from position 0 in the buffer onward. No need to search for anything or to rearrange the buffers.
Code:

#INT_RDA
void RS232_ISR(){
   

   tmp=getc();                      // get received char and with that also clear the interrupt flag                                       

// Process reception through state machine
// Possible data from GSM module that will be handled is:                                                                       
// +CMT:

                                                                 
  switch (gsm_state) {
 
//get initial character, '+'             
      case 0:{                                                                                                   
        if(tmp == '+' ){     //we have "+", could be "+CMT:"
            gsm_state = 1;                //expecting C
        }                                     
         else {                         
            gsm_state = 0;                     
         }
         break;         
     }
//********WE HAVE RECIEVED '+' AS A FIRST CHARACTER***************************
// we have +, expecting C     
      case 1:{
         if    (tmp == 'C')         //have "+C"
               gsm_state = 11;      //expecting 'M'         
         else
            gsm_state = 0;          //didn't get 'C', reset state machine           
         break;
     }

// we have "+C", expecting 'M'
      case 11:  {
         if(tmp == 'M' )                     //
            gsm_state = 12;     
         else
            gsm_state = 0;                   //error, reset state machine
         break;         
     }
// we have "+CM", expecting 'T'               
      case 12:  {
         if(tmp == 'T' )                     //
            gsm_state = 13;
         else
            gsm_state = 0;                   //error, reset state machine
         break;           
     }
// we have "+CMT", expecting ':'             
      case 13:  {
         if(tmp == ':' ){                 
            gsm_state = 14;
         next_in = 0;               // always start at the beggining of the buffer         
       }
         else{
            gsm_state = 0;                   //error, reset state machine
       }
         break;           
     }
// we have "+CMT:", expecting data. Start filling the buffer until you get all the info in.             
      case 14:  {
      buffer[next_in]= tmp;            // move received char to the appropriate place in buffer.
      ++next_in;                       // increment IN pointer                                                                                             
      if(next_in==BUFFER_SIZE-1) {      // if we have 65, go back to 0         
         next_in=0;                           
      }
      if(tmp == SOME PREDEFINED CHARACTER){   // when you encounter something uniqe in the message (sixth '"' or '-' or CR or LF stop filling
         sms_in=1;                     // the buffer, signal to main you have a new message and go waiting for
         gsm_state = 0;                  // the next one
                     
      }
      break;
     }
  }
}           


Case 14 isn't finished, you have to supply the condition.

Regards,
Samo


Last edited by PrinceNai on Wed Apr 28, 2021 5:25 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Tue Apr 27, 2021 9:31 am     Reply with quote

Also, this is wrong:

if(BFR_COUNTER==65)BFR_COUNTER=0;

You are writing up to location 64 in the buffer., Will destroy the character
after the buffer. A 64 character buffer supports access to locations 0 to
63, not 64.... Sad
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Tue Apr 27, 2021 10:33 am     Reply with quote

Thank you both!

@Ttelmah, yes, you are right, the final count for this loop was wrong, and the others also. This issue has been corrected, and, sometimes, when the buffer synchronizes, I get the exactly answer I need, but, “sometimes”.

@PrinceNai, this is a very new approach for me, for sure I will give a try, because the routine I wrote was not running well.
For me, that I not an expert, the use of UART is very complex, I have a few experiences with this communication method, and the CCS manual is sometimes a little confusing to me. I had seen tons of codes, sometimes huge and very complex, but I think there must be a way to make this simple task easier. This feeling is greater when I see the Arduino code that do exactly what I need, always, without any fail. Take a look below and see how simple is that!

“For me, would be much easier if SIM800 module uses I2C”

Code:

void leGSM()
   {
     static String textoRec = "";
     static unsigned long delay1 = 0;
     static int count=0; 
     static unsigned char buffer[64];
   if(serialGSM.available())
      {           
       while(serialGSM.available())
          {         
            buffer[count++]=serialGSM.read();     
           if(count==64)break;
           }
      textoRec+=(char*)buffer;
        delay1=millis();
          for(inti=0;i<count;i++)
             {
            buffer[i]=NULL;
           }
        count=0;                       
        }
    if(((millis()-delay1)>100)&&textoRec!="")
      {
      if(textoRec.substring(2,7)=="+CMT:")
         {
           temSMS = true;
           }
      if(temSMS)
         {
            telefoneSMS = "";
           dataHoraSMS = "";
           mensagemSMS = "";
         byte linha = 0; 
           byte aspas = 0;
           for(int nL=1;nL<textoRec.length();nL++)
              {
            if(textoRec.charAt(nL)=='"')
               {
                     aspas++;
                     continue;
                  }                       
                if((linha==1)&&(aspas==1))
                   {
                     telefoneSMS+=textoRec.charAt(nL);
                  }
            if((linha==1)&&(aspas==5))
               {
                     dataHoraSMS+=textoRec.charAt(nL);
                  }
            if(linha==2)
               {
                    mensagemSMS+=textoRec.charAt(nL);
                  }
            if(textoRec.substring(nL-1,nL+1)=="\r\n")
               {
                     linha++;
                  }
              }
           }
        else
           {
             comandoGSM = textoRec;
           }
     textoRec = ""; 
        }     
   }
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Thu Apr 29, 2021 5:32 am     Reply with quote

PrinceNai, good day!

Working flowless!

I will post here the code, so somehow may be interesting for other people, that like me, are not experts in programming.

The code may have some improvements yet, but the basic concept work very fine.

I confess I had some problems trying to handle char BFR, in fact, I still have some issues, but now it is working well.

I really appreciate your help!

Code:

#include <16f628A.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, NOCPD, PUT, NOLVP
#use delay(clock=4000000, RESTART_WDT)
#use rs232(UART1, baud=9600, stream=GSM)

#byte porta=0x05
#byte portb=0x06

int PAGE=10, AUX_LED_STATUS=0, AUX_SMS=0, FLG_0=0, next_in=0, GSM_STR=0;

char BFR[64];
char TMP_CHAR;

#bit LED_STATUS=portb.5 //GREEN STATUS LED
#bit RELE_CAM=porta.1   //POE 48 RELAY
#bit RELE_SWT=porta.0   //SWITCH RELAY
#bit RELE_NVR=porta.7   //NVR RELAY
#bit BZZ=portb.7      //BUZZER
#bit IGT=porta.3      //IGNITION START SIGNAL

#bit SMS_IN=FLG_0.0
#bit SMS_GO=FLG_0.1

void GSM_SET() //GSM SETUP
   {
   fprintf(GSM,"AT+CMGF=1\n");
   delay_ms(200);
   fprintf(GSM,"AT+CNMI=2,2,0,0,0\n");
   delay_ms(200);
   fprintf(GSM,"ATX4\n");
   delay_ms(200);
   fprintf(GSM,"AT+CSCLK=0");
   delay_ms(200);
   fprintf(GSM,"ATE0\n");
   delay_ms(200);
   fprintf(GSM,"AT+COLP=1\n");
   delay_ms(200);
   fprintf(GSM,"AT+CPMS=\"SM\",\"SM\",\"SM\"\r");    
   }
void SMS_OUT() //SEND SMS MESSAGE BACK
   {
   int i;
   GSM_STR=0;   
//     fprintf(GSM,"AT+CMGS=\"+5504141991876833\"\r\n"); //TEST ONLY
   fprintf(GSM,"AT+CMGS=\"+55041"); //OPERATOR CODE (TIM=41)
   for(i=5;i<=13;i++)fprintf(GSM, "%c", BFR[i]); //SENDER NUMBER
   fprintf(GSM,"\"\r\n");
   delay_ms(200);
   fprintf(GSM,"TROLLER BDA5i62\n"); //VEHICLE ID
   delay_ms(200);
   fprintf(GSM,"EU SOU UM VEÍCULO!\n"); //JUST FOR TESTING
   delay_ms(200);
   fprintf(GSM,"SOFTWARE EM TESTE\n"); //JUST FOR TESTING
   delay_ms(200);
   fprintf(GSM,"ABAIXO COPIA DA MENSSAGEM\n"); //JUST FOR TESTING
   delay_ms(200);
   for(i=41;i<=52;i++) //SMS - ECHO
      {
      if(BFR[i]<=0X7E)fprintf(GSM,"%c",BFR[i]);
      BFR[i]=0xFF;
      }
   delay_ms(200);
   fputc(0X1A,GSM);                   
   BZZ=0;
   SMS_IN=0;
   SMS_GO=0;
   }   
void main()
   {
    SETUP_COMPARATOR(NC_NC_NC_NC);
   set_tris_a (0b01111100);
   set_tris_b (0b01011111);
   SETUP_COUNTERS(RTCC_INTERNAL,RTCC_DIV_256);
      SETUP_TIMER_1(T1_DISABLED|T1_DIV_BY_8);
      SETUP_TIMER_2(T2_DISABLED,0,16);
      ENABLE_INTERRUPTS(GLOBAL);
    ENABLE_INTERRUPTS(INT_RTCC);
      ENABLE_INTERRUPTS(INT_RDA);             
      porta=0X00;
      portb=0X00;
loop:
   while(PAGE==0)
      {
//      restart_wdt();
      if(SMS_GO)SMS_OUT();
      }
   while(PAGE==10)
      {
//      restart_wdt();
      GSM_SET();
      delay_ms(1000);
      PAGE=0;
      }      

   goto loop;
   }
#INT_RTCC
void RTCC_ISR()
   {
   AUX_LED_STATUS++;
   if(AUX_LED_STATUS==0X19)   
      {
      AUX_SMS++;
      AUX_LED_STATUS=0;
      LED_STATUS=!LED_STATUS; //BLINKING LED (I AM ALIVE)
      }
   if(AUX_SMS==3)
      {
      AUX_SMS=0;
      if(SMS_IN)SMS_GO=1;
      }   
   }
#INT_RDA
void RS232_ISR()
   {
   TMP_CHAR=getc();
   AUX_SMS=0;                                       
   switch(GSM_STR)
      {
          case 0:   //GET +
          {                                                                                                   
           if(TMP_CHAR=='+')GSM_STR=1;                             
            else GSM_STR=0;                     
            break;         
           }   
         case 1: //GET C
            {
            if(TMP_CHAR=='C')GSM_STR=2;
            else GSM_STR=0;       
            break;
           }
         case 2: //GET M
           {
            if(TMP_CHAR=='M')GSM_STR=3;
            else GSM_STR=0; 
            break;         
           }               
         case 3: //GET T
            {
            if(TMP_CHAR=='T')GSM_STR=4;    
            else GSM_STR=0;    
            break;           
           }           
         case 4: //GET : AND FIRES SMS
            {
            if(TMP_CHAR==':')
               {                 
               GSM_STR=10;
               BZZ=1;     
               SMS_IN=1; //SMS INCOMMING
               next_in=0;   
                }
            else GSM_STR=0;
            break;           
           }
         case 10: //LOAD BFR
            {
            BFR[next_in]=TMP_CHAR;   
            ++next_in;                                                                                                       
            if(next_in==63)next_in=0;                           
            break;
           }
        }
   }
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Apr 29, 2021 5:41 am     Reply with quote

:-)

I'm glad you've made it.
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Apr 29, 2021 11:42 pm     Reply with quote

From a personal experience. Maybe the original SIM800 from Simcom is a good piece of hardware. I bought mine from Ali for a buck or two and had to reflash them to even work in either Slovenia or Montenegro. They dropped connection all the time and sent out undocumented answers. I moved to A6 modules from Ali. Way better. I'm green enough, so I threw all the SIM800 modules into electronic waste bin. Broke them in half first. First to save the nature and second to prevent an aspiring CCS user from pulling his hair out and ending as bald as me or even worse, closing his laptop the wrong way.
Just a warning.
Regards,
Samo
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Fri Apr 30, 2021 12:36 pm     Reply with quote

Noticed!

FACT! they are very unstable. But now I finally confident that the code is going right. This module for sure have some strange behavior but, after three weeks pouring my hair off, finally I get satisfied.

When I buy more for the next projects, I will move for SIM900, it seems a little more confident.

Thank you!
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sat May 01, 2021 9:01 am     Reply with quote

I am following your advice. This SIM800 module is a mess!

Moving for SIM 900 to give it a try!
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Sat May 01, 2021 10:57 am     Reply with quote

Please report how it goes. For me SIM modules just didn't work. It took some time before I realized it was not just the faulty code I wrote. 99 times out of 100 it worked. Why not the hundredth time then? I went down with the baudrate to eliminate possible RS232 errors. Ran PIC from a crystal to ensure frequency was ok, again to be sure the timing for serial was ok. Nothing changed. Than I hooked everything through serial-usb module to watch what happens on my PC. Than I saw (after sending hundreds of SMS's) there are lots of ERROR responses from the module. Lots of resets (yes, I changed power supplies, put a big tantalum cap on it 0,5 cm from the input to the module). With A6 that changed :-). It works. Since I work like 1000 km away from home, I'm able to turn on or off some relays to turn on lights there now and then. And get the info about it. Won't scare off the thieves, but it is nice to see at least the code is ok.
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Sat May 01, 2021 11:10 am     Reply with quote

And while being at it. Has anybody done a project to send a message to let's say Viber from a house Wifi?
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sat May 01, 2021 1:56 pm     Reply with quote

PrinceNai wrote:
Please report how it goes. For me SIM modules just didn't work. It took some time before I realized it was not just the faulty code I wrote. 99 times out of 100 it worked. Why not the hundredth time then? I went down with the baudrate to eliminate possible RS232 errors. Ran PIC from a crystal to ensure frequency was ok, again to be sure the timing for serial was ok. Nothing changed. Than I hooked everything through serial-usb module to watch what happens on my PC. Than I saw (after sending hundreds of SMS's) there are lots of ERROR responses from the module. Lots of resets (yes, I changed power supplies, put a big tantalum cap on it 0,5 cm from the input to the module). With A6 that changed :-). It works. Since I work like 1000 km away from home, I'm able to turn on or off some relays to turn on lights there now and then. And get the info about it. Won't scare off the thieves, but it is nice to see at least the code is ok.


Yes, in fact, I don't have all this information, like serial watches and so, but I am sure the code is ok, in fact, it worked fine for almost 24 hours, but suddenly stops to answer my SMS’s, due to something around 5 hours with no activity. So, I was suspicious that the RS232 could not stay inactive for a long period off-time, I really don’t know.

The module’s behavior strange, sometimes, out of nothing, it loses the connectivity with the operator, stop responding and so on. I am trying another way, sending the configuration at times and times, avoiding BUS to stay inactive for long periods of time. Until now, it seems to be OK, lets see how it performs with more time.

This development intends to stay in some vehicles that may be a thousand kilometer from me, and I simply need to recover some information about the video recording system I am developing. I just can’t walk 1000 km to recover this information.

But the thing that I really would discover is the strange behavior of the char BFR[]. I just cannot clear the buffer. Every time I do this, the code stops working. Don’t now why this is happening,
Code:


Int I;
For(i=0;i<=63;i++)BFR[i]=’\0’;



This results in a mess! Don’t really know why. I so angry with this that my will is to change char x int and do something like fprintf(GSM, “%c”, BFR[i]). Really annoying problem I am facing.

Well, lets see if the continuous time to time RS232 activity makes some change in my concept about the SIM800.

Keep you informed.

Thank you.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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