PIC to MAX232

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
The Blaah part is used in the original code. For testing I comment out the coding. So now it is actually using the Rx ISR only.

I changed to another method.
I am using an array of 17 to buffer the UART's 16 bit characters terminated with "CR"

I can nicely echo back from PIC to USART terminal 16 characters.

As of now I am trying to compare two strings to figure out what is what...still working on it.
I am getting a headache..been staring at the monitor far too long...My Head is filing up with ,
ANSI C String Libraries.
I think I will dream about it too.

The state machine gave me a dead end...nothing I tried went beyond "ERROR" & "OK". I think it is too long.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
Just so any one can find a mistake I am posting this...I need to sleep.

C:
unsigned short j;
const short n = 17; // 16 characters + 1 termination
char UART_Temp, i = 0, flag = 0;
unsigned int UART_Data[n];
unsigned int UART_Data_New[];

void interrupt(){

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

  // More BLAAAAAAH;
    }
  }
  /*const short n = 17;
char UART_Temp, i = 0, flag = 0;
unsigned int UART_Data[n]
*/

//******************************************************************************
  if(RCIE_bit){                   // If RX Interrupt enabled
    if(RCIF_bit){                 // and If RX Interrupt occured
      UART_Temp = UART1_Read();
      UART_Data[i] = UART_Temp;
      i++;

      if(UART_Temp == 13){ // looking for CR at the end of UART Data
        flag = 1;
      }
    }
  }
}

while(1){
  if (flag ==1) {
    j = 0;
    while(j < i) {
      UART1_Write(UART_Data[j]);
      j++;
    }
    i = 0;
    flag = 0;
  }

}
}
Like I said // Blaah is empty for now. What you see there is what I got. That area exists in Original code

I think I can do this if I can compare the UART_Data to the ones I need and enable Flags to do the work.
 

bwack

Joined Nov 15, 2011
113
I can try the modem respond strings (stimuli) on the state machine by pasting the switch block into a function, and then single step it with the simulator. Have you tried that before? it is golden.
Also after reading more on eusart and this pic I find that you should check the oerr bit for overrun errors. If the FIFO overflow, it will not receive more data before clearing the oerr bit. you cant clear it directly, you must clear and reset the cren bit. see
http://www.mikroe.com/chapters/view/76pic-basic-book-chapter-3-pic16f887-microcontroller/#c3v8
http://www.datasheetlib.com/datasheet/120884/pic16f887_microchip-technology.html?page=157#datasheet
you can also check the framing error bit to discard a response and send a new request to the modem.
 
Last edited:

bwack

Joined Nov 15, 2011
113
Ok I loaded your statemachine with
char array[] = "+COPS: 0,2,47201";

And it fails at O. Took me 30 seconds to find out after setting up the c code. Again, the debugger/simulator is golden.I have a video about that on youtube if anyones interested
firmware debugging (mikroC)

C:
       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;
I'll just leave this here. You'll figure it out ;) Looks like you have the same problem at case 21. case 19 is missing.

The test code:
C:
#define GSM_OK 1
#define ERROR 2
#define GSM_ERROR 3
#define GSM_DhiMobile 4
#define GSM_Ooredoo 5


char Uart_read, gsm_state, response, responseID, response_rcvd;
char array[] = "+COPS: 0,2,47201";
char count=0;

void main(){
OSCCON = 0x77;  // 8MHz Internal Osc.
ANSEL = 0x03;   // RA0 & RA1 as Analog Rest as Digital IO.
ANSELH = 0x00;  // Rest as Digital IO.
CM1CON0 = 0x07; // Disable Comparator 1.
CM2CON0 = 0x07; // Disable Comparator 2.
PORTA = 0;      // Clear PORT A.
PORTB = 0;      // Clear PORT B.
PORTC = 0;      // Clear PORT C.
PORTD = 0;      // Clear PORT D.
PORTE = 0;      // Clear PORT E.
TRISA = 0xFF;   // PORT A as Input.
TRISB = 0x00;   // PORT B as Output.
TRISC = 0xF8;   // RC <0-2> As Output, Rest as Input
TRISD = 0xFF;   //
TRISE = 0xFF;   // PORT E as Input.
//------- Initialte ADC & LCD & UART -------------------------------------------
ADC_Init();              // Innitiate LCD.
VCFG0_bit = 1;           // Externel Vref +.
VCFG1_bit = 0;           // Internal Vref - as GND.
//Lcd_Init();              // Innitiate LCD.
//Lcd_Cmd(_LCD_CLEAR);     // Clear LCD.
//Lcd_Cmd(_LCD_CURSOR_OFF);// Cursor OFF.
Delay_ms(100);              // Wait to Stabilize.
//UART1_Init(9600);           // Initialize UART module at 9600 baud.
Delay_ms(100);              // Wait for UART module to stabilize.
//------- Clear IRQ and Fire up the Timers -------------------------------------
OPTION_REG = 0x81;          // No pullups, Timer 0 at Prescaler 4.
INTCON = 0;                 // Disable All Interrupts First.
PIE1 = 0;                   // Disable All Peripheral Interrupts.
PIE2 = 0;                   // Disable All Peripheral Interrupts.
INTCON.T0IE = 1;            // Enable the Timer0 Interrupt.
INTCON.T0IF = 0;            // Clear Timer 0 Register Overflow Flag.
// TMR0 = TMR0set;           // Load Timer 0 with Preset.
T1CON = 0x30;               // No gate, Int Tcyc/8, TMR1 Stopped.
TMR1H = TMR1L = 0;          // Timer counts up to CCP value.
CCPR1 = 625;                // 1usTcyc * 8 Prescale * 625 = 5msec.
CCP1CON = 0x0B;             // NO Hardware PWM.
TMR1IF_bit = 0;             // PIR1 reg, Clear the TMR1 Overflow IRQ.
CCP1IF_bit = 0;             // Clear TMR1 IRQ flag bit.
RCIF_bit = 0;               // Clear Rx Interrupt Flag .................
T1CON.TMR1ON = 1;           // Start TIMER 1.
TMR1IE_bit = 1;             // Enable the Timer1 overflow Interrupt.
PIE1.RCIE = 1;              // Enable Rx Interrupt .................
CCP1IE_bit = 1;             // Enable the CCP1 Interrupt.
INTCON.GIE = 1;             // Global Interrupt Enabled.

//  Lcd_Out(1,1,Const2Ram(String,lcd2));
//  Lcd_Out(2,1,Const2Ram(String,lcd3));


  while(1){
       //Uart_Read = UART1_Read();   // Get received byte
       Uart_Read = array[count];
       count++;
// 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;
        }
      }
    }
}
but yeah, the cstring library is the way to go I think too. Remember to terminate the strings with 0x00.
 
Last edited:

jayanthd

Joined Jul 4, 2015
945
Use RealTerm Serial Terminal Software and issue all require AT commands to modem one at a time and it will give responses.

Just post the realterm screenshots. I need to know the exact responses with \r\n to write the parsing routine.

Also mention each response and tell me exactly what part of the response you want to get extracted.

I will then write a code for you.


This is a simple GSM project which I did.

C:
#define ON   1
#define OFF  0

#define HIGH 1
#define LOW  0

#define TRUE 1
#define FALSE 0

// GSM module connections
sbit gsmReset at RD7_bit;
sbit gsmReset_Direction at TRISD7_bit;
// End of GSM module connections

sbit LED at RD0_bit;

char myFlags = 0;

sbit sendSmsFlag at myFlags.B0;

char gsmBuffer[25];
char buffer1[20];
char sms[23];
char smsIndex[4];

char gsmAttempt = 0;
unsigned int gsmBufferIndex = 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=\"9742453836\"\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 sms1[] = "Light is ON";
const char sms2[] = "Light is OFF";

//Function Prototypes
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 CODE_TO_TURN_ON_LED_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode0)) == 0)
#define CODE_TO_TURN_OFF_LED_RECEIVED (strcmp(sms, CopyConst2Ram(buffer1, secretCode1)) == 0)

void interrupt() {
   
    if((RCIE_bit) && (RCIF_bit)) {
        if(OERR_bit) {
              OERR_bit = 0;
              CREN_bit = 0;
              CREN_bit = 1;
        }

        gsmBuffer[gsmBufferIndex++] = UART1_Read();
        gsmBuffer[gsmBufferIndex] = '\0';

        RCIF_bit = 0;
    }    
}

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

    return d;
}

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

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

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

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

    *s2 = '\0';                        
    asm clrwdt
}

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

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

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

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

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

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

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

    *s2 = '\0';
    asm clrwdt
}

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

    if(clr)memset(gsmBuffer, '\0', sizeof(gsmBuffer));    
    (*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) {
    asm clrwdt
   
    while(strstr(s1, CopyConst2Ram(s2, s3)) == 0) {
        CopyConst2Ram(s2, s4);
        strcat(s2, s5);
        strcat(s2, "\r");
        UART1_Write_Text(s2);
        DelayXSec(2);
       
        if((*gsmAttempt)++ == 3) {
            GSM_RESET() ;            
            (*gsmAttempt) = 0;
            (*idx) = 0;
            memset(gsmBuffer, '\0', sizeof(gsmBuffer));
        }
    }

    (*idx) = 0;

    Extract_SMS(s1, s6);
   
    if(clr)memset(gsmBuffer, '\0', sizeof(gsmBuffer));
    asm clrwdt
}

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) {
    asm clrwdt
   
    while(strstr(s1, CopyConst2Ram(s2, s3)) == 0) {
        asm clrwdt
        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);
       
        UART1_Write_Text(s8);
        Delay_ms(500);
        UART1_Write(0x1A);
       
        DelayXSec(6);
    }

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

void main() {

    asm clrwdt
    OPTION_REG = 0x87;
   
    CMCON = 0x07;
    ADCON1 = 0x87;

    TRISA = 0x00;
    TRISB = 0x00;
    TRISC = 0x80;
    TRISD = 0x00;
    TRISE = 0x00;
   
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;
       
    UART1_Init(9600);
    Delay_ms(100);
   
    RCIF_bit = 0;
    RCIE_bit = 1;
   
    PEIE_bit = 1;
    GIE_bit = 1;    

    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand1, &gsmBufferIndex, &gsmAttempt, 1);
    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand4, &gsmBufferIndex, &gsmAttempt, 1);
    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand5, &gsmBufferIndex, &gsmAttempt, 1);
    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand6, &gsmBufferIndex, &gsmAttempt, 1);
    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand7, &gsmBufferIndex, &gsmAttempt, 1);
    GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommandA, &gsmBufferIndex, &gsmAttempt, 1);    

    while(1) {

        asm clrwdt
               
        if(strstr(gsmBuffer, CopyConst2Ram(buffer1, atResponse3))) {
            DelayXSec(3);
            Get_SMS_Index(gsmBuffer, smsIndex);
            asm clrwdt
            GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand1, &gsmBufferIndex, &gsmAttempt, 1);            
            GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommand5, &gsmBufferIndex, &gsmAttempt, 1);
            GSM_Get_SMS(gsmBuffer, buffer1, atResponse1, atCommand8, smsIndex, &gsmBufferIndex, &gsmAttempt, sms, 1);
           
            Send_SMS(gsmBuffer, buffer1, atResponse1, atResponse4, atCommand1, atCommand5, atCommand9, sms, &gsmBufferIndex, &gsmAttempt, 1);          
            asm clrwdt    
            GSM_Send_Const_Command(gsmBuffer, buffer1, atResponse1, atCommandA, &gsmBufferIndex, &gsmAttempt, 1);
            memset(sms, '\0', sizeof(sms));
       
        }        
    }
}
 
Last edited:

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
I do have a problem...
My terminal software does not show \r\n in the response. Forgive me I am new to this modem thing.
I may be a hell of a repair tech and I can build and design circuits but I am very new to MikroC.
@jayanthd I do not understand most of the code you posted. The C String thing is a whole new area for me.

How I got so far in parsing thing is that I read a lot in google and from looking at codes I wrote everything. Partly I do understand it.
I had the same problem when I started with LCD. I cannot get the micro to display more than like 10 msg without display garbage after that.
Members in AAC and google reading helped to save the LCD msg in ROM array and pass to RAM for displaying. This saved the RAM space and I can display all with ROM full of messages.

Same thing happened with ADC oversampling and @joeyd999 idea helped me to do it. Even that part is yet to implement in my PSU design but yes my testing showed I can get 1mV resolution from a 10 bit ADC.

So this modem this also tough to begin with but if there are people (members of AAC) to give me pointers, I can do it.
Problem is this is not unlimited time kinda project that I do to learn and build for personal satisfaction but rather a Project that I want to get my hands on so time is a factor.

I have saved all the responses I get from the modem both in ASCII and HEX.
and from that I figuring out the CR and LF and I am not sure than modem responds to \r\n. Modem use the wavecom AT command set.
Modem does not always respond with just OK and ERROR. to certain commands it ends up with 16 bit character plus an OK.

@jayanthd Since you asked I am showing you the modem response in exactly how the respond is in terminal software.
( the command issued and received is enclosed in " " , it is not a part of the text)

When I send "AT ", I get
"AT"
"OK"
( You see above it has two lines, That is how modem replies. )

I send "ATE0 ", I get
"OK"
( ATE0 is echo cancel, After this if I issue "AT", I get just "OK" ).
note :- I am sending above commands during modem Init() routine at power on. To cancel echo

To check network (I use this to display network status on LCD)
I Issue "AT+COPS?"
(if not registered)
"+COPS: 0" ( yes there is "space" chr here ) ( this command not registered on network)
(if Ready, there are two response. depends on the carrier we have)
"+COPS: 0,2,47201" ( yes there is "space" chr here )
"OK"
or
"+COPS: 0,2,47202" ( yes there is "space" chr here )
"OK"
(above the last character tells which network the SIM is.

To check SIM (I use this to display SIM status on LCD)
I Issue "AT+CPIN?" I get
( If SIM is ready)
"+CPIN: READY" ( yes there is "space" chr here )
( If SIM is not ready)
"ERROR" ( this can be a lot, like PIN, blocked but do not care as the SIM that is installed needs ready to use one without PIN)

I Issue "AT+CSQ" I get
"+CSQ: 18,0" ( yes there is "space" chr here )
"OK"

These are the ones I need for now.

The last one is tricky (+CSQ: 18,0)
+CSQ is to check network strength, I am using this to show the network strength in dBm, I can do the calculation but I need to extract the 2 numerical values that is in above. the location is at "18"
The data in those two location will change from "00" to "31" or "99" .
99 is no network, where is 0- 31 is the strength.
I can do the calculation and send it LCD but my Problem is Extraction them which so far I have no idea on how to. May be like compare or copying --I do not know.

I guess that's all there is
 
Last edited:

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
@bwack
Same problem as case 19 and 21.
You mean parsing it failing at "O' or "0". :(
I have similar issues at two locations ?
You know you are forcing me to go back and look for mistakes. :oops:
Which is good by the way...:)

I will double check on it.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
It's because you need to fix case 7 also.
Ahh crap!..."7" too ??? o_O

Aaah you a killing me here....I feel so stupid :oops:

Still I am not using case 99 and 100 as of yet.

at 7 it checks for P and jumps O...No ?
My response is "+COPS: 0"
I am lost here.
 

bwack

Joined Nov 15, 2011
113
C:
      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;
Uart_Read is 'O', gsm_state is set to 8.
It is not P - skip
It is not S - else gsm_state = 0; <-- Thats the fault there. It can be fixed by doing this :) :

C:
       case 7: { // +CO or +CP or +CS
          if(Uart_Read == 'O')   // Iff we have 'O', it could be "COPS"
            gsm_state = 8;        // expecting 'P'
          else if(Uart_Read == 'P')   // Iff we have 'P', it could be "CPIN"
            gsm_state = 99;       // expecting 'I'
          else 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;
 

jayanthd

Joined Jul 4, 2015
945
Please use realterm free software for capturing the responses and post the screenshots. I need it. \r\n is nothing but <CR><LF> in realterm. It displays <CR><LF>

Without knowing how manu \r\n are there it will be difficult to guess and write parsing function.
 

bwack

Joined Nov 15, 2011
113
Looks like the double responses always end with OK, so you can ignore if the string matches "OK" .. ?

C:
  if (strncmp("OK",UART_Data,2)!=0) {
     // do something
  }
?
 

jayanthd

Joined Jul 4, 2015
945
Usually in modems OK will be actually \r\nOK\r\n

In my code at commands and responses checked can be changed in the const char variables.

Use At and ATE1. Don't use ATE0. If OK is not echoed then it will be difficult to check if error is received.

In my mikroC PRO PIC code just add more at commands and more responses and use it in the Send_Const_AT_Command() function. That's it.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
C:
      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;
Uart_Read is 'O', gsm_state is set to 8.
It is not P - skip
It is not S - else gsm_state = 0; <-- Thats the fault there. It can be fixed by doing this :) :

C:
       case 7: { // +CO or +CP or +CS
          if(Uart_Read == 'O')   // Iff we have 'O', it could be "COPS"
            gsm_state = 8;        // expecting 'P'
          else if(Uart_Read == 'P')   // Iff we have 'P', it could be "CPIN"
            gsm_state = 99;       // expecting 'I'
          else 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;
It could be that.
Question is why when it is 'O', it is not jumping to 8 ?
 

jayanthd

Joined Jul 4, 2015
945
Display As Ascii
Half Duplex

Connect your modem to PC and issue AT commands with CR+LF

In Send tab it has option to send CR+LF

Just send the screenshots and I will give code in 30 minutes.
 

jayanthd

Joined Jul 4, 2015
945
You are using only the commands mentioned in post #47 ?

If yes, then I will send you the code in 30 minutes.

The At commands and respones are similar to SIM900 and SIM800 modems.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
10,004
I am at work.
I can do this at home. I will post result around midnight.
That is around 30 minutes difference from you.
 
Top