0

$USD

$USD
TUTORIALS ArduinoRobotics

GSM/GPRS/GPS Shield tutorial —— CID and One touch caller ID dial

DFRobot Jul 09 2012 812
What our live would be like without cellphone now? This small box seals in much magic includes establish calls, send out messages and even connect with net. We always keep wondering about how it works, whether it can do much for our robots and even more.

This project aims to demonstrate the interaction between you and your robot via GSM net. In this project, we can easily show the call number on LCD screen, and can make it call back using a push button. ( Send out command through SMS and establish voice connection via call.)The GPS/GPRS/GSM (Global System for Mobile Communications) module is controlled by serial port, while LCD by I2C interfaces .They are both on Arduino board.

Of course, what we can do is far beyond that show's above. With this module, we can easily get the location via the GPS integrated components , then sending out the data through GSM . Transmitting the data of your robot 's sensor using GPRS may be also a wonderful idea. This module shows so great power, just run your imagination!

Hardware 1.Arduino UNO 2.GPS/GPRS/GSM Module V2.0 3.I2C/TWI LCD2004 Module 4.Digital Push Button 5.2.54 pin  Header ?Jumper Wires 6.Battery Software
//DFRobot.com
//Compatible with the Arduino IDE 1.0
//Library version:1.1

//#steps:
//#    1. Combine the Arduino Board and GSM/GPS/GPRS Module, get power supply and connect arduino to pc through usb cable
//#    2. Connect the LCD Module to the GSM/GPS/GPRS Module via pin headers as:
//         LCD Module      GSM/GPS/GPRS Module
//            VCC                5V
//            GND                GND
//            SCL            ANALOG IN 5              
//            SDA            ANALOG IN 4
//#    3. Get the Push Botton connected to the GSM/GPS/GPRS Module as:(you can also redistribute the pins as your case)
//         Push Botton      GSM/GPS/GPRS Module
//             1                J9-1
//             2                J9-2
//             3                J9-3              
//#    4. Turn switch 1 on GSM/GPS/GPRS Module to EN(right side), upload the sketch to Arduino.
//#    5. Turn switch 1 back to left side. Turn switch 2 to arduino(right side).  
//#    6. If indication leds does not show GSM/GPS/GPRS Module at work, press reset key on the GSM/GPS/GPRS Module

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display
byte gsmDriverPin[3] = {
  3,4,5};//The default digital driver pins for the GSM and GPS mode
//If you ganna to change the digital driver pins
//or you have a conflict with D3~D5 on Arduino board,
//you could remove the J10~J12 jumpers to reconnect other driver pins for the module!

#define LCDCLEARLINE(a) lcd.setCursor(0,a);lcd.print("                    ");lcd.setCursor(0,a)//clear a'th line

#define LPIN 6
#define HPIN 7
#define KEYPIN 8
//You can change to any other pins accessible

#define S_IDLE 0
#define S_ATOK 1
#define S_SENDMESSAGE 2
#define S_GETMESSAGE 3
#define S_CALLIN 4
#define S_CALLBACK 5
#define S_CALLMISS 6
#define S_OPPOSITEBUSY 7
#define S_CALLLIST 8

#define D_RING "RING"
#define D_CALLIN "Call In"
#define D_CALLBACK "Call Back To"
#define D_CALLMISS "Missed Call From"
#define D_OPPOSITEBUSY "Opposite Busy"
#define D_CALLREADY "Call Ready"
#define D_ATOK "Module OK"

#define M_CALLIN "RING"
#define M_CALLMISS "NO CARRIER"
#define M_OPPOSITEBUSY "BUSY"
#define M_ATOK "OK"
#define M_CALLREADY "Call Ready"
#define M_CALLLIST "+CLCC:"

#define C_AT "AT"
#define C_ATOFF "ATE0"
#define C_CALLOUT "ATD"
#define C_CALLLIST "AT+CLCC"

void setup()
{
  Serial.begin(19200);
  InitGsmMode();
  InitLcd();
  InitKey();
}

void loop()
{
  String event_message="";

  char callin_num[12];
  callin_num[11]='�';

  int at_event=0;
  int last_event=at_event;

  Serial.println("ATE0");
  delay(1000);
  Serial.println("AT");
  at_event=1;
  delay(1000);

  while(1)
  { 
    event_message=SerialDataRead(event_message);

    event_message=SerialMessageCheck(event_message,&at_event,callin_num);

    LcdDisplay(&at_event, callin_num,&last_event); 

    SendATCommand(&at_event,callin_num);
  }
 } 
//#########################INITIAL FUNCTIONS##############################
void InitGsmMode(){
  //Init the driver pins for GSM function
  for(int i = 0 ; i < 3; i++){
    pinMode(gsmDriverPin[i],OUTPUT);
  }

  digitalWrite(3,LOW);//Enable the GSM mode
  digitalWrite(4,HIGH);//Disable the GPS mode
  //Output GSM Timing
  digitalWrite(5,HIGH);
  delay(1500);
  digitalWrite(5,LOW);  
  delay(1500);//need test
}
void InitLcd(void){
  //Init LCD display
  lcd.init();                     
  lcd.backlight();
  LiquidCrystal_I2C lcd(0x27,20,4);
}
void InitKey(void){
  //Init KEY
  pinMode(LPIN,OUTPUT);
  pinMode(HPIN,OUTPUT);
  pinMode(KEYPIN,INPUT_PULLUP);

  digitalWrite(LPIN,LOW);
  digitalWrite(HPIN,HIGH);
}
//################Serial Date read######################
String SerialDataRead(String MessageData){
  char CharRead;
  int i;

  if(Serial.available())//serial data read
  {  
    CharRead=Serial.read();

    if(CharRead!=10&&CharRead!=13) 
    {
      MessageData=MessageData+CharRead;
    }
   }
   else ;
   return MessageData;
}
//##################SERIAL MESSAGE CHECK#####################
String SerialMessageCheck(String Message,int *Event,char *Number){
  int messageIndex1;
  int messageIndex2;
  int i;

  if(Message.indexOf(M_ATOK)!=-1&&*Event==S_ATOK) //check AT OK
  {
    Message=""; *Event=S_IDLE;      lcd.setCursor(0,2);lcd.print(D_ATOK);lcd.setCursor(0,0);
  }
  else if(Message.indexOf(M_CALLREADY)!=-1) //check CALL READY
  {
    Message="";           lcd.setCursor(0,3);lcd.print(D_CALLREADY);
  }
  else if(Message.indexOf(M_CALLIN)!=-1&& *Event!=S_CALLIN&&*Event!=S_CALLLIST) //check "RING" only once
  {
    Message=""; *Event=S_CALLIN; Serial.println(C_CALLLIST);
  }
  else if(Message.indexOf(M_CALLMISS)!=-1) //check "NO CARRIER"
  {
    Message=""; *Event=S_CALLMISS;
   }
  else if(Message.indexOf(M_OPPOSITEBUSY)!=-1) //check OPPOSITE BUSY
  {
    Message=""; *Event=S_OPPOSITEBUSY;
   }
  else if(Message.indexOf(M_CALLLIST)!=-1) //check CALL IN NUMBER
  {
    messageIndex1=Message.indexOf('"');
    messageIndex2=Message.indexOf('"',messageIndex1+1);

    if( messageIndex1!=-1&&messageIndex2!=-1&&messageIndex1!=messageIndex2)
    {   
        for(i=0;i<11;i++)
        {
           Number[10-i]=Message[messageIndex2-(i+1)];//store CALL IN NUMBER
        }
        Number[11]='�';      
        Message="";
        *Event=S_CALLLIST;
    }
    else ;
   } 
  else; 
 return Message; 
}
//###################AT COMMAND SEND OUT######################
void SendATCommand(int *Event,char *Number){

  if(!digitalRead(KEYPIN))//call back 
  {
    delay(10);
    if(!digitalRead(KEYPIN))
    {
      while(!digitalRead(KEYPIN));
      *Event=S_CALLBACK;
      Serial.print(C_CALLOUT);
      Serial.print(Number);
      Serial.println(';');
    }
    else
    ;
  }
}
//##################LCD DISPLAY#################
void LcdDisplay(int *Event, char *Number,int *L_event){ 
 if(*Event!=*L_event)
 { 
    switch(*Event){    
      case S_IDLE: *L_event=*Event;break;     
      case S_SENDMESSAGE:break;   
      case S_GETMESSAGE: break;    
      case S_CALLIN: LCDCLEARLINE(0);*L_event=*Event;lcd.print(D_RING);break;    
      case S_CALLBACK: LCDCLEARLINE(0);*L_event=*Event;lcd.print(D_CALLBACK);LCDCLEARLINE(1);lcd.print(Number);break;    
      case S_CALLMISS: LCDCLEARLINE(0);*L_event=*Event;lcd.print(D_CALLMISS);LCDCLEARLINE(1);lcd.print(Number);break;    
      case S_OPPOSITEBUSY: LCDCLEARLINE(0);*L_event=*Event;lcd.print(Number);LCDCLEARLINE(1);lcd.print(D_OPPOSITEBUSY);break;    
      case S_CALLLIST: LCDCLEARLINE(0);*L_event=*Event;lcd.print(Number);LCDCLEARLINE(1);lcd.print(D_CALLIN);break;    
      default: break;
    }
  }
  else;
}