In this do it yourself activity, we are going to create Simple Mobile Phone using raspberry pi in which gsm module is used to make or answer the call and also to send or read SMS. This raspberry pi phone also has a microphone and speaker for talking over it. This project will also ensure that there is good interfacing of GSM modules, nay, different models of GSM modules, with the Raspberry Pi and all the code that is needed to make any phone work. Earlier, we developed the same sort of Simple Mobile Phone using Arduino, details are here.
Required Components:
- Raspberry Pi 3 (any model)
- GSM Module
- 16×2 LCD
- 4×4 Keypad (user may use membrane keypad)
- 10k pot
- Breadboard
- Connecting jumper wire
- Power supply
- Speaker
- MIC
- SIM Card
- Speaker
- Audio Amplifier Circuit (Optional)
Working Explanation:
In this DIY project, combining the Raspberry Pi 3 with the GSM module SIM900A, we have streamlined the device’s features and components. The 4×4 Alphanumeric Keypad allows users to input various commands, including, but not limited to, entering phone numbers, sending and reading SMS messages, and making and receiving voice calls. The GSM module facilitates communication with the network, while the MIC and Speaker enable voice calling and ringtone functionality. Meanwhile, the 16×2 LCD display provides users with critical information, such as messages, instructions, and alerts.
Alphanumeric input allows for the entry of both numbers and alphabets using a single keypad. In this implementation, we have connected a 4×4 keypad to the Raspberry Pi and developed code to support the input of alphabetic characters. For a detailed look at the code, please refer to the Code section below.
The operation of this project is straightforward. The Alphanumeric Keypad plays a crucial role in executing all the features. To gain a comprehensive understanding of the process, please refer to the Full code and a Demo Video provided below. In the following sections, we will thoroughly discuss each of the four key features of this project.
Explaining Four Features of Raspberry Pi Mobile Phone:
1. Make a Call:
For making a call with help of our Raspberry Pi based Phone we have to type ‘C’ and then it’s necessary to input the Mobile Number from which call is to be made. Number will be entered by the help of number pad or alphanumeric keypad. what ever number we have to enter after that we have to press the key ‘C’. Now Raspberry Pi will process for connecting the call to the entered number by using AT command:Now Raspberry Pi will process for connecting the call to the entered number by using AT command:
ATDxxxxxxxxxx; <Enter> where xxxxxxxxx is entered Mobile Number.
2. Receive a Call:
Making a call: It is very easy to receive a call. When someone is calling to your system by using the SIM number, which is there in GSM module then your system will display’Incoming…’ message on the LCD with the incoming number of the caller. Let’s press ‘A’ to attend this call Now, or something like this:
ATA <enter>
3. Send SMS:
When we want to Send a SMS using our Raspberry Pi based Phone, then One has to Press ‘D’. Next, it will prompt for the Recipient Number, meaning ‘to whom’ are we going to send the short message service. Then, after typing the phone number we need digest that the next number we have to press ‘D’ and LCD want to know the message. Next step is, similar to the what a normal mobile phone, we have the keypad to type the message and then after typing the message we have to again press ‘D’ to dispatch the SMS. To Send SMS Raspberry Pi sends given command:To Send SMS Raspberry Pi sends given command:
AT+CMGF=1 <enter> AT+CMGS=”xxxxxxxxxx” <enter> where: xxxxxxxxxx is entered mobile number
And send 26 to GSM to send SMS.
4. Receive and Read SMS:
This feature is also basic. In this, GSM will receive SMS and stores it in SIM card.Moreover, it will transmit viz., sending, SMS and stores it in SIM card. And the received SMS indication is constantly checked over UART by Raspberry Pi. In every instance of a new message being received the LCD will display the “New message” text and all we have to do is to Press ‘B’ to read the SMS. SMS Received indication is:
+CMTI: “SM”,6 Where 6 is message location where it stored in SIM card.
When Raspberry Pi receives this kind of indication ‘SMS received’ then it takes the location of the storage of the SMS and then issues a command to the GSM to read those SMSs which have been received. And display a message ‘New Message’ on over the LCD.
AT+CMGR=<SMS stored location><enter>
Now GSM sends stored message to Raspberry Pi and then Raspberry Pi extract main SMS and display it over the LCD.
Note: There is no coding for MIC and Speaker.
Check the Full code and a Demo Video below to properly understand the process.
Circuit Diagram and Explanation:
RS, EN and the data lines (D4, D5, D6 and D7) of the 16×2 LCD module are interfaced to the GPIO pin no 18, 23, 24, 25, 8 and 7 of the Raspberry Pi respectively. Rx and Tx pin of the GSM Module is connected with the Tx and Rx of the Raspberry directly and the ground of the GSM must be connected to the ground of the Raspberry. Row pins R1, R2, R3, R4 of 4 X 4 keypad are connected with GPIO pin numbers 12, 16, 20, and 21 of the Raspberry Pi, and the column pins C1, C2, C3, C4 of the same keypad are connected with GPIO pin numbers 26, 19, 13, and 6 of the Raspberry Pi.
This Audio Amplifier Circuit is directly connected to the mic+ and mic- of the GSM module, and the speaker is connected with the help of this circuit at the sp+ and sp- pins of the GSM module. This is the audio amplifier circuit, and you can avoid this circuit and directly connect the speaker to the GSM module.
Programming Explanation:
Programming part of this Raspberry Pi Mobile Phone is a little complex for those who have no programming background. Here we are using Python language for the Program. For new Raspberry Pi users, they must read our previous posts on the basics of Raspberry Pi and installing Raspberry Jessie OS on Pi.
In this code, we have created def keypad(): function for interfacing simple keypad with ability of entering numbers. And for entering alphabets, we have created def alphaKeypad(): which at the same time can used for typing the alphabets. Now we have have made this keypad multi-functioning just as Arduino keypad library it allows the user to perform all the wished actions. As it can be seen from the figures by employing this keypad one can enter characters and integer using only the 10 keys.
For instance if we press key 2 (abc2) it illuminate ‘a’ if you press it again it replaces ‘a’ with ‘b’ and if you press three times it replaces ‘b’ with ‘c’ at the same location of the LCD. If we wait for some time after pressing of key, cursor will be automatically shifted to next place or position on LCD. Now as we have reached the next index in this case now we can enter next char or number. The same is done for the rest of keys For the case of other keys, the same procedure is followed.
def keypad(): for j in range(4): gpio.setup(COL[j], gpio.OUT) gpio.output(COL[j], 0) ch=0 for i in range(4): if gpio.input(ROW[i])==0: ch=MATRIX[i][j] return ch while (gpio.input(ROW[i]) == 0): pass gpio.output(COL[j],1)
def alphaKeypad(): lcdclear() setCursor(x,y) lcdcmd(0x0f) msg="" while 1: key=0 count=0 key=keypad() if key == '1': ind=0 maxInd=6 Key='1' getChar(Key, ind, maxInd) .... ..... ..... .....
First of all, in this python script we have included some required libraries and defined pins for LCD, keypad and other components:
import RPi.GPIO as gpio import serial import time msg="" alpha="1!@.,:?ABC2DEF3GHI4JKL5MNO6PQRS7TUV8WXYZ90 *#" x=0 y=0 MATRIX = [ ['1','2','3','A'], ['4','5','6','B'], ['7','8','9','C'], ['*','0','#','D'] ] ROW = [21,20,16,12] COL = [26,19,13,6] ... ..... ..... .....
Now it’s time to give direction to the pins:
gpio.setwarnings(False) gpio.setmode(gpio.BCM) gpio.setup(RS, gpio.OUT) gpio.setup(EN, gpio.OUT) gpio.setup(D4, gpio.OUT) gpio.setup(D5, gpio.OUT) gpio.setup(D6, gpio.OUT) gpio.setup(D7, gpio.OUT) gpio.setup(led, gpio.OUT) gpio.setup(buz, gpio.OUT) gpio.setup(m11, gpio.OUT) gpio.setup(m12, gpio.OUT) gpio.setup(button, gpio.IN) gpio.output(led , 0) gpio.output(buz , 0) gpio.output(m11 , 0) gpio.output(m12 , 0)
Then initialize Serial communication like below:
Serial = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=2)
Now we need to write some function for driving LCD. Function def lcdcmd(ch): is used for sending command to LCD and def lcdwrite(ch): function is used for sending data to LCD. Along with these functions, def lcdclear(): is used to clear the LCD, def setCursor(x,y): is used to set cursor position at the LCD and def lcdprint(Str): is used to print string on LCD.
def lcdcmd(ch): gpio.output(RS, 0) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) .... ..... ..... ....
def lcdwrite(ch): gpio.output(RS, 1) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) if ch&0x20==0x20: gpio.output(D5, 1) .... ..... ..... ....
def lcdclear(): lcdcmd(0x01) def lcdprint(Str): l=0; l=len(Str) for i in range(l): lcdwrite(ord(Str[i])) def setCursor(x,y): if y == 0: n=128+x elif y == 1: n=192+x lcdcmd(n)
After this we need to write some functions for sending SMS, receiving SMS, making a call and attending the call.
Function def call(): is used for making the call. And function def receiveCall(data): is used to showing the incoming message and number on LCD. Finally def attendCall(): is used to attend the call.
Function def sendSMS(): is used to write and send the message with the help of alphaKeypad() function. And function def receiveSMS(data): is used receive and retrieve the location of SMS. Finally def readSMS(index): is used to display the message on LCD.
You can find all the above functions in Code given below.
So this is how you can convert your Raspberry Pi into a mobile phone with help of GSM module. Also check this Raspberry Pi Touch Screen Smart Phone.
Code
import RPi.GPIO as gpio import serial import time msg="" # 0 7 11 15 19 23 27 32 36 414244 ROLL45 alpha="1!@.,:?ABC2DEF3GHI4JKL5MNO6PQRS7TUV8WXYZ90 *#" x=0 y=0 MATRIX = [ ['1','2','3','A'], ['4','5','6','B'], ['7','8','9','C'], ['*','0','#','D'] ] ROW = [21,20,16,12] COL = [26,19,13,6] moNum=['0','0','0','0','0','0','0','0','0','0'] m11=17 m12=27 led=5 buz=26 button=19 RS =18 EN =23 D4 =24 D5 =25 D6 =8 D7 =7 HIGH=1 LOW=0 gpio.setwarnings(False) gpio.setmode(gpio.BCM) gpio.setup(RS, gpio.OUT) gpio.setup(EN, gpio.OUT) gpio.setup(D4, gpio.OUT) gpio.setup(D5, gpio.OUT) gpio.setup(D6, gpio.OUT) gpio.setup(D7, gpio.OUT) gpio.setup(led, gpio.OUT) gpio.setup(buz, gpio.OUT) gpio.setup(m11, gpio.OUT) gpio.setup(m12, gpio.OUT) gpio.setup(button, gpio.IN) gpio.output(led , 0) gpio.output(buz , 0) gpio.output(m11 , 0) gpio.output(m12 , 0) for j in range(4): gpio.setup(COL[j], gpio.OUT) gpio.setup(COL[j],1) for i in range (4): gpio.setup(ROW[i],gpio.IN,pull_up_down=gpio.PUD_UP) Serial = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=2) data="" def begin(): lcdcmd(0x33) lcdcmd(0x32) lcdcmd(0x06) lcdcmd(0x0C) lcdcmd(0x28) lcdcmd(0x01) time.sleep(0.0005) def lcdcmd(ch): gpio.output(RS, 0) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) if ch&0x20==0x20: gpio.output(D5, 1) if ch&0x40==0x40: gpio.output(D6, 1) if ch&0x80==0x80: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) # Low bits gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x01==0x01: gpio.output(D4, 1) if ch&0x02==0x02: gpio.output(D5, 1) if ch&0x04==0x04: gpio.output(D6, 1) if ch&0x08==0x08: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) def lcdwrite(ch): gpio.output(RS, 1) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) if ch&0x20==0x20: gpio.output(D5, 1) if ch&0x40==0x40: gpio.output(D6, 1) if ch&0x80==0x80: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) # Low bits gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x01==0x01: gpio.output(D4, 1) if ch&0x02==0x02: gpio.output(D5, 1) if ch&0x04==0x04: gpio.output(D6, 1) if ch&0x08==0x08: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) def lcdclear(): lcdcmd(0x01) def lcdprint(Str): l=0; l=len(Str) for i in range(l): lcdwrite(ord(Str[i])) def setCursor(x,y): if y == 0: n=128+x elif y == 1: n=192+x lcdcmd(n) def keypad(): for j in range(4): gpio.setup(COL[j], gpio.OUT) gpio.output(COL[j], 0) ch=0 for i in range(4): if gpio.input(ROW[i])==0: ch=MATRIX[i][j] #lcdwrite(ord(ch)) # print "Key Pressed:",ch # time.sleep(2) return ch while (gpio.input(ROW[i]) == 0): pass gpio.output(COL[j],1) # callNum[n]=ch def serialEvent(): data = Serial.read(20) #if data != '\0': print data data="" def gsmInit(): lcdclear() lcdprint("Finding Module"); time.sleep(1) while 1: data="" Serial.write("AT\r"); data=Serial.read(10) print data r=data.find("OK") if r>=0: break time.sleep(0.5) while 1: data="" Serial.write("AT+CLIP=1\r"); data=Serial.read(10) print data r=data.find("OK") if r>=0: break time.sleep(0.5) lcdclear() lcdprint("Finding Network") time.sleep(1) while 1: data="" Serial.flush() Serial.write("AT+CPIN?\r"); data=Serial.read(30) print data r=data.find("READY") if r>=0: break time.sleep(0.5) lcdclear() lcdprint("Finding Operator") time.sleep(1) while 1: data="" Serial.flush() Serial.read(20) Serial.write("AT+COPS?\r"); data=Serial.read(40) #print data r=data.find("+COPS:") if r>=0: l1=data.find(",\"")+2 l2=data.find("\"\r") operator=data[l1:l2] lcdclear() lcdprint(operator) time.sleep(3) print operator break; time.sleep(0.5) Serial.write("AT+CMGF=1\r"); time.sleep(0.5) # Serial.write("AT+CNMI=2,2,0,0,0\r"); # time.sleep(0.5) Serial.write("AT+CSMP=17,167,0,0\r"); time.sleep(0.5) def receiveCall(data): inNumber="" r=data.find("+CLIP:") if r>0: inNumber="" inNumber=data[r+8:r+21] lcdclear() lcdprint("incoming") setCursor(0,1) lcdprint(inNumber) time.sleep(1) return 1 def receiveSMS(data): print data r=data.find("\",") print r if r>0: if data[r+4] == "\r": smsNum=data[r+2:r+4] elif data[r+3] == "\r": smsNum=data[r+2] elif data[r+5] == "\r": smsNum=data[r+2:r+5] else: print "else" print smsNum if r>0: lcdclear() lcdprint("SMS Received") setCursor(0,1) lcdprint("Press Button B") print "AT+CMGR="+smsNum+"\r" time.sleep(2) return str(smsNum) else: return 0 def attendCall(): print "Attend call" Serial.write("ATA\r") data="" data=Serial.read(10) l=data.find("OK") if l>=0: lcdclear() lcdprint("Call attended") time.sleep(2) flag=-1; while flag<0: data=Serial.read(12); print data flag=data.find("NO CARRIER") #flag=data.find("BUSY") print flag lcdclear() lcdprint("Call Ended") time.sleep(1) lcdclear() def readSMS(index): print index Serial.write("AT+CMGR="+index+"\r") data="" data=Serial.read(200) print data r=data.find("OK") if r>=0: r1=data.find("\"\r\n") msg="" msg=data[r1+3:r-4] lcdclear() lcdprint(msg) print msg time.sleep(5) lcdclear(); smsFlag=0 print "Receive SMS" def getChar(Key, ind, maxInd): ch=0 ch=ind lcdcmd(0x0e) Char='' count=0 global msg global x global y while count<20: key=keypad() print key if key== Key: setCursor(x,y) Char=alpha[ch] lcdwrite(ord(Char)) ch=ch+1 if ch>maxInd: ch=ind count=0 count=count+1 time.sleep(0.1) msg+=Char x=x+1 if x>15: x=0 y=1 lcdcmd(0x0f) def alphaKeypad(): lcdclear() setCursor(x,y) lcdcmd(0x0f) msg="" while 1: key=0 count=0 key=keypad() if key == '1': ind=0 maxInd=6 Key='1' getChar(Key, ind, maxInd) elif key == '2': ind=7 maxInd=10 Key='2' getChar(Key, ind, maxInd) elif key == '3': ind=11 maxInd=14 Key='3' getChar(Key, ind, maxInd) elif key == '4': ind=15 maxInd=18 Key='4' getChar(Key, ind, maxInd) elif key == '5': ind=19 maxInd=22 Key='5' getChar(Key, ind, maxInd) elif key == '6': ind=23 maxInd=26 Key='6' getChar(Key, ind, maxInd) elif key == '7': ind=27 maxInd=31 Key='7' getChar(Key, ind, maxInd) elif key == '8': ind=32 maxInd=35 Key='8' getChar(Key, ind, maxInd) elif key == '9': ind=36 maxInd=40 Key='9' getChar(Key, ind, maxInd) elif key == '0': ind=41 maxInd=42 Key='0' getChar(Key, ind, maxInd) elif key == '*': ind=43 maxInd=43 Key='*' getChar(Key, ind, maxInd) elif key == '#': ind=44 maxInd=44 Key='#' getChar(Key, ind, maxInd) elif key== 'D': return def sendSMS(): print"Sending sms" lcdclear() lcdprint("Enter Number:") setCursor(0,1) time.sleep(2) moNum="" while 1: key=0; key=keypad() #print key if key>0: if key == 'A' or key== 'B' or key== 'C': print key return elif key == 'D': print key print moNum Serial.write("AT+CMGF=1\r") time.sleep(1) Serial.write("AT+CMGS=\"+91"+moNum+"\"\r") time.sleep(2) data="" data=Serial.read(60) print data alphaKeypad() print msg lcdclear() lcdprint("Sending.....") Serial.write(msg) time.sleep(1) Serial.write("\x1A") while 1: data="" data=Serial.read(40) print data l=data.find("+CMGS:") if l>=0: lcdclear() lcdprint("SMS Sent.") time.sleep(2) return; l=data.find("Error") if l>=0: lcdclear() lcdprint("Error") time.sleep(1) return else: print key moNum+=key lcdwrite(ord(key)) time.sleep(0.5) def call(): print "Call" n=0 moNum="" lcdclear() lcdprint("Enter Number:") setCursor(0,1) time.sleep(2) while 1: key=0; key=keypad() #print key if key>0: if key == 'A' or key== 'B' or key== 'D': print key return elif key == 'C': print key print moNum Serial.write("ATD+91"+moNum+";\r") data="" time.sleep(2) data=Serial.read(30) l=data.find("OK") if l>=0: lcdclear() lcdprint("Calling.....") setCursor(0,1) lcdprint("+91"+moNum) time.sleep(30) lcdclear() return #l=data.find("Error") #if l>=0: else: lcdclear() lcdprint("Error") time.sleep(1) return else: print key moNum+=key lcdwrite(ord(key)) n=n+1 time.sleep(0.5) begin() lcdcmd(0x01) lcdprint(" Mobile Phone ") lcdcmd(0xc0) lcdprint(" Using RPI ") time.sleep(3) lcdcmd(0x01) lcdprint("Circuit Digest") lcdcmd(0xc0) lcdprint("Welcomes you") time.sleep(3) gsmInit() smsFlag=0 index="" while 1: key=0 key=keypad() print key if key == 'A': attendCall() elif key == 'B': readSMS(index) smsFlag=0 elif key == 'C': call() elif key == 'D': sendSMS() data="" Serial.flush() data=Serial.read(150) print data l=data.find("RING") if l>=0: callstr=data receiveCall(data) l=data.find("\"SM\"") if l>=0: smsstr=data smsIndex="" (smsIndex)=receiveSMS(smsstr) print smsIndex if smsIndex>0: smsFlag=1 index=smsIndex if smsFlag == 1: lcdclear() lcdprint("New Message") time.sleep(1) setCursor(0,0) lcdprint("C--> Call <--A"); setCursor(0,1); lcdprint("D--> SMS <--B")