PIC and gsm module communication

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

Viewing 16 reply threads
  • 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?

Viewing 16 reply threads
  • You must be logged in to reply to this topic.
Select your currency
ZAR South African rand
EUR Euro