PIC to MAX232

AlbertHall

Joined Jun 4, 2014
12,625
So is it safe to assume my PIC is working with internal 8Mhz at 9600 baud ?
Yup. The PIC, the level converter, the wiring is all OK.
Now you can add other stuff to your program. Check for the UART receiver interrupt first and note that any interrupt routine must take less time than one 9600 baud character (≈1mS) or they may cause a UART receiver overflow.
 

MaxHeadRoom

Joined Jul 18, 2013
30,661
But in the pic USART the FIFO buffering allows reception of two complete characters and the start of a third before s/w must start servicing the EUSART receiver.
Max.
 

jayanthd

Joined Jul 4, 2015
945
Problem is in ISR and Timer0 is causing the problem. Try this.
C:
void interrupt(){
  if((T0IE_bit) && (T0IF_bit)) {
  //  BLAAAAAAAAH:
  }
  if((CCP1IE_bit) && (CCP1IF_bit)) {
  // More BLAAAAAAH;
  }
//******************************************************************************
  if(RCIE_bit){                       // RX interrupt enabled
    if(RCIF_bit){                     // If Interrupt occured
      Tmp = UART1_Read(); // get received byte
// process reception through state machine
// we are parsing only "OK" and "RING" responses
      switch (gsm_state) {
        case 0: {
          response = -1; // clear response
          if (Tmp == 'O') // we have 'O', it could be "OK"
            gsm_state = 1; // expecting 'K'
          if (Tmp == 'R') // we have 'R', it could be "RING"
            gsm_state = 10; // expecting 'I'
         break;
        }
        case 1: {
          if (Tmp == 'K') { // we have 'K' ->
            response = GSM_OK; // we have "OK" response
            gsm_state = 50; // expecting CR+LF
          }
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
A bit of a problem..
I can parse OK and ERROR via ISR
and use it to display the necessary msg in LCD.
So I added up the rest and connect my modem.
The modem is responding with the "OK" to start up and after that it is not replying to the AT commands given by the PIC. Or it may be replying but the PIC is again giving me the "F".
The Init() works since my startup LCD msg will only appear after the modem sends "OK' to 4 AT commands. So after 4 "OK"'s the LCD starts as designed. ANd it is after that it gets stuck.

I am thinking the way the modem replies. I mean it replies in ASCII but it is too long and my " parsing " is not working.
I read the data and it seems the UART Read register is 8 bits, am I wrong here ?

I think my modem response is too large.
See below are the Response I need to parse.
OK and ERROR works.
I am having problem with ( for now) :

+COPS: 0,2,47201
+COPS: 0,2,47202
+CPIN: READY

This how the modem response to the terminal. There are "spaces" too

Part of my code,
C:
char Uart_Read;
Uart_Read= UART1_Read();
Question is how long the Rx data be for
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
Crap..!
I am editing the ISR to figure out a way. I would need to clean it up. first.
ISR is only for Rx IRQ for now.

still you can see . There may be errors as of now but the OK and ERROR is working.
PIC is internal 8MHz. 9600 Baud

C:
void interrupt(){
  if(INTCON.T0IF){
  INTCON.T0IF = 0;
  //  BLAAAAAAAAH:
  }
  if(CCP1IE_bit){
  if(CCP1IF_bit){
  CCP1IF_bit = 0;

  // More BLAAAAAAH;
  }
  }
if(RCIE_bit){                   // If RX Interrupt enabled
    if(RCIF_bit){                 // and If RX Interrupt occured
      Uart_Read = UART1_Read();   // Get received byte
// Processing reception through state machine
// We are parsing only 'OK', 'ERROR', '+CSQ: XX,XX', '+COPS: 0,2,4720(1or2)' \
   '+CPIN: READY' responses
      switch(gsm_state){
        case 0: {
          response = -1;          // clear response
          if(Uart_Read == 'O')   // we have 'O', it could be "OK"
            gsm_state = 1;        // expecting 'K'
          if(Uart_Read == 'E')   // we have 'E', it could be "ERROR"
            gsm_state = 2;        // expecting 'R'
          if(Uart_Read == '+')   // we have '+', it could be "CSQ,COPS or CPIN"
            gsm_state = 6;        // expecting 'C'
         break;
        }
        case 1:{  // OK
          if(Uart_Read == 'K'){  // we have 'K' ->
            response = GSM_OK;    // we have "OK" response
            gsm_state = 253;      // expecting CR+LF
          }
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 2:{  // ER
          if(Uart_Read == 'R')   // we have 'R', it could be "ERROR"
            gsm_state = 3;        // expecting 'R'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 3:{  // ERR
          if(Uart_Read == 'R')   // we have 'R', it could be "ERROR"
            gsm_state = 4;        // expecting 'O'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 4:{  // ERRO
          if(Uart_Read == 'O')   // we have 'O', it could be "ERROR"
            gsm_state = 5;        // expecting 'R'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 5:{  // ERROR
          if(Uart_Read == 'R'){  // we have 'R',
            response = ERROR;     // we have "ERROR" response
            response_rcvd = 1;    // set reception flag
            responseID = response;// set response ID
            gsm_state =  0;      // reset state machine
          }
         //  else
         //   gsm_state = 0;        // reset state machine
         break;
        }
        case 6:{  // +C
          if(Uart_Read == 'C')   // we have 'C', it could be "CSQ,COPS or CPIN"
            gsm_state = 7;        // expecting 'S or O or P'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 7:{ // +CO or +CP or +CS
          if(Uart_Read == 'O')   // Iff we have 'O', it could be "COPS"
            gsm_state = 8;        // expecting 'P'
          if(Uart_Read == 'P')   // Iff we have 'P', it could be "CPIN"
            gsm_state = 99;       // expecting 'I'
          if(Uart_Read == 'S')   // Iff we have 'S', it could be "CSQ"
            gsm_state = 100;      // expecting 'Q'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 8:{  // +COP
          if(Uart_Read == 'P')   // we have 'P', it could be "COPS"
            gsm_state = 9;        // expecting 'S'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 9:{  // +COPS
          if(Uart_Read == 'S')   // we have 'S', it could be "+COPS: 0,2,4720x
            gsm_state = 10;       // expecting ':'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 10:{  // +COPS:
          if(Uart_Read == ':')   //we have ':', it could be +COPS: 0,2,4720x
            gsm_state = 11;       // expecting ' '
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 11:{  // +COPS:_
          if(Uart_Read == 0x20)  //we have ' ', it could be +COPS: 0,2,4720x
            gsm_state = 12;       // expecting '0'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 12:{  // +COPS: 0
          if(Uart_Read == '0')   //we have '0', it could be +COPS: 0,2,4720x
            gsm_state = 13;       // expecting ',' or 'CR'
         else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 13:{  // +COPS: 0,  or +COP: 0
          if(Uart_Read == ',')   //we have ',', it could be +COPS: 0,2,4720x
            gsm_state = 14;       // expecting '2'
          if(Uart_Read == 10){  // if we have LF
            response = GSM_ERROR; // we have GSM ERROR response
            response_rcvd = 1;    // set reception flag
            responseID = response;// set response ID
            gsm_state =  0;      // reset state machine                                                                                 ***
          }
         break;
        }
        case 14:{  // +COPS: 0,2
          if(Uart_Read == '2')   //we have '2', it could be +COPS: 0,2,4720x
            gsm_state = 15;       // expecting ','
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 15:{  // +COPS: 0,2,
          if(Uart_Read == ',')   //we have ',', it could be +COPS: 0,2,4720x
            gsm_state = 16;       // expecting '"'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 16:{  // +COPS: 0,2,4
          if(Uart_Read == '4')   //we have '4', it could be +COPS: 0,2,4720x
            gsm_state = 17;       // expecting '7'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 17:{  // +COPS: 0,2,47
          if(Uart_Read == '7')   //we have '7', it could be +COPS: 0,2,4720x
            gsm_state = 18;       // expecting '2'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 18:{  // +COPS: 0,2,472
          if(Uart_Read == '2')   //we have '2', it could be +COPS: 0,2,4720x
            gsm_state = 19;       // expecting '0'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 20:{  // +COPS: 0,2,4720x ( X is 1 or 2 )
          if(Uart_Read == '0')   //we have '0', it could be +COPS: 0,2,4720x
            gsm_state = 21;       // expecting '1 or 2'
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 21:{  // +COPS: 0,2,4720x ( X is 1 or 2 )
          if(Uart_Read == '1'){  //we have '1', it could be +COPS: 0,2,47201
            response = GSM_DhiMobile; // we have DhiMobile response
            gsm_state = 253;      // expecting 'CR+LF'
          }
          if(Uart_Read == '2'){  //we have '2', it could be +COPS: 0,2,47202
            response = GSM_Ooredoo;   // we have Ooredoo response
            gsm_state = 253;      // expecting 'CR+LF'
          }
           else          
            gsm_state = 0;        // reset state machine
         break;
        }

      
      
// CR + LF
        case 253:{// CR
          if(Uart_Read == 13)   // we have CR, it could be CR+LF
            gsm_state = 254;      // expecting LF
           else
            gsm_state = 0;        // reset state machine
         break;
        }
        case 254:{// LF
          if(Uart_Read == 10){  // we have LF, response is complete
            response_rcvd = 1;    // set reception flag
            responseID = response;// set response ID
          }
          gsm_state = 0;          // reset state machine
         break;
        }
        default:{                 // unwanted character
          gsm_state = 0;          // reset state machine
         break;
        }
      }
    }
  }
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
That's funny...if I take out the TMr0 and TMR1, it's not working...o_O

And the BLAAAH..part is just empty
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
I checked with the modem.
When I take out the SIM card, modem replied "ERROR" to command issued by PIC "AT+CPIN? " and LCD Msg shows that the SIM had failed.

I believe it due to exceeding 8 bits.
OK and ERROR are with in a Byte.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
Code:
+COPS: 0,2,47201 -->0x2B 0x43 0x4F 0x50 0x53 0x3A 0x20 0x30 0x2C 0x32 0x2C 0x34 0x37 0x32 0x30 0x31
How long is the above ?
2 Bytes?
 

jayanthd

Joined Jul 4, 2015
945
The problem is still the ISR. ISR code is very lengthy. It is not good the parse the gsm data in ISR. You need to use a buffer of size say 200 bytes with an index for the buffer and fill all data into it like

C:
uart_rd[index++] = UART1_Read();
uart_rd[index] = '\0';
and in while(1) loop you have to use strstr() or strcmp() to check if OK is received in the buffer. If yes then you can extract the required data or send other AT commands after clearing the buffer.

Which PIC are you using ? You can't have all baudrates at all Fosc.

I use PIC18F46K22 which is cheaper than most PIC16F devices and it has lots of ROM and RAM.

I have done GSM projects successfully.

Yes, UART1_Read() returns a single byte. The internal code of this function is nothing but

C:
return RCREG;
 
Last edited:

jayanthd

Joined Jul 4, 2015
945
This is one of the gsm project which I did. It works fine for me. It is used to control devices based on received sms.

C:
#define ON   1
#define OFF  0

#define SET 1
#define CLEAR 0

#define HIGH 1
#define LOW  0

#define OPEN 1
#define CLOSE 0

#define TRUE 1
#define FALSE 0

#define ENABLE 1
#define DISABLE 0

#define ENABLED 1
#define DISABLED 0

#define ACTIVE 1
#define INACTIVE 0

#define First_Time_Use_Address 0x01
#define Temperature_Threshold_Address 0x02
#define Event_Address 0x03

// GSM module connections
sbit gsmReset at LATB4_bit;
sbit gsmReset_Direction at TRISB4_bit;
// End of GSM module connections

sbit LIGHT at LATB7_bit;
sbit ALARM at LATC2_bit;
sbit GATE  at LATB6_bit;

sbit NORMAL_VOLTAGE_LED at LATC0_bit;
sbit UNDER_VOLTAGE_LED at LATC1_bit;
sbit OVER_VOLTAGE_LED at LATB2_bit;

char myFlagsA = 0, myFlagsB = 0;

sbit gateStatusFlag at myFlagsA.B0;
sbit mainsStatusFlag at myFlagsA.B1;
sbit alarmStatusFlag at myFlagsA.B2;
sbit doOnceFlag at myFlagsA.B3;
sbit doOnceFlag2 at myFlagsA.B4;
sbit turnOffLightsFlag at myFlagsA.B5;
sbit timerOnFlag at myFlagsA.B6;
sbit lightStatusFlag at myFlagsA.B7;

sbit sendSmsFlag at myFlagsB.B0;
sbit firstTimeUseFlag at myFlagsB.B1;

char gsmBuffer[270];
char message[50];
char buffer1[50];
char buffer2[50];
char sms[100];
char smsIndex[4];
char value[4];
char str[23];
char lightDelayCode[10];
char temperatureThresholdData[5];
char gsmAttempt = 0;
char port = 0;
unsigned int diff = 0;

unsigned int iTemperature = 0, iPreviousTemperature = 0;
unsigned int iTemperatureThreshold = 0;
unsigned int delayCounter = 0, lightBlinkCounter = 0;
unsigned long lightDelayValue = 0, noOf200MilliSecondsCounter = 0, gsmBufferIndex = 0;
unsigned int addr = 0, val = 0;
unsigned char iEvent = 15;
unsigned int mainsVoltage = 0, prevMainsVoltage = 0;

double fTemperature = 0.0, fPreviousTemperature = 0.0;

//GSM Constant Strings
const char atCommand1[] = "AT\r";
const char atCommand2[] = "ATE0\r";
const char atCommand3[] = "ATE1\r";
const char atCommand4[] = "AT+IPR=9600\r";
const char atCommand5[] = "AT+CMGF=1\r";
const char atCommand6[] = "AT+CPMS=\"SM\",\"SM\",\"SM\"\r";
const char atCommand7[] = "AT+CNMI=2,1\r";
const char atCommand8[] = "AT+CMGR=";
//const char atCommand9[] = "AT+CMGS=\"9900516837\"\r";
const char atCommand9[] = "AT+CMGS=\"+27725138668\"\r";
const char atCommandA[] = "AT+CMGD=1,4\r";

const char atResponse1[] = "\r\nOK\r\n";
const char atResponse2[] = "ERROR";
const char atResponse3[] = "+CMTI: \"SM\",";
const char atResponse4[] = "> ";
const char atResponse5[] = "RING";
const char atResponse6[] = "NO CARRIER";
const char atResponse7[] = "NO ANSWER";
const char atResponse8[] = "+CFUN: 1";
const char atResponse9[] = "+CPIN: READY";



const char secretCode[]  = "20!4";
const char secretCode0[] = "20!4#l1";  //to turn lights ON
const char secretCode1[] = "20!4#l0";  //to turn lights OFF
const char secretCode2[] = "20!4#ls";  //to get STATUS of lights
const char secretCode3[] = "20!4#gt";  //to get temperature reading
const char secretCode4[] = "20!4#da";  //to de-activate the alarm
const char secretCode5[] = "20!4#aa";  //to activate the alarm
const char secretCode6[] = "20!4#as";  //to get the STATUS of the alarm
const char secretCode7[] = "20!4#cg";  //to close the electric gate
const char secretCode8[] = "20!4#og";  //to open the electric gate
const char secretCode9[] = "20!4#gs";  //to get the STATUS of the electric gate to see if its OPEN/CLOSED
const char secretCodeA[] = "20!4#ps";  //to get the STATUS of the power supply if its interrupted or not
const char secretCodeB[] = "20!4#rt";  //to get set temperature thtreshold value
const char secretCodeC[] = "20!4#d";   //to set Light On / OFF Delay
const char secretCodeD[] = "20!4#t";   //to set Light On / OFF Delay

const char sms1[] = "Light is ON";
const char sms2[] = "Light is OFF";
const char sms3[] = "Gate is open";
const char sms4[] = "Gate is closed";
const char sms5[] = "Alarm is ON";
const char sms6[] = "Alarm is OFF";
const char sms7[] = "Temperature is high";
const char sms8[] = "Power supply is OK";
const char sms9[] = "Power supply is not OK";
const char smsA[] = "Temperature Threshold is set to ";
const char smsB[] = " degree C";
const char smsC[] = "Temperature is ";
const char smsD[] = "Cannot control Gate. Voltage is not Ok";
const char smsE[] = "Incorrect Code Received";
const char smsF[] = "Light Will Turn ON after ";
const char smsG[] = "Light will turn OFF after ";
const char smsH[] = " minutes";
const char smsI[] = "First time use. ";
const char smsJ[] = " Threshold is not set.";

//Function Prototypes
char *CopyConst2Ram(char *dest, const char *src);

void DelayXSec(unsigned long int sec);

char *CopyConst2Ram(char *dest, const char *src);
void GSM_RESET();
void Extract_SMS(char *s1, char *s2);
void Get_SMS_gsmBufferIndex(char *s1, char *s2);
void Get_GSM_Time(char *s1, char *s2);
void Get_Code(char *s1, char *s2);
void GSM_Send_Const_Command(char *s1, char *s2, const char *s3, const char *s4, unsigned int *idx, char *gsmAttempt, char clr);
void GSM_Get_SMS(char *s1, char *s2, const char *s3, const char *s4, char *s5, unsigned int *idx, char *gsmAttempt, char *s6, char clr);
void Send_SMS(char *s1, char *s2, const char *s3, const char *s4, const char *s5, const char *s6, const char *s7, char *s8, unsigned int *idx, char *gsmAttempt, char clr);

#define SEND_AT_COMMAND GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand1, &gsmBufferIndex, &gsmAttempt, 1);
#define SET_GSM_BAUDRATE  GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand4, &gsmBufferIndex, &gsmAttempt, 1);
#define SET_GSM_TEXT_MODE GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand5, &gsmBufferIndex, &gsmAttempt, 1);
#define SET_SIM_MEMORY_FOR_SMS GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand6, &gsmBufferIndex, &gsmAttempt, 1);
#define ENABLE_NEW_SMS_NOTIFICATION GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand7, &gsmBufferIndex, &gsmAttempt, 1);
#define DELETE_ALL_SMS GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommandA, &gsmBufferIndex, &gsmAttempt, 1);
#define READ_SMS GSM_Get_SMS(gsmBuffer, buffer1, atResponse1, atCommand8, smsIndex, &gsmBufferIndex, &gsmAttempt, sms, 1);
#define SEND_SMS Send_SMS(gsmBuffer, buffer1, atResponse1, atResponse4, atCommand1, atCommand5, atCommand9, sms, &gsmBufferIndex, &gsmAttempt, 1);

#define SECRET_CODE_RECEIVED (strstr(sms, CopyConst2Ram(buffer1, secretCode)) != 0)

#define SECRET_CODE_TO_TURN_ON_LIGHT_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode0)) == 0)
#define SECRET_CODE_TO_TURN_OFF_LIGHT_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode1)) == 0)
#define SECRET_CODE_TO_GET_STATUS_OF_LIGHT_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode2)) == 0)
#define SECRET_CODE_TO_GET_TEMPERATURE_READING_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode3)) == 0)
#define SECRET_CODE_TO_DE_ACTIVATE_THE_ALARM_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode4)) == 0)
#define SECRET_CODE_TO_ACTIVATE_THE_ALARM_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode5)) == 0)
#define SECRET_CODE_TO_GET_STATUS_OF_ALARM_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode6)) == 0)
#define SECRET_CODE_TO_CLOSE_GATE_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode7)) == 0)
#define SECRET_CODE_TO_OPEN_GATE_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode8)) == 0)
#define SECRET_CODE_TO_GET_STATUS_OF_GATE_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode9)) == 0)
#define SECRET_CODE_TO_GET_STATUS_OF_POWER_SUPPLY_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCodeA)) == 0)
#define SECRET_CODE_TO_GET_TEMPERATURE_THRESHOLD_RECEIVED (strstr(sms, CopyConst2Ram(buffer1, secretCodeB)) != 0)
#define SECRET_CODE_TO_SET_LIGHT_ON_OFF_DELAY_RECEIVED (strstr(sms, CopyConst2Ram(buffer1, secretCodeC)) != 0)
#define SECRET_CODE_TO_SET_TEMPERATURE_THRESHOLD_RECEIVED (strstr(sms, CopyConst2Ram(buffer1, secretCodeD)) != 0)

#define MAINS_VOLTAGE_IS_NORMAL (!mainsStatusFlag)
#define MAINS_VOLTAGE_IS_ABNORMAL (mainsStatusFlag == 1)

#define INITIALIZE_PWM_FOR_BUZZER_AT_2500_KHz { PWM1_Init(2500); }
#define SET_PWM_DUTY_TO_0 { PWM1_Set_Duty(0); }

#define ENABLE_SERIAL_INTERRUPT { RCIE_bit = 1; }
#define ENABLE_PERIPHERAL_INTERRUPTS { PEIE_bit = 1; }
#define ENABLE_GLOBAL_INTERRUPT { GIE_bit = 1; }
#define DISABLE_GLOBAL_INTERRUPT { GIE_bit = 0; }

#define INITIALIZE_UART_WITH_9600_BPS_BAUD { UART1_Init(9600);  Delay_ms(200); }

#define ENABLE_EXTERNAL_INTERRUPT_0 { INT0IE_bit = 1; }
#define CLEAR_EXTERNAL_INTERRUPT_FLAG { INT0IF_bit = 0; }

#define READ_TEMPERATURE_THRESHOLD_VALUE_FROM_EEPROM { iTemperatureThreshold = EEPROM_Read(Temperature_Threshold_Address); Delay_ms(20); }
#define READ_PENDING_EVENT_VALUE_FROM_EEPROM { iEvent = EEPROM_Read(Event_Address); Delay_ms(20); }
#define READ_FIRST_TIME_USE_FLAG_FROM_EEPROM { firstTimeUseFlag = EEPROM_Read(First_Time_Use_Address); Delay_ms(20); }

#define SAVE_CURRENT_EVENT_VALUE_TO_EEPROM { EEPROM_Write(Event_Address, iEvent); Delay_ms(20); }

#define UART_OVERRUN_ERROR (OERR_bit == 1)
#define CLEAR_UART_OVERRUN_ERROR { OERR_bit = 0; }
#define DISABLE_UART_CONTINUOUS_RECEIVE { CREN_bit = 0; }
#define ENABLE_UART_CONTINUOUS_RECEIVE { CREN_bit = 1; }

#define READ_GSM_DATA_INTO_BUFFER { gsmBuffer[gsmBufferIndex++] = UART1_Read(); }
#define TERMINATE_GSM_BUFFER { gsmBuffer[gsmBufferIndex] = '\0'; }

#define CLEAR_UART_INTERRUPT_FLAG { RCIF_bit = 0; }

#define SERIAL_DATA_RECEIVED (RCIF_bit == 1)

#define WAIT_A_WHILE_TO_RECEIVE_THE_SMS Delay_ms(3000);
#define GET_SMS_INDEX Get_SMS_Index(gsmBuffer, smsIndex);

#define FIRST_TIME_USE (firstTimeUseFlag == 1)
#define CLEAR_FIRST_TIME_USE_FLAG { firstTimeUseFlag = 0; }

#define SET_SEND_SMS_FLAG { sendSmsFlag = TRUE; }
#define CLEAR_SEND_SMS_FLAG { sendSmsFlag = FALSE; }

#define SET_GATE_STATUS_FLAG { gateStatusFlag = TRUE; }
#define CLEAR_GATE_STATUS_FLAG { gateStatusFlag = FALSE; }

#define SET_LIGHT_STATUS_FLAG { lightStatusFlag = TRUE; }
#define CLEAR_LIGHT_STATUS_FLAG { lightStatusFlag = FALSE; }

#define SET_GATE_STATUS_FLAG { sendSmsFlag = TRUE; }
#define CLEAR_SEND_SMS_FLAG { sendSmsFlag = FALSE; }

#define SET_MAINS_STATUS_FLAG { mainsStatusFlag = TRUE; }
#define CLEAR_MAINS_STATUS_FLAG { mainsStatusFlag = FALSE; }

#define CLEAR_EVENT_COUNTER { iEvent = 0; }

#define EVENT_IS_0 {iEvent = 0; }
#define EVENT_IS_1 {iEvent = 1; }
#define EVENT_IS_2 {iEvent = 2; }
#define EVENT_IS_3 {iEvent = 3; }
#define EVENT_IS_4 {iEvent = 4; }
#define EVENT_IS_5 {iEvent = 5; }
#define EVENT_IS_6 {iEvent = 6; }
#define EVENT_IS_7 {iEvent = 7; }
#define EVENT_IS_8 {iEvent = 8; }
#define EVENT_IS_9 {iEvent = 9; }
#define EVENT_IS_10 {iEvent = 10; }
#define EVENT_IS_11 {iEvent = 11; }
#define EVENT_IS_12 {iEvent = 12; }
#define EVENT_IS_13 {iEvent = 13; }
#define EVENT_IS_14 {iEvent = 14; }
#define EVENT_IS_15 {iEvent = 15; }
#define EVENT_IS_16 {iEvent = 16; }
#define EVENT_IS_17 {iEvent = 17; }

#define SEND_PULSE_MOTOR_TO_OPEN_GATE { GATE = 1; Delay_ms(2000); GATE = 0; }
#define SEND_PULSE_MOTOR_TO_CLOSE_GATE { GATE = 1; Delay_ms(2000); GATE = 0; }

#define NEW_SMS_RECEIVED (strstr(gsmBuffer, CopyConst2Ram(buffer1, atResponse3)))

#define TURN_ON_LIGHT { LIGHT = 1; }
#define TURN_OFF_LIGHT { LIGHT = 0; }

#define LIGHT_IS_ON (lightStatusFlag == 1)
#define LIGHT_IS_OFF (lightStatusFlag == 0)

#define TURN_ON_NORMAL_VOLTAGE_LED { NORMAL_VOLTAGE_LED = 1; UNDER_VOLTAGE_LED = 0; OVER_VOLTAGE_LED = 0; }
#define TURN_ON_UNDER_VOLTAGE_LED { NORMAL_VOLTAGE_LED = 0; UNDER_VOLTAGE_LED = 1; OVER_VOLTAGE_LED = 0; }
#define TURN_ON_OVER_VOLTAGE_LED { NORMAL_VOLTAGE_LED = 0; UNDER_VOLTAGE_LED = 0; OVER_VOLTAGE_LED = 1; }

#define READ_TEMPERATURE { fTemperature = iTemperature = ADC_Read(0); Delay_ms(20); }

#define START_ALARM { PWM1_Set_Duty(127); PWM1_Start(); }
#define STOP_ALARM { PWM1_Stop(); }
#define SET_ALARM_STATUS_FLAG { alarmStatusFlag = 1; }
#define CLEAR_ALARM_STATUS_FLAG { alarmStatusFlag = 0; }
#define ALARM_IS_ON (alarmStatusFlag == 1)
#define ALARM_IS_OFF (alarmStatusFlag == 0)

#define MAINS_VOLTAGE_IS_NORMAL (mainsStatusFlag == 0)

#define GATE_IS_OPEN (gateStatusFlag == 1)
#define GATE_IS_CLOSED (gateStatusFlag == 0)
#define EVENT iEvent

#define CLEAR_WATCH_DOG_TIMER asm { clrwdt }

//Timer1
//Prescaler 1:8; TMR1 Preload = 15536; Actual Interrupt Time : 200 ms
//Place/Copy this part in declaration section
void InitTimer1(){
    T1CON = 0x31;
    TMR1IF_bit = 0;
    TMR1H = 0x3C;
    TMR1L = 0xB0;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}

void interrupt() {

    if(INT0IF_bit) {
        INT0IF_bit = 0;
        iEvent = 7;
        sendSmsFlag = 1;
    }

    if SERIAL_DATA_RECEIVED {
        if UART_OVERRUN_ERROR {
              CLEAR_UART_OVERRUN_ERROR
              DISABLE_UART_CONTINUOUS_RECEIVE
              ENABLE_UART_CONTINUOUS_RECEIVE
        }

        READ_GSM_DATA_INTO_BUFFER
        TERMINATE_GSM_BUFFER

        CLEAR_UART_INTERRUPT_FLAG
    }

     if(TMR1IF_bit) {
        TMR1IF_bit = 0;
        TMR1H = 0x3C;
        TMR1L = 0xB0;
        //Enter your code here

        if(lightDelayValue) {
             if(++noOf200MilliSecondsCounter == (lightDelayValue * 300)) {
                   LIGHT = 0;
                   lightDelayValue = 0;
                   TMR1ON_bit = 0;
                   lightStatusFlag = 0;
             }
        }
    }
}

char *CopyConst2Ram(char *dest, const char *src){
    char *d ;
    CLEAR_WATCH_DOG_TIMER
    d = dest;
    for(;*dest++ = *src++;)CLEAR_WATCH_DOG_TIMER;

    return d;
}

void DelayXSec(unsigned long int sec) {
    while(sec != 0) {
        Delay_ms(1000);
        CLEAR_WATCH_DOG_TIMER
        --sec;
    }
}

void GSM_RESET() {
    gsmReset = 1;
    CLEAR_WATCH_DOG_TIMER
    Delay_ms(20);
    gsmReset = 0;
    CLEAR_WATCH_DOG_TIMER
}

void Extract_SMS(char *s1, char *s2) {
    unsigned int i = 0;
    CLEAR_WATCH_DOG_TIMER
    while(*s1) {
        if(*s1 == '\n')
            ++i;
        CLEAR_WATCH_DOG_TIMER
        *s1++;

        if(i == 2)break;
    }
    CLEAR_WATCH_DOG_TIMER
    while((*s1) && (*s1 != '\r')) {
            *s2++ = *s1++;
            CLEAR_WATCH_DOG_TIMER
    }

    *s2 = '\0';                         //Terminate the string2 with null character
    CLEAR_WATCH_DOG_TIMER
}

void Get_SMS_Index(char *s1, char *s2) {

    while(*s1 != 'C') {
           *s1++;
           CLEAR_WATCH_DOG_TIMER
    }

    while(*s1 != 'M') {
           *s1++;
           CLEAR_WATCH_DOG_TIMER
    }

    while(*s1 != 'T') {
           *s1++;
           CLEAR_WATCH_DOG_TIMER
    }

    while(*s1 != 'I') {
           *s1++;
           CLEAR_WATCH_DOG_TIMER
    }

    while(*s1 != ',') {
           *s1++;
           CLEAR_WATCH_DOG_TIMER
    }

    *s1++;
    while(*s1 != '\r') {
        *s2++ = *s1++;
        CLEAR_WATCH_DOG_TIMER
    }

    *s2 = '\0';
    CLEAR_WATCH_DOG_TIMER
}

void Get_Value(char *s1, char *s2) {
    while(*s1 != '#') {
          *s1++;
          CLEAR_WATCH_DOG_TIMER
    }

    while((*s1) && ((*s1 >= '0') && (*s1 <= '9'))) {
         *s2++ = *s1++;
         CLEAR_WATCH_DOG_TIMER
    }

    *s2 = '\0';
    CLEAR_WATCH_DOG_TIMER
}

void Get_Light_Delay_Value(char *s1, char *s2) {
    while(*s1 != 'd') {
          *s1++;
          CLEAR_WATCH_DOG_TIMER
    }
    *s1++;
    while((*s1) && ((*s1 >= '0') && (*s1 <= '9'))) {
         *s2++ = *s1++;
         CLEAR_WATCH_DOG_TIMER
    }

    *s2 = '\0';
    CLEAR_WATCH_DOG_TIMER
}

void GSM_Send_Const_Command(char *s1, char *s2, const char *s3, const char *s4, unsigned int *idx, char *gsmAttempt, char clr) {
    CLEAR_WATCH_DOG_TIMER
    while(strstr(s1, CopyConst2Ram(s2, s3)) == 0) {
        UART1_Write_Text(CopyConst2Ram(s2, s4));
        CLEAR_WATCH_DOG_TIMER
        DelayXSec(2);
        CLEAR_WATCH_DOG_TIMER
        if((*gsmAttempt)++ == 3) {
            GSM_RESET();
            CLEAR_WATCH_DOG_TIMER
            memset(gsmBuffer, '\0', sizeof(gsmBuffer));
            (*gsmAttempt) = 0;
            (*idx) = 0;
        }
    }

    if(clr)memset(gsmBuffer, '\0', sizeof(gsmBuffer));
    CLEAR_WATCH_DOG_TIMER
    (*gsmAttempt) = 0;
    (*idx) = 0;
}

void GSM_Get_SMS(char *s1, char *s2, const char *s3, const char *s4, char *s5, unsigned int *idx, char *gsmAttempt, char *s6, char clr) {
    CLEAR_WATCH_DOG_TIMER
    while(strstr(s1, CopyConst2Ram(s2, s3)) == 0) {
        CopyConst2Ram(s2, s4);
        CLEAR_WATCH_DOG_TIMER
        strcat(s2, s5);
        strcat(s2, "\r");
        UART1_Write_Text(s2);
        CLEAR_WATCH_DOG_TIMER
        DelayXSec(2);
        CLEAR_WATCH_DOG_TIMER
        if((*gsmAttempt)++ == 3) {
            GSM_RESET() ;
            CLEAR_WATCH_DOG_TIMER
            (*gsmAttempt) = 0;
            (*idx) = 0;
            memset(gsmBuffer, '\0', sizeof(gsmBuffer));
        }
    }

    (*idx) = 0;

    Extract_SMS(s1, s6);
    CLEAR_WATCH_DOG_TIMER

    if(clr)memset(gsmBuffer, '\0', sizeof(gsmBuffer));
    CLEAR_WATCH_DOG_TIMER
}

void Send_SMS(char *s1, char *s2, const char *s3, const char *s4, const char *s5, const char *s6, const char *s7, char *s8, unsigned int *idx, char *gsmAttempt, char clr) {

    while(strstr(s1, CopyConst2Ram(s2, s3)) == 0) {
        CLEAR_WATCH_DOG_TIMER
        GSM_Send_Const_Command(s1, s2, s3, s5, idx, gsmAttempt, 1);
        GSM_Send_Const_Command(s1, s2, s3, s6, idx, gsmAttempt, 1);
        GSM_Send_Const_Command(s1, s2, s4, s7, idx, gsmAttempt, 1);
        CLEAR_WATCH_DOG_TIMER
        UART1_Write_Text(s8);
        Delay_ms(500);
        UART1_Write(0x1A);
        CLEAR_WATCH_DOG_TIMER
        DelayXSec(6);
    }

    memset(gsmBuffer, '\0', sizeof(gsmBuffer));
    (*idx) = 0;
    CLEAR_WATCH_DOG_TIMER
}

void main() {

    CMCON = 0x07;
    ADCON1 = 0x0D;

    TRISA = 0xC3;
    TRISB = 0x09;
    TRISC = 0x80;
    CLEAR_WATCH_DOG_TIMER

    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    CLEAR_WATCH_DOG_TIMER

    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    CLEAR_WATCH_DOG_TIMER

    INTEDG0_bit = 1;
    ENABLE_EXTERNAL_INTERRUPT_0
    CLEAR_EXTERNAL_INTERRUPT_FLAG

    INITIALIZE_UART_WITH_9600_BPS_BAUD
    CLEAR_WATCH_DOG_TIMER

    DISABLE_GLOBAL_INTERRUPT
    READ_FIRST_TIME_USE_FLAG_FROM_EEPROM
    READ_TEMPERATURE_THRESHOLD_VALUE_FROM_EEPROM
    READ_PENDING_EVENT_VALUE_FROM_EEPROM

    CLEAR_WATCH_DOG_TIMER
    ENABLE_SERIAL_INTERRUPT
    ENABLE_PERIPHERAL_INTERRUPTS
    ENABLE_GLOBAL_INTERRUPT

    CLEAR_WATCH_DOG_TIMER
    INITIALIZE_PWM_FOR_BUZZER_AT_2500_KHz
    SET_PWM_DUTY_TO_0
    CLEAR_WATCH_DOG_TIMER

    SEND_AT_COMMAND
    SET_GSM_BAUDRATE
    SET_GSM_TEXT_MODE
    SET_SIM_MEMORY_FOR_SMS
    ENABLE_NEW_SMS_NOTIFICATION
    DELETE_ALL_SMS

    CLEAR_WATCH_DOG_TIMER

    doOnceFlag = 0;

    if(iEvent != 0) {
        sendSmsFlag = 1;
    }

    while(1) {

        CLEAR_WATCH_DOG_TIMER
        mainsVoltage = ADC_Read(1) * 229.0 / 1024.0;
        CLEAR_WATCH_DOG_TIMER
        //5V dc adc input is equal to 250.0 V AC
        Delay_ms(20);
        CLEAR_WATCH_DOG_TIMER

        if(prevMainsVoltage != mainsVoltage) {
            CLEAR_WATCH_DOG_TIMER
            if((mainsVoltage >= 180.0) && (mainsVoltage <= 240.0)) {
                 TURN_ON_NORMAL_VOLTAGE_LED
                 mainsStatusFlag = 0;
            }
            else if(mainsVoltage < 180.0) {
                 TURN_ON_UNDER_VOLTAGE_LED
                 mainsStatusFlag = 1;
            }
            else if(mainsVoltage > 240.0) {
                 TURN_ON_OVER_VOLTAGE_LED
                 mainsStatusFlag = 1;
            }

            CLEAR_WATCH_DOG_TIMER

            prevMainsVoltage = mainsVoltage;
        }

        CLEAR_WATCH_DOG_TIMER
        READ_TEMPERATURE
        fTemperature /= 2.046;
        iTemperature /= 2;

        if(iPreviousTemperature != iTemperature) {
             if(iTemperature > iTemperatureThreshold) {
                    EVENT_IS_1;
                    SET_SEND_SMS_FLAG
             }
             else if(iTemperature <= iTemperatureThreshold) {
                    EVENT_IS_0;
                    doOnceFlag = 0;
             }

             FloatToStr(fTemperature, message);

             iPreviousTemperature = iTemperature;
        }

        if FIRST_TIME_USE {
            EVENT_IS_17;
            SET_SEND_SMS_FLAG
            CLEAR_FIRST_TIME_USE_FLAG
        }

        CLEAR_WATCH_DOG_TIMER

        if NEW_SMS_RECEIVED {

             WAIT_A_WHILE_TO_RECEIVE_THE_SMS
             GET_SMS_INDEX
             CLEAR_WATCH_DOG_TIMER
             SEND_AT_COMMAND
             SET_GSM_TEXT_MODE
             READ_SMS

             CLEAR_WATCH_DOG_TIMER

             if SECRET_CODE_RECEIVED {
                   CLEAR_WATCH_DOG_TIMER
                   if SECRET_CODE_TO_TURN_ON_LIGHT_RECEIVED {
                        EVENT_IS_2
                   }
                   else if SECRET_CODE_TO_TURN_OFF_LIGHT_RECEIVED {
                        EVENT_IS_3
                   }
                   else if SECRET_CODE_TO_GET_STATUS_OF_LIGHT_RECEIVED {
                        EVENT_IS_4
                   }
                   else if SECRET_CODE_TO_GET_TEMPERATURE_READING_RECEIVED {
                        EVENT_IS_5
                   }
                   else if SECRET_CODE_TO_DE_ACTIVATE_THE_ALARM_RECEIVED {
                        EVENT_IS_6
                   }
                   else if SECRET_CODE_TO_ACTIVATE_THE_ALARM_RECEIVED {
                        EVENT_IS_7
                   }
                   else if SECRET_CODE_TO_GET_STATUS_OF_ALARM_RECEIVED {
                        EVENT_IS_8
                   }
                   else if SECRET_CODE_TO_CLOSE_GATE_RECEIVED {
                        EVENT_IS_9
                   }
                   else if SECRET_CODE_TO_OPEN_GATE_RECEIVED {
                        EVENT_IS_10
                   }
                   else if SECRET_CODE_TO_GET_STATUS_OF_GATE_RECEIVED {
                        EVENT_IS_11
                   }
                   else if SECRET_CODE_TO_GET_STATUS_OF_POWER_SUPPLY_RECEIVED {
                        EVENT_IS_12;
                   }
                   else if SECRET_CODE_TO_SET_TEMPERATURE_THRESHOLD_RECEIVED  {
                        Get_Value(sms, temperatureThresholdData); 
                        EVENT_IS_13;
                   }
                   else if SECRET_CODE_TO_GET_TEMPERATURE_THRESHOLD_RECEIVED {
                        EVENT_IS_14;
                   }
                   else if SECRET_CODE_TO_SET_LIGHT_ON_OFF_DELAY_RECEIVED {
                        EVENT_IS_15;
                   }
                   else {
                       EVENT_IS_16;
                   }

                   CLEAR_WATCH_DOG_TIMER
                   SAVE_CURRENT_EVENT_VALUE_TO_EEPROM
                   CLEAR_WATCH_DOG_TIMER
                   memset(sms, '\0', sizeof(sms));
                   CLEAR_WATCH_DOG_TIMER
                   SET_SEND_SMS_FLAG
             }
             else {
                 EVENT_IS_16;
                 SET_SEND_SMS_FLAG
             }
        }

        CLEAR_WATCH_DOG_TIMER

        if(sendSmsFlag == TRUE) {

             CLEAR_WATCH_DOG_TIMER

             switch(EVENT) {
                    case 1:
                          CopyConst2Ram(sms, sms7);
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 2:
                          TURN_ON_LIGHT
                          CopyConst2Ram(sms, sms1);
                          CLEAR_WATCH_DOG_TIMER
                          lightStatusFlag = 1;
                          InitTimer1();
                          break;
                    case 3:
                          TURN_OFF_LIGHT
                          CopyConst2Ram(sms, sms2);
                          CLEAR_WATCH_DOG_TIMER
                          lightStatusFlag = 0;
                          break;
                    case 4:
                          if LIGHT_IS_ON {
                               CopyConst2Ram(sms, sms1);
                          }
                          else if LIGHT_IS_OFF {
                               CopyConst2Ram(sms, sms2);
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 5:
                          CopyConst2Ram(sms, smsC);
                          CLEAR_WATCH_DOG_TIMER
                          FloatToStr(fTemperature, buffer1);
                          Ltrim(buffer1);
                          Rtrim(buffer1);
                          strcat(sms, buffer1);
                          strcat(sms, " degree C");
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 6:
                          STOP_ALARM
                          CLEAR_ALARM_STATUS_FLAG
                          CopyConst2Ram(sms, sms6);
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 7:
                          START_ALARM
                          SET_ALARM_STATUS_FLAG
                          CopyConst2Ram(sms, sms5);
                          CLEAR_WATCH_DOG_TIMER
                          INT0IF_bit = 0;
                          break;
                    case 8:
                          if ALARM_IS_ON {
                               CopyConst2Ram(sms, sms5);
                          }
                          else if ALARM_IS_OFF {
                               CopyConst2Ram(sms, sms6);
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 9:
                          if MAINS_VOLTAGE_IS_NORMAL {
                              GATE = 1;
                              Delay_ms(2000);
                              GATE = 0;
                              CopyConst2Ram(sms, sms4);
                              CLEAR_GATE_STATUS_FLAG
                          }
                          else {
                              CopyConst2Ram(sms, smsD);
                              CLEAR_GATE_STATUS_FLAG
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 10:
                          if MAINS_VOLTAGE_IS_NORMAL {
                              SEND_PULSE_MOTOR_TO_OPEN_GATE
                              CopyConst2Ram(sms, sms3);
                              SET_GATE_STATUS_FLAG
                          }
                          else if MAINS_VOLTAGE_IS_ABNORMAL {
                              CopyConst2Ram(sms, smsD);
                              CLEAR_GATE_STATUS_FLAG
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 11:
                          if GATE_IS_OPEN {
                                CopyConst2Ram(sms, sms3);
                          }
                          else if GATE_IS_CLOSED {
                                CopyConst2Ram(sms, sms4);
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 12:
                          if MAINS_VOLTAGE_IS_NORMAL  {
                              CopyConst2Ram(sms, sms8);
                              gateStatusFlag = 1;
                          }
                          else if MAINS_VOLTAGE_IS_ABNORMAL  {
                              CopyConst2Ram(sms, sms9);
                              gateStatusFlag = 0;
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 13:
                          iTemperatureThreshold = atol(temperatureThresholdData);
                          GIE_bit = 0;
                          EEPROM_Write(Temperature_Threshold_Address, iTemperatureThreshold);
                          Delay_ms(50);

                          GIE_bit = 1;
                          IntToStr(iTemperatureThreshold, sms);

                          CLEAR_WATCH_DOG_TIMER
                          Ltrim(sms);
                          Rtrim(sms);
                          CopyConst2Ram(buffer1, smsA);
                          strcat(buffer1, sms);
                          CopyConst2Ram(buffer2, smsB);
                          strcat(buffer1, buffer2);

                          strcpy(sms, buffer1);
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 14:
                          GIE_bit = 0;
                          iTemperatureThreshold = EEPROM_Read(Temperature_Threshold_Address);
                          Delay_ms(50);
                          GIE_bit = 1;
                          IntToStr(iTemperatureThreshold, sms);
                          CLEAR_WATCH_DOG_TIMER
                          Ltrim(sms);
                          Rtrim(sms);
                          CopyConst2Ram(buffer1, smsA);
                          strcat(buffer1, sms);
                          CopyConst2Ram(buffer2, smsB);
                          strcat(buffer1, buffer2);
                          strcpy(sms, buffer1);
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 15:
                          Get_Light_Delay_Value(sms, lightDelayCode);
                          lightDelayValue = atol(lightDelayCode);

                          if(TMR1ON_bit == 0) {
                              InitTimer1();
                          }

                          if(lightStatusFlag == 0) {
                              CopyConst2Ram(sms, smsF);
                              IntToStr(lightDelayValue, str);
                              Ltrim(str);
                              Rtrim(str);
                              strcat(sms, str);
                              CopyConst2Ram(str, smsH);
                              strcat(sms, str);
                          }
                          else if(lightStatusFlag == 1) {
                              CopyConst2Ram(sms, smsG);
                              IntToStr(lightDelayValue, str);
                              Ltrim(str);
                              Rtrim(str);
                              strcat(sms, str);
                              CopyConst2Ram(str, smsH);
                              strcat(sms, str);
                          }
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 16:
                          CopyConst2Ram(sms, smsE);
                          CLEAR_WATCH_DOG_TIMER
                          break;
                    case 17:
                          CopyConst2Ram(sms, smsI);
                          CopyConst2Ram(buffer1, smsC);
                          strcat(sms, buffer1);
                          strcat(sms, message);
                          CopyConst2Ram(buffer1, smsB);
                          strcat(sms, buffer1);
                          CopyConst2Ram(buffer1, smsJ);
                          strcat(sms, buffer1);
                          CLEAR_WATCH_DOG_TIMER
                          break;
             };

             CLEAR_WATCH_DOG_TIMER

             if((iEvent != 0) && (iEvent != 1)) {
                  SEND_SMS
             }
             else if((iEvent == 1) && (doOnceFlag == 0)) {
                  SEND_SMS
                  doOnceFlag = 1;
             }

             DELETE_ALL_SMS

             memset(sms, '\0', sizeof(sms));

             CLEAR_WATCH_DOG_TIMER
             CLEAR_EVENT_COUNTER
             CLEAR_SEND_SMS_FLAG
             CLEAR_WATCH_DOG_TIMER
        }
    }
}
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
I do not have the option to change the PIC which is 16F887.

The main circuit is based on that.
The SMS is an additional feature requested to me. I am trying to implement it. Which by the way is totally new to me.

Trying for the first time I am surprised I got this far.

I only need to send SMS to around 10 no.s max in an event.
I cannot get any GSM module except the old Maestro lite 100 (GSM/GPRS) modem. I need to buy one which will take a month to get me.
The modem I got is old and it does not support SmartPack software which would make everything a whole lot easier.

So I need to work with what I got to get the project approval.
The controller coding is done. All I need is to add the SMS feature.
The control part ate around 60% of ROM and 30% of RAM. This has a lotta Display messages updated periodically to a 20*40 LCD.

Currently I am using TMRo and TMR1.

I read around and saw the Rx is mostly done in ISR.
But like @jayanthd said it could be done other ways. I dunno. I am new to this modem thing.

All I need is to take the 16 bit reply and parse it.

If a character is a byte then why can I parse OK and ERROR ?
ERROR is clearly 5 bytes then.
 
Last edited:

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
And other thing.
The Modem does not always respond with an OK command to all the AT commands like.
If I send AT+CPIN?
I get just "+CPIN: Ready".
If not ready then just "ERROR"
Other commands , I get the reply followed by CR+LF and an "OK".

This is one weird modem. I guess that is why it has a SmartPack in it. With SmartPack, all I need is trigger an input and viola, SMS is gone to programmed phone book. I can even save the SMS I need to send.
Never new the one I got was way old and it does not support Smartpack. The new ones does. That is what the Maestro Guy I chatted with said.
 

jayanthd

Joined Jul 4, 2015
945
Modem gives only responses like OK and ERROR ? It doesn't give other data like SMS. Modem doesn't have command to inform about new SMS received ? Do you want to read SMS or just send SMS ?

Problem is bank switching. MikroC doesn't generate bank switching code for PIC16F devices. I think this is the problem. When you compile are you getting IRP_bit must be manually set to access xyz variable message ?

Zip and post your complete mikroC PRO PIC project files and I will modify the code for you so that it works without problems.

If you have circuit in proteus format then zip and post it also.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
No..I do not get bank switching errors.
As far as I know MikroC does not issue any errors and it compiles .
I am not simulating, I am running this on a development board EasyPIC7

The GSM part is done on a fresh PIC to test it.
The Project is complete on a prototype running flawlessly. I have the USART terminals free just in case and I was right. Customer did want the SMS. so all I need is to study the SMS fresh and implement it in to the project. I know I can do that once I understand the modem part.
And No I cannot give the project files. It does not belong to me once done.

If you can show me a way to parse the 16 bit characters my problem will be solved.
I do not need to read any SMS.
All I need to send the required SMS to certain numbers on fault event , tht's it.

I am doing all this to learn just in case if they ask me that need to see the modem response like SIM ready and signal strength which I am sure will come up due to the locations they might need to install the product. Which will benefit if poor signal areas comes up
I can for sure send the SMS since I can issue AT commands and read the "OK" response.

The code I am working on is at home. I am at work right now.

I need to find a way to read the 16 characters and to parse it.

The Modem responds to all AT command I give via USART terminal.
And responds in the way I posted above
It's my Parsing routine that does not respond to anything other that "OK" and "ERROR"
 

bwack

Joined Nov 15, 2011
113
Ok, I've been looking at your interrupt service routine (ISR), and I wonder how much time the "//BLAAH" part takes on timer overflow interrupts. I presume you arent doing anything lengthy in there like multiplication or what not?
Second, you can put the state machine into the main forever-loop, but it should work as long it is not taking up more than 1-2ms. Also if you put the statemachine outside the ISR, it is easier to debug it.

I suggest you do one of the following. Dumps. Store every incoming byte into a 16byte array in the ISR, and dump it out on the display in the main forever loop.
The second suggestion is to instead of resetting the state machine like you do now on unexpected characters, trap it ! Set it to a trap state, or individual trap states indicating where it failed.

The ISR length has been mentioned. I would have put the state machine outside, and just buffered to received chars. Perhaps in a circular buffer. It would only help if the //BLAAAH part is short.
 
Last edited:
Top