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

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



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sat May 01, 2021 9:43 pm     Reply with quote

I like to define it like this:

Code:

int8 BFR_size = 64;
char BFR[BFR_size];
int8 Next_BFR = 0;


and then call:
Code:

void Clear_BFR() {         
   Next_BFR=0;                                                                                 
   while (Next_BFR < BFR_size -1){          // BFR ends at 63                                                         
      BFR[Next_BFR] = '\0';                     
      Next_BFR++;
   }
   Next_BFR=0;             // just to know where I am
}


I never ever use variables like i or j. Those can be defined in hundred places across your code and it is hard to find the right one when debugging.

In your case it could be a case issue, "I" vs. "i". I'm not an expert in C like tons of other guys here. They can write a code for an iPhone in one line. But I'm far from it, very far. So as a non-expert, I'd suggest you use braces with if's, elses, cases, whiles and separate the lines. Even if it's just one statement following. It is very easy to write two. Very interesting and time consuming thing to find out. It's also easier to read and follow the code.

Regarding Uart inactivity; I send a command ("AT+CREG?\r\n") to check if the module is online every few seconds, looking for an +CREG: 0,1 or 0,5 for roaming. You could only send a simple AT to see the module is alive now and then, looking for an OK answer. You can very easily expand the state machine in serial isr to look for OK and set an OK flag if you get it. Just add an else if in state 0 to wait for "O" and add another state below which waits for "K". Then set OK_flag. The sequence would be:

send AT
wait a moment
check OK_flag
if set, you are good, clear ok flag and continue
if not? problems :-) . It could be an ERROR answer, no answer...

I tried to solve those with soft reset, but it didn't always work. In the end I modified my board to be able to shut down the module via FET and tried to initialize again. With SIM modules that proved to be a problem, since they just didn't connect and I was watching my board trying to reset it for hours.
BTW, it was a smoke, CO and heat alarm system for my heating unit (turning on the lights is a by-product, way easier). So 99 out of 100 wasn't good enough, if your house was burning, as the Murphy would have it, the hundredth time.

Regards,
Samo
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Sun May 02, 2021 5:33 am     Reply with quote

Good day!

Code:

int8 BFR_size = 64;
char BFR[BFR_size];
int8 Next_BFR = 0;


I will give a try!

Code:

void Clear_BFR() {         
   Next_BFR=0;                                                                                 
   while (Next_BFR < BFR_size -1){          // BFR ends at 63                                                         
      BFR[Next_BFR] = '\0';                     
      Next_BFR++;
   }
   Next_BFR=0;             // just to know where I am
}


Also! Will write this way.

Quote:

I never ever use variables like i or j. Those can be defined in hundred places across your code and it is hard to find the right one when debugging.


I don't think this have any relation with the problem, because they are locals, they only exists when the code execute it, but let's see what happens when I change the code.


Quote:

I'd suggest you use braces with if's, elses, cases, whiles and separate the lines


For sure they are! I just bring the line here, not the entire delimiters.

Well, I am getting close of the problem. I did the following steps:

First, I raised a little bit my power supply, for 5.20 volts, instead of 5,00 volts. The result was that the module behave is now smooth, there were no problems like loose connectivity, lost communication, stay offline trying to connect with operator and so on. So, the module now seems to be in a stable working mode.

Second, even sending the module restart code below, I lost communication between RS232. This happens when I send a different kind of message, not SMS. Somehow, it seems to me that the RS232 becomes inactive, or for some other unknow reason, something strange happens to my code, and I am not able to reset the module and all the critical variables that are so important to keep RS232 synchronized.

Quote:

send AT
wait a moment
check OK_flag
if set, you are good, clear ok flag and continue
if not? problems :-) . It could be an ERROR answer, no answer...


The above is all I trying to avoid. I don’t have memory to do this way, otherwise, I may be short of memory when I write the rest of my code. I will poste my entire code here, as it is, just to check if there is anything I can do to prevent this “lost code” to happens. This is the main reason I suddenly lost communication with the module, sometimes, or, somehow, there must be a stack overflow, or something like this in the code. I will try to turn on the watchdog, to see if the microprocessor resets itself when this problem shows again.

Here is the code, as it is now. It was running smooth since yesterday 16:00, now here in Brazil is exactly 08:21. T
The strange behavior only happens when I send a MMS or something different from PURE text SMS.

FULL CODE AS IT IS NOW!

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=100, AUX_LED_STATUS=0, AUX_SMS=0, FLG_0=0, BFR_CNT=0, GSM_DLI=0, GSM_STR=0;

char BFR[64];
char TMP_CHAR;

//AT+CMGL="ALL" - LIST ALL SMS IN SIM CARD
//AT+CMGD=1,4 - APAGA TODAS SMS NO LOCATION 1

#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 SET_GSM=FLG_0.1
#bit DEL_SMS=FLG_0.2

void GSM_DEL_MSG()
   {
   fprintf(GSM,"AT+CMGD=1,4");
   DEL_SMS=0;   
   }   
void GSM_SET() //GSM SETUP
   {
   fprintf(GSM,"AT+CMGF=1\n");
   delay_ms(200);
   fprintf(GSM,"AT+COPS=0\n");
   delay_ms(200);
   fprintf(GSM,"AT+CFUN=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");
//   fprintf(GSM,"AT+CFUN=16");
   AUX_SMS=0;
   GSM_STR=0;
   GSM_DLI=0;
   SET_GSM=0;    
   }
void SMS_OUT() //SEND SMS MESSAGE BACK
   {
   int i;
//   fprintf(GSM,"AT+CMGS=\"04141991876833\"\r\n"); //TEST ONLY
   fprintf(GSM,"AT+CMGS=\"041"); //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]!='\xFF')fprintf(GSM,"%c",BFR[i]);
      BFR[i]='\xFF';
      }
   delay_ms(200);
   fputc(0X1A,GSM);
   SMS_IN=0;
   GSM_STR=0;
   GSM_DLI=0;
   BZZ=0;
   RELE_NVR=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_RDA);             
      porta=0X00;
      portb=0X00;
loop:
   while(PAGE==0)
      {
      if(SMS_IN)SMS_OUT();
      if(SET_GSM)GSM_SET();
      }
   while(PAGE==80)
      {
      ENABLE_INTERRUPTS(INT_RTCC);
      delay_ms(1000);
      PAGE=0;
      }
   while(PAGE==90)
      {
      delay_ms(5000);
      GSM_SET();
      PAGE=80;
      }
   while(PAGE==100)
      {
      LED_STATUS=1;
      delay_ms(1000);
      GSM_DEL_MSG();
      delay_ms(5000);
      PAGE=90;
      }      
   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==0X1E)
      {
      SET_GSM=1;
      BZZ=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==':')
               {   
              BFR_CNT=0;             
               GSM_STR=5;
                }
            else GSM_STR=0;
            break;           
           }
         case 5: //LOAD BFR
            {
            BFR[BFR_CNT]=TMP_CHAR;   
            ++BFR_CNT;                                                                                                       
            if(BFR_CNT==63)BFR_CNT=0;
            if(TMP_CHAR=='\x0A')GSM_DLI++;
            if(GSM_DLI==0x02)
               {   
               RELE_NVR=1;   
               SMS_IN=1; //SMS INCOMMING
               GSM_STR=6;
                 }                 
            break;
           }
      }
   }


At this point of time, I just need to have a recover for this problem, I mean, even with this errors and all the module fails, I need a way to the code recover itself, and be able to restart everything and keep running back, wherever the problem is, code or module.
temtronic



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

View user's profile Send private message

PostPosted: Sun May 02, 2021 7:03 am     Reply with quote

This....
Quote:
First, I raised a little bit my power supply, for 5.20 volts, instead of 5,00 volts.
suggests a problem in the design and construction of the power supply section.
According to the SIM800c hardware manual, you need a soild 4.00 volts at 2 amps to power the chip. They show a possible 5 volt to 4 volt section, using a linear regulator.
ALL GSM type devices NEED a lot of electrons during transmission, and I suspect the 2 amps is the MINUMUM (short bursts of data not long durations).

I'd design/build a PSU capable of 4 volts, 5 amps for the SIM800, then ADD the power required for the PIC and other peripherals (LEDS, relays, pullups), etc.
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Sun May 02, 2021 8:21 am     Reply with quote

temtronic! Good day!

No issues about my power supply. It is in the bench now, and I have a nice power supply capable of 3 A.

In fact, the redundance I made is working, I say, even after the BUG appears, it is able to recover the module, once that at times-to-times, send again the reset configuration to the module. It just recovers itself after a short period of time. I know that this is not the correct way to do this, but is acceptable for my application.
What I going to do next, is to connect a pin to hard reset the module, just a few seconds before send the reset configuration sequence, this way, I will be able to move on the rest of the code, that is quite simple when compared with the GSM part of the code.

Thanks,
temtronic



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

View user's profile Send private message

PostPosted: Sun May 02, 2021 8:44 am     Reply with quote

When you say 3 amps, that's At the Sim module, so 4.00 volts @ 3 amps ?

Have you put an oscilloscope on it it 'see' what the VDD is doing ?
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sun May 02, 2021 12:55 pm     Reply with quote

Do you have a USB-serial module lying somewhere around? If you do, hook it on the TX line of PIC to be able to see in real time what you send to the module and when. I fiddled with this a couple of years ago, but I know I was able to see complete exchange on uart, both from PIC and modem (maybe it was on RX line with ECHO enabled). It helped a lot to be able to see what modem throws out as an answer to a comand. LED's on RX and TX are also helpful.
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Sun May 02, 2021 2:58 pm     Reply with quote

PrinceNai, temtronic!

PrinceNai!
Quote:
Do you have a USB-serial module lying somewhere around? If you do, hook it on the TX line of PIC to be able to see in real time what you send to the module and when. I fiddled with this a couple of years ago, but I know I was able to see complete exchange on uart, both from PIC and modem (maybe it was on RX line with ECHO enabled). It helped a lot to be able to see what modem throws out as an answer to a comand. LED's on RX and TX are also helpful.


No, I don't have any! That's why I, unfortunately, buy the Arduino mega! Even without having any will to learn anything from it, I can use the serial interface, but only when I run the code from Arduino.

temtronic!
Quote:
When you say 3 amps, that's At the Sim module, so 4.00 volts @ 3 amps ?
Have you put an oscilloscope on it it 'see' what the VDD is doing ?


No, I mean that my power supply is able to handle up to 3 A, the module itself, when it is negotiating with operator, consumes only something around 0,7A maximum. The power supply has both voltage and current digital meters.

I do have a digital oscilloscope, I may check the voltage behavior, but I don’t think it will be necessary.
I am starting to code the hard reset pin, for pure luck, in this development, I have one pin unused, so I will hook to it.

Regards;
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sun May 02, 2021 3:23 pm     Reply with quote

Something like this?

https://www.instructables.com/How-to-Use-Arduino-As-USB-to-TTL-Serial-Converter-/
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon May 03, 2021 1:05 am     Reply with quote

There is a very 'key' thing when dealing with modules like this (and with SD
cards as well), that 'meters' only show voltage an current averaged over
quite a long interval. These modules have nasty little 'momentary' spikes
in their consumption lasting for only a few nSec, that the meter will not show.
This is why a good (low ESR) smoothing capacitor, really close to the pins
of the actual modem module is 'vital'. My own boar running these modems
has been fine for several years, but has two OSCON 220uF 10V capacitors
less than 15mm from the supply pins....
temtronic



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

View user's profile Send private message

PostPosted: Mon May 03, 2021 4:55 am     Reply with quote

As Mr. T points out, 'meters' like DVMs are very slow.....typically only read at 3 Hz (3 readings per second)... it only takes a microsecond 'glitch' to make the SIM go 'funny'. That's why a 'scope' is necessary to 'see' the power levels in real time.
Also the power traces to the SIM need to be 'wide', they HAVE to handle the 'huge' inrush current of 2 amps (possibly more) during the transmissions. A long, thin trace can easily drop the voltage down to reduce power to the SIM, so again... it goes 'funny'. Most people understand about 'line loss' when using long extension cords, bu similar power losses can occur on a small PCB !
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Mon May 03, 2021 5:16 am     Reply with quote

Good day!

Quote:
Something like this?
https://www.instructables.com/How-to-Use-Arduino-As-USB-to-TTL-Serial-Converter-/


That's really hand and helpful! For sure I will try! At least, the Arduino board shall serves for anything good. Rsrsrsrs

Quote:
There is a very 'key' thing when dealing with modules like this (and with SD
cards as well), that 'meters' only show voltage an current averaged over
quite a long interval. These modules have nasty little 'momentary' spikes
in their consumption lasting for only a few nSec, that the meter will not show.
This is why a good (low ESR) smoothing capacitor, really close to the pins
of the actual modem module is 'vital'. My own boar running these modems
has been fine for several years, but has two OSCON 220uF 10V capacitors
less than 15mm from the supply pins....


You are right! In fact, I rebuild my circuit on the proto-board, dragged the module for a more closer position to the 5,0V power supply, tripled the connection both to ground and VCC, put a 1000 x 16V capacitor very near the module pins, and the behavior is very nice till now! No issues had occurred since them. The module is stable and working well.

With the serial from Arduino board, for sure I will see exactly what’s happening with the BUS.

Thank you all!
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Mon May 03, 2021 5:19 am     Reply with quote

With this new arrangement, I will try to STOP sending reset to the module, and see how it will perform.

Regards
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 Previous  1, 2
Page 2 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