Oops! It appears that you have disabled your Javascript. In order for you to see this page as it is meant to appear, we ask that you please re-enable your Javascript!

PIC and gsm module communication

Home Forums MikroC Pro for PIC Tutorial Discussions PIC and gsm module communication

This topic contains 17 replies, has 2 voices, and was last updated by  ddjoumetio 1 month, 1 week ago.

  • Author
    Posts
  • #5668

    ddjoumetio
    Participant

    greetings , please i do have a lot of difficulties making this program run correctly. i had it modified but i still have a problem , cause i can send ON at times and it sets a port high but when i send OFF is doesn’t set the same port low.

  • #5672

    Bitahwa Bindu
    Keymaster

    Your question is very broad, which program you are talking about?

    If you are talking about a project we published then refer the link here, so we know what you are talking about.

    What do you mean by run correctly? What works and what doesn’t work?

    Can you post your code?

    we can’t guess what exactly is wrong if you don’t provide enough information, like what you mean by program not running correctly, your code, what you are getting and what you are expecting, the PIC you are using, how you are testing, etc.

  • #5674

    ddjoumetio
    Participant

    signed char sms_in[90];
    char i=0;
    bit flag;
    void interrupt() {
    if(PIR1.RC1==1){
    if(UART1_Data_Ready()){
    sms_in[i] = UART1_Read();
    i++;
    RC4_bit=1;
    delay_ms(10000);
    if(i==88){
    flag=1;
    }
    }
    }
    }
    void main(){
    TRISC5_bit=0;
    TRISC4_bit=0;
    TRISC3_bit=0;
    INTCON.GIE=1;
    INTCON.PEIE=1;
    PIE1.RCIE=1;
    UART1_init(9600);
    delay_ms(2000);
    UART1_Write_Text(“AT\r\n”);
    delay_ms(2000);
    UART1_Write_Text(“AT+CMGF=1\r\n”);
    delay_ms(2000);
    UART1_Write_Text(“AT+CMGDA=\”DEL ALL\”\r\n”);
    delay_ms(2000);
    UART1_Write_Text(“AT+CNMI=2,2,0,0,0\r\n”);
    delay_ms(2000);
    while(1){
    RC3_bit=1;
    delay_ms(1500);
    UART1_Write_Text(“AT+CMGR=1\r\n”);
    delay_ms(2000);
    if(flag==1)
    {
    char q=75;
    if(sms_in[q]==’O’ && sms_in[q+1]==’N’ && sms_in[q+2]==’N’ ){
    RC5_bit=1;
    delay_ms(10000);
    UART1_Write(0X0D);
    UART1_Write(0X0A);
    flag=0;
    i=0;
    PIR1.RC1=0;
    }
    else if(sms_in[q]==’O’ && sms_in[q+1]==’F’ && sms_in[q+2]==’F’ ){
    RC5_bit=0;
    delay_ms(10000);
    UART1_Write(0X0D);
    UART1_Write(0X0A);
    i=0;
    flag=0;
    PIR1.RC1=0;
    }
    }
    }
    }

  • #5675

    ddjoumetio
    Participant

    i am a beginner in programming i want to on the led when i sent ONN using my phone and ….

     

  • #5677

    Bitahwa Bindu
    Keymaster

    This code is different from the code we published in our project. Why not use a code that is working then modify it to suit your needs?

    You can refer to our code to see what you did wrong: https://www.studentcompanion.co.za/sms-controlled-relay-with-pic-microcontroller-mikroc/

  • #5678

    ddjoumetio
    Participant

    The thing is i used your code to blink a LED with PIC16F877A, and when i send ON, it showed the message has been received but no action was performed by the Pic. So i don’t know if it is because i used that. But now i switched to PIC18F45K22…i will try run your code and see if the pic will perform an action upon receiving ON. Thanks

     

  • #5679

    ddjoumetio
    Participant

    And is it normal PIR1.RC1IF isn’t cleared at the end of the interrupt?

  • #5680

    Bitahwa Bindu
    Keymaster

    You test first a working code, once it’s working then you can modify it to fit your needs, and only modify the part that should be modified and add some comments so anybody who try to assist you can read your comments and understand what you did ad the reasons. The code you have posted is completely different form the code we have posted, only you understand this new code.

    Unfortunately we can’t waste time trying to figure out your code which is completely different to a working code.

  • #5681

    Bitahwa Bindu
    Keymaster

    REGISTER 9-4: PIR1: PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1

    • bit 5 RC1IF: EUSART1 Receive Interrupt Flag bit
      1 = The EUSART1 receive buffer, RCREG1, is full (cleared when RCREG1 is read)
      0 = The EUSART1 receive buffer is empty

    Reading RCREG does it for you

  • #5684

    ddjoumetio
    Participant

    /*****************************************************************************
    Project: SMS Controlled Relay with PIC Microcontroller
    http://www.studentcompanion.co.za
    Date: July, 2019
    ******************************************************************************/
    //
    // Modem responses
    //
    #define OK 0
    #define ON 1
    #define OFF 0
    //
    // AT commands used in the program
    //
    char AT[] = “AT”;
    char No_Echo[] = “ATE0”;
    char Mode_Text[] = “AT+CMGF=1”;
    char Delete_All[] = “AT+CMGD=1,4”;
    char Get_Message[] = “AT+CMGL=\”REC UNREAD\””;
    char Relay;
    char SMS_Arrived;
    //
    // States and State variables
    //
    char State = 0;
    char response_rcvd = 0;
    short responseID = -1;
    short response = -1;

    //
    // This function returns the modem response
    //
    short Modem_Response()
    {
    if(response_rcvd)
    {
    response_rcvd = 0;
    return responseID;
    }
    else
    return -1;
    }

    //
    // This function waits for a modem response
    //
    void Wait_Modem_Response(char resp)
    {
    while(Modem_Response() != resp);
    }

    //
    // This function sends a command to the modem. The command must be a string i.e.
    // it must be terminated with a NULL character. After ending teh command the
    // carriage return character is sent
    //
    void Send_To_Modem(char *s)
    {
    while(*s)
    {
    Uart1_Write(*s++);
    }
    Uart1_Write(0x0D);
    }

    //
    // This function initializes the GSM click board
    //
    void Init_GSM(void)
    {
    UART1_Init(9600); // Set UART to 9600 Baud
    Delay_Ms(3000); // Wait a while
    }

    //
    // This is the interrupt service routine. Modem responses are checked in this
    // routine in the form of a State machine. The program jumps to this routine
    // every time a character is received through the UART. A State machine code
    // is implemented inside this routine to check the modem response. The keywords
    // checked from the modem response are: OK, #ON and #OFF. Variable SMS_Arrived
    // is set to 1 when an SMS message is received from the mobile phone. An endless
    // loop in the main program controls the relay accordingly
    //
    void interrupt()
    {
    char Dat;

    LATB = 0x02; // Set pin RB1 high

    if(PIR1.RC1IF == 1) // If this is a UART1 interrupt
    {
    Dat = Uart1_Read(); // Read he UARt1 data

    switch(State) // Start of the State machine
    {
    case 0: // State 0
    {
    response = -1;
    if(Dat == ‘O’)State = 1; // Response starts with ‘O’
    if(Dat == ‘#’)State = 100; // Next State is 100
    break;
    }

    case 1: // State 1
    {
    if(Dat == ‘K’) // Next response char is ‘K’
    {
    response = OK; // Response is ‘OK’
    State = 2; // Next State is 2
    }
    break;
    }

    case 2: // State 2
    {
    if(Dat == 0x0D) // A carriage return ?
    State = 3; // Next State is 3
    else
    State = 0; // Next State is 0
    break;
    }

    case 3: // State 3
    {
    if(Dat == 0x0A) // A line feed ?
    {
    response_rcvd = 1; // Response received flag is set
    ResponseID = response; // Response ID is set
    }
    State = 0; // Next State is 0
    break;
    }

    case 100:
    {
    if(Dat == ‘O’)State = 101; // So far #O detected
    break;
    }

    case 101:
    {
    if(Dat == ‘N’) // #ON detected
    {
    Relay = ON; // Relay to be turned ON
    SMS_Arrived = 1; // SMS arrived flag
    State = 0;
    }
    if(Dat == ‘F’)State = 102; // #OF detected
    break;
    }

    case 102:
    {
    if(Dat == ‘F’) // #OFF detected
    {
    Relay = OFF; // Relay to be turned OFF
    SMS_Arrived = 1; // SMS arrived flag
    State = 0;
    }
    break;
    }

    default: // Otherwise…
    {
    State = 0; // Next State is 0
    break;
    }
    }
    }
    }

    //
    // This function enables (initializes) the UART1 interrupts. Thus, whenever a
    // character is received from the serial port, the program jumps to the
    // interrupt service routine
    //
    void Init_UART1_Interrupts(void)
    {
    PIE1.RC1IE = 1;
    INTCON.PEIE = 1;
    INTCON.GIE = 1;
    }

    //
    // Start of MAIN program
    //
    void main()
    {
    TRISB = 0x00; // Set RB0 as output for relay

    LATB = 0x00; // Relay deactivated to start with

    Delay_Ms(5000); // Wait until GSM board is stabilized
    Init_GSM(); // Initialize the GSM click board
    Init_UART1_Interrupts(); // Initialize UART1 interrupts
    //
    // Auto-baud detect. Keep sending AT commands and wait until “OK” is received
    //
    while(1)
    {
    Send_To_Modem(AT);
    Delay_Ms(200);
    if(Modem_Response() == OK)break;
    }
    //
    // At this point the modem baud rate is set to 9600
    // We can now start sending our AT commands to the modem

    //
    //
    // Disable Echo
    //
    Send_To_Modem(No_Echo);
    Wait_Modem_Response(OK);
    //
    // Set SMS mode to text
    //
    Send_To_Modem(Mode_Text);
    Wait_Modem_Response(OK);
    //
    // The following is an endless loop where the program looks for an SMS message
    // from the mobile phone. The program works in polled mode
    //
    //
    // Delete all messages to start with
    //
    Delay_Ms(5000);
    SMS_Arrived = 0;
    Send_To_Modem(Delete_All);
    Wait_Modem_Response(OK);
    //
    // Entering the endless loop where teh program looks for an SMS message and then
    // controls the Relay accordingly. The comamnd #ON activates the Relay. On the
    // other hand the command #OFF deactivates th Relay. Any electrical equipment
    // conencted to the Relay is thus controlled remotely from a mobile phone
    while(1)
    {
    Send_To_Modem(Get_Message); // Check if any SMS arrived
    //
    // Wait until modem is ready
    //
    while(1)
    {
    Send_To_Modem(AT);
    Delay_Ms(1000);
    if(Modem_Response() == OK)break;
    }
    //
    // Check if a message has arrived
    //
    if(SMS_Arrived == 1) // A new SMS arrived
    {
    SMS_Arrived = 0; // Clear SMS arrived flag

    if(Relay == ON)
    {
    LATB = 0x01 ; // Set the pin RB0 high
    }

    else if(Relay == OFF)
    LATB = 0x00; // Set the pin LOW

    //
    // Delete all messages
    //
    Send_To_Modem(Delete_All); // Delete all existing messages
    Wait_Modem_response(OK); // Wait until modem is ready
    }
    Delay_Ms(10000);
    }
    }

  • #5685

    ddjoumetio
    Participant

    I’ve never been part of a forum, it’s my first time…so don’t know if i have to follow some rules and regulation.

    what i added was to blink LEDs, my main purpose is being able to send, receive and make action based on message received using pic. i have succeeded sending a message to my number, so i wish to receive now a message and perform an action. But my LED is not coming ON…i am using Pic18f45k22.

  • #5686

    Bitahwa Bindu
    Keymaster

    HI, What message are you sending as an SMS to switch ON your relay?

    How are you connecting your LED to the PIC?

    Are you able to blink your LED in Code without SMS? What SMS module are you using? Did you delete all SMS messages from the SIM card before using it?

  • #5690

    ddjoumetio
    Participant

    Hi, i am sending “ON”, and in the condition where the message ON is received…i put on an LED. meanwhile when OFF i put it OFF.

    I connected my LED to  RB0 of the pic and another to RB1 (it is on when an interrupt occurs).

    Yes am able to blink the LED.

    Am using SIM900.

    Didn’t delete , because i saw the  AT  command “AT+CMGD=1,4” to delete messages and i thought it wont make a difference. But i will do that right away…

     

  • #5691

    Bitahwa Bindu
    Keymaster

    In the code, to Switch On the LED, you must send the Command is #ON and to switch OFF is #OFF. Not ON or OFF. You must read and understand the code, if you want to use ON and OFF then change the code.

    What do you want to happen on PORTB1? what are you getting at the moment?

     

  • #5692

    ddjoumetio
    Participant

    Thanks a lot i had difficulties at the level of the “#” in the interrupt.

    portb1… i wish to know when an interrupt occurs. So i blink LED at different level of the program to see where the program is going  wrong, dont know if its a bad programming practice or not.

    So i tried with the #ON and still nothing, so i place a blinking process in the code where the  pic waits for the response OK…when i mount it, it just keeps blinking continously, so don’t know if am not doing something correctly.

     

  • #5693

    ddjoumetio
    Participant

    // LCD setup pin
    sbit LCD_RS at LATD4_bit;
    sbit LCD_EN at LATD5_bit;
    sbit LCD_D4 at LATD0_bit;
    sbit LCD_D5 at LATD1_bit;
    sbit LCD_D6 at LATD2_bit;
    sbit LCD_D7 at LATD3_bit;

    sbit LCD_RS_Direction at TRISD4_bit;
    sbit LCD_EN_Direction at TRISD5_bit;
    sbit LCD_D4_Direction at TRISD0_bit;
    sbit LCD_D5_Direction at TRISD1_bit;
    sbit LCD_D6_Direction at TRISD2_bit;
    sbit LCD_D7_Direction at TRISD3_bit;

    // END of LCD setup

    #define OK 0
    #define ON 1
    #define OFF 0
    //
    // AT commands used in the program
    //
    char AT[] = “AT”;
    char No_Echo[] = “ATE0”;
    char Mode_Text[] = “AT+CMGF=1”;
    char Delete_All[] = “AT+CMGD=1,4”;
    char Get_Message[] = “AT+CMGL=\”REC UNREAD\””;
    char Relay;
    char SMS_Arrived;
    //
    // States and State variables
    //
    char State = 0;
    char response_rcvd = 0;
    short responseID = -1;
    short response = -1;

    //
    // This function returns the modem response
    //
    short Modem_Response()
    {
    if(response_rcvd)
    {
    response_rcvd = 0;
    return responseID;
    }
    else
    return -1;
    }

    //
    // This function waits for a modem response
    //
    void Wait_Modem_Response(char resp)
    {
    while(Modem_Response() != resp);
    }

    //
    // This function sends a command to the modem. The command must be a string i.e.
    // it must be terminated with a NULL character. After ending teh command the
    // carriage return character is sent
    //
    void Send_To_Modem(char *s)
    {
    while(*s)
    {
    Uart1_Write(*s++);
    }
    Uart1_Write(0x0D);
    }

    //
    // This function initializes the GSM click board
    //
    void Init_GSM(void)
    {
    UART1_Init(9600); // Set UART to 9600 Baud
    Delay_Ms(3000); // Wait a while
    }

    //
    // This is the interrupt service routine. Modem responses are checked in this
    // routine in the form of a State machine. The program jumps to this routine
    // every time a character is received through the UART. A State machine code
    // is implemented inside this routine to check the modem response. The keywords
    // checked from the modem response are: OK, #ON and #OFF. Variable SMS_Arrived
    // is set to 1 when an SMS message is received from the mobile phone. An endless
    // loop in the main program controls the relay accordingly
    //
    void interrupt()
    {
    char Dat;

    if(PIR1.RC1IF == 1) // If this is a UART1 interrupt
    {
    Dat = Uart1_Read(); // Read he UARt1 data

    switch(State) // Start of the State machine
    {
    case 0: // State 0
    {
    response = -1;
    if(Dat == ‘O’)State = 1; // Response starts with ‘O’
    if(Dat == ‘#’)State = 100; // Next State is 100
    break;
    }

    case 1: // State 1
    {
    if(Dat == ‘K’) // Next response char is ‘K’
    {
    response = OK; // Response is ‘OK’
    State = 2; // Next State is 2
    }
    break;
    }

    case 2: // State 2
    {
    if(Dat == 0x0D) // A carriage return ?
    State = 3; // Next State is 3
    else
    State = 0; // Next State is 0
    break;
    }

    case 3: // State 3
    {
    if(Dat == 0x0A) // A line feed ?
    {
    response_rcvd = 1; // Response received flag is set
    ResponseID = response; // Response ID is set
    }
    State = 0; // Next State is 0
    break;
    }

    case 100:
    {
    if(Dat == ‘O’)State = 101; // So far #O detected
    break;
    }

    case 101:
    {
    if(Dat == ‘N’) // #ON detected
    {
    Relay = ON; // Relay to be turned ON
    SMS_Arrived = 1; // SMS arrived flag
    State = 0;
    }
    if(Dat == ‘F’)State = 102; // #OF detected
    break;
    }

    case 102:
    {
    if(Dat == ‘F’) // #OFF detected
    {
    Relay = OFF; // Relay to be turned OFF
    SMS_Arrived = 1; // SMS arrived flag
    State = 0;
    }
    break;
    }

    default: // Otherwise…
    {
    State = 0; // Next State is 0
    break;
    }
    }
    }
    }

    //
    // This function enables (initializes) the UART1 interrupts. Thus, whenever a
    // character is received from the serial port, the program jumps to the
    // interrupt service routine
    //
    void Init_UART1_Interrupts(void)
    {
    PIE1.RC1IE = 1;
    INTCON.PEIE = 1;
    INTCON.GIE = 1;
    }

    //
    // Start of MAIN program
    //
    void main()
    {
    TRISB = 0x00; // Set RB0 as output for relay
    ANSELB = 0x00; // Set Port B as digital pin
    ANSELD = 0x00; // Set port D as digital pin
    LATB = 0x00;

    TRISD = 0x00;
    Lcd_Init(); //LCD Initialized
    Lcd_Cmd(_LCD_CLEAR); //LCD Clear
    Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor OFF

    //Displaying message on LCD
    Lcd_out(1, 1, “Welcome Home”);
    Lcd_out(2, 2, “OWNER”);

    Delay_Ms(5000); // Wait until GSM board is stabilized
    Init_GSM(); // Initialize the GSM click board
    Init_UART1_Interrupts(); // Initialize UART1 interrupts
    //
    // Auto-baud detect. Keep sending AT commands and wait until “OK” is received
    //
    while(1)
    { LATB = 0x02; // Set RB1  high
    delay_ms(2000);
    LATB = 0x00; // Set RB1 low
    Send_To_Modem(AT);
    Delay_Ms(200);
    if(Modem_Response() == OK)break;
    }
    LATB = 0x02; // Set pin RB1 high
    //
    // At this point the modem baud rate is set to 9600
    // We can now start sending our AT commands to the modem

    //
    //
    // Disable Echo
    //
    Send_To_Modem(No_Echo);
    Wait_Modem_Response(OK);
    //
    // Set SMS mode to text
    //
    Send_To_Modem(Mode_Text);
    Wait_Modem_Response(OK);
    //
    // The following is an endless loop where the program looks for an SMS message
    // from the mobile phone. The program works in polled mode
    //
    //
    // Delete all messages to start with
    //
    Delay_Ms(5000);
    SMS_Arrived = 0;
    Send_To_Modem(Delete_All);
    Wait_Modem_Response(OK);
    //
    // Entering the endless loop where teh program looks for an SMS message and then
    // controls the Relay accordingly. The comamnd #ON activates the Relay. On the
    // other hand the command #OFF deactivates th Relay. Any electrical equipment
    // conencted to the Relay is thus controlled remotely from a mobile phone
    while(1)
    {
    Send_To_Modem(Get_Message); // Check if any SMS arrived
    //
    // Wait until modem is ready
    //
    while(1)
    {
    Send_To_Modem(AT);
    Delay_Ms(1000);
    if(Modem_Response() == OK)break;
    }
    //
    // Check if a message has arrived
    //
    if(SMS_Arrived == 1) // A new SMS arrived
    {
    SMS_Arrived = 0; // Clear SMS arrived flag

    if(Relay == ON)
    {
    LATB = 0x01 ; // Set the pin RB0 high
    }

    else if(Relay == OFF)
    LATB = 0x00; // Set the pin LOW

    //
    // Delete all messages
    //
    Send_To_Modem(Delete_All); // Delete all existing messages
    Wait_Modem_response(OK); // Wait until modem is ready
    }
    Delay_Ms(10000);
    }
    }

  • #5696

    ddjoumetio
    Participant

    i figured out that my GSM doesn’t seem to be sending the OK, in the first while loop. Any reason why?

You must be logged in to reply to this topic.

Select your currency
EUR Euro
USD United States (US) dollar