|
|
View previous topic :: View next topic |
Author |
Message |
rudy
Joined: 27 Apr 2008 Posts: 167
|
CHAR AND STRING |
Posted: Mon Apr 26, 2021 7:57 pm |
|
|
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
|
|
Posted: Mon Apr 26, 2021 10:14 pm |
|
|
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
|
|
Posted: Tue Apr 27, 2021 4:42 am |
|
|
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
|
|
Posted: Tue Apr 27, 2021 5:04 am |
|
|
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
|
|
Posted: Tue Apr 27, 2021 9:24 am |
|
|
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
|
|
Posted: Tue Apr 27, 2021 9:31 am |
|
|
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.... |
|
|
rudy
Joined: 27 Apr 2008 Posts: 167
|
|
Posted: Tue Apr 27, 2021 10:33 am |
|
|
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
|
|
Posted: Thu Apr 29, 2021 5:32 am |
|
|
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
|
|
Posted: Thu Apr 29, 2021 5:41 am |
|
|
:-)
I'm glad you've made it. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Apr 29, 2021 11:42 pm |
|
|
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
|
|
Posted: Fri Apr 30, 2021 12:36 pm |
|
|
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
|
|
Posted: Sat May 01, 2021 9:01 am |
|
|
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
|
|
Posted: Sat May 01, 2021 10:57 am |
|
|
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
|
|
Posted: Sat May 01, 2021 11:10 am |
|
|
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
|
|
Posted: Sat May 01, 2021 1:56 pm |
|
|
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. |
|
|
|
|
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
|